mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' into beta
This commit is contained in:
commit
90d945750a
@ -100,7 +100,7 @@ private final class ContentNode: ASDisplayNode {
|
||||
self.updateImage(image: image, size: size, spacing: spacing)
|
||||
|
||||
let disposable = (signal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] imageVersions in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] imageVersions in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -109,7 +109,7 @@ private final class ContentNode: ASDisplayNode {
|
||||
strongSelf.updateImage(image: image, size: size, spacing: spacing)
|
||||
}
|
||||
})
|
||||
self.disposable = disposable.strict()
|
||||
self.disposable = disposable
|
||||
} else {
|
||||
let image = generateImage(size, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
@ -333,7 +333,7 @@ public final class AnimatedAvatarSetView: UIView {
|
||||
self.updateImage(image: image, size: size, spacing: spacing)
|
||||
|
||||
let disposable = (signal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] imageVersions in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] imageVersions in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -342,7 +342,7 @@ public final class AnimatedAvatarSetView: UIView {
|
||||
strongSelf.updateImage(image: image, size: size, spacing: spacing)
|
||||
}
|
||||
})
|
||||
self.disposable = disposable.strict()
|
||||
self.disposable = disposable
|
||||
} else {
|
||||
let image = generateImage(size, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
@ -368,12 +368,12 @@ public final class DefaultAnimatedStickerNodeImpl: ASDisplayNode, AnimatedSticke
|
||||
}
|
||||
self.disposable.set((source.directDataPath(attemptSynchronously: false)
|
||||
|> filter { $0 != nil }
|
||||
|> deliverOnMainQueue).start(next: { path in
|
||||
|> deliverOnMainQueue).startStrict(next: { path in
|
||||
f(path!)
|
||||
}))
|
||||
case .cached:
|
||||
self.disposable.set((source.cachedDataPath(width: width, height: height)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] path, complete in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] path, complete in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ public final class DirectAnimatedStickerNode: ASDisplayNode, AnimatedStickerNode
|
||||
self.sourceDisposable = (source.directDataPath(attemptSynchronously: false)
|
||||
|> filter { $0 != nil }
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] path in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] path in
|
||||
guard let strongSelf = self, let path = path else {
|
||||
return
|
||||
}
|
||||
|
@ -69,6 +69,9 @@ public final class AppLockContextImpl: AppLockContext {
|
||||
private let rootPath: String
|
||||
private let syncQueue = Queue()
|
||||
|
||||
private var disposable: Disposable?
|
||||
private var autolockTimeoutDisposable: Disposable?
|
||||
|
||||
private let applicationBindings: TelegramApplicationBindings
|
||||
private let accountManager: AccountManager<TelegramAccountManagerTypes>
|
||||
private let presentationDataSignal: Signal<PresentationData, NoError>
|
||||
@ -112,14 +115,14 @@ public final class AppLockContextImpl: AppLockContext {
|
||||
}
|
||||
self.autolockTimeout.set(self.currentStateValue.autolockTimeout)
|
||||
|
||||
let _ = (combineLatest(queue: .mainQueue(),
|
||||
self.disposable = (combineLatest(queue: .mainQueue(),
|
||||
accountManager.accessChallengeData(),
|
||||
accountManager.sharedData(keys: Set([ApplicationSpecificSharedDataKeys.presentationPasscodeSettings])),
|
||||
presentationDataSignal,
|
||||
applicationBindings.applicationIsActive,
|
||||
self.currentState.get()
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] accessChallengeData, sharedData, presentationData, appInForeground, state in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] accessChallengeData, sharedData, presentationData, appInForeground, state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -254,8 +257,8 @@ public final class AppLockContextImpl: AppLockContext {
|
||||
|
||||
self.currentState.set(.single(self.currentStateValue))
|
||||
|
||||
let _ = (self.autolockTimeout.get()
|
||||
|> deliverOnMainQueue).start(next: { [weak self] autolockTimeout in
|
||||
self.autolockTimeoutDisposable = (self.autolockTimeout.get()
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] autolockTimeout in
|
||||
self?.updateLockState { state in
|
||||
var state = state
|
||||
state.autolockTimeout = autolockTimeout
|
||||
@ -264,6 +267,11 @@ public final class AppLockContextImpl: AppLockContext {
|
||||
})
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.disposable?.dispose()
|
||||
self.autolockTimeoutDisposable?.dispose()
|
||||
}
|
||||
|
||||
private func updateTimestampRenewTimer(shouldRun: Bool) {
|
||||
if shouldRun {
|
||||
if self.timestampRenewTimer == nil {
|
||||
|
@ -442,7 +442,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] maxCaptionLength in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] maxCaptionLength in
|
||||
self?.maxCaptionLength = maxCaptionLength
|
||||
})
|
||||
}
|
||||
|
@ -231,19 +231,19 @@ public class AttachmentController: ViewController {
|
||||
didSet {
|
||||
if let mediaPickerContext = self.mediaPickerContext {
|
||||
self.captionDisposable.set((mediaPickerContext.caption
|
||||
|> deliverOnMainQueue).start(next: { [weak self] caption in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] caption in
|
||||
if let strongSelf = self {
|
||||
strongSelf.panel.updateCaption(caption ?? NSAttributedString())
|
||||
}
|
||||
}))
|
||||
self.mediaSelectionCountDisposable.set((mediaPickerContext.selectionCount
|
||||
|> deliverOnMainQueue).start(next: { [weak self] count in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] count in
|
||||
if let strongSelf = self {
|
||||
strongSelf.updateSelectionCount(count)
|
||||
}
|
||||
}))
|
||||
self.loadingProgressDisposable.set((mediaPickerContext.loadingProgress
|
||||
|> deliverOnMainQueue).start(next: { [weak self] progress in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] progress in
|
||||
if let strongSelf = self {
|
||||
strongSelf.panel.updateLoadingProgress(progress)
|
||||
if let layout = strongSelf.validLayout {
|
||||
@ -252,13 +252,13 @@ public class AttachmentController: ViewController {
|
||||
}
|
||||
}))
|
||||
self.mainButtonStateDisposable.set((mediaPickerContext.mainButtonState
|
||||
|> deliverOnMainQueue).start(next: { [weak self] mainButtonState in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] mainButtonState in
|
||||
if let strongSelf = self {
|
||||
let _ = (strongSelf.panel.animatingTransitionPromise.get()
|
||||
|> filter { value in
|
||||
return !value
|
||||
}
|
||||
|> take(1)).start(next: { [weak self] _ in
|
||||
|> take(1)).startStandalone(next: { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
strongSelf.panel.updateMainButtonState(mainButtonState)
|
||||
if let layout = strongSelf.validLayout {
|
||||
@ -591,7 +591,7 @@ public class AttachmentController: ViewController {
|
||||
$0
|
||||
}
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak snapshotView] _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self, weak snapshotView] _ in
|
||||
guard let strongSelf = self, let layout = strongSelf.validLayout else {
|
||||
return
|
||||
}
|
||||
@ -1039,7 +1039,7 @@ public class AttachmentController: ViewController {
|
||||
let disposableSet = DisposableSet()
|
||||
let _ = (context.engine.messages.attachMenuBots()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { bots in
|
||||
|> deliverOnMainQueue).startStandalone(next: { bots in
|
||||
for bot in bots {
|
||||
for (name, file) in bot.icons {
|
||||
if [.iOSAnimated, .placeholder].contains(name), let peer = PeerReference(bot.peer._asPeer()) {
|
||||
|
@ -85,7 +85,7 @@ private final class IconComponent: Component {
|
||||
|
||||
self.disposable = (svgIconImageFile(account: component.account, fileReference: fileReference)
|
||||
|> runOn(Queue.concurrentDefaultQueue())
|
||||
|> deliverOnMainQueue).start(next: { [weak self] transform in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] transform in
|
||||
let arguments = TransformImageArguments(corners: ImageCorners(), imageSize: availableSize, boundingSize: availableSize, intrinsicInsets: UIEdgeInsets())
|
||||
let drawingContext = transform(arguments)
|
||||
let image = drawingContext?.generateImage()?.withRenderingMode(.alwaysTemplate)
|
||||
@ -965,7 +965,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
let _ = (strongSelf.context.account.viewTracker.peerView(peerId)
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerView in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peerView in
|
||||
guard let strongSelf = self, let peer = peerViewMainPeer(peerView) else {
|
||||
return
|
||||
}
|
||||
@ -1029,7 +1029,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
||||
}, statuses: nil)
|
||||
|
||||
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
strongSelf.presentationData = presentationData
|
||||
|
||||
@ -1165,7 +1165,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.iconDisposables[file.fileId] = accountFullSizeData.start()
|
||||
}
|
||||
} else {
|
||||
self.iconDisposables[file.fileId] = freeMediaFileInteractiveFetched(account: self.context.account, userLocation: .other, fileReference: .attachBot(peer: peer, media: file)).start()
|
||||
self.iconDisposables[file.fileId] = freeMediaFileInteractiveFetched(account: self.context.account, userLocation: .other, fileReference: .attachBot(peer: peer, media: file)).startStrict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
let timeout = min(timeout, 5)
|
||||
#endif
|
||||
self.currentTimeoutTime = timeout
|
||||
let disposable = ((Signal<Int, NoError>.single(1) |> delay(1.0, queue: Queue.mainQueue())) |> restart).start(next: { [weak self] _ in
|
||||
let disposable = ((Signal<Int, NoError>.single(1) |> delay(1.0, queue: Queue.mainQueue())) |> restart).startStrict(next: { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
if let currentTimeoutTime = strongSelf.currentTimeoutTime, currentTimeoutTime > 0 {
|
||||
strongSelf.currentTimeoutTime = currentTimeoutTime - 1
|
||||
@ -348,7 +348,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
})
|
||||
self.countdownDisposable.set(disposable)
|
||||
} else if case let .email(_, _, _, pendingDate, _, _) = codeType, let pendingDate {
|
||||
let disposable = ((Signal<Int, NoError>.single(1) |> delay(1.0, queue: Queue.mainQueue())) |> restart).start(next: { [weak self] _ in
|
||||
let disposable = ((Signal<Int, NoError>.single(1) |> delay(1.0, queue: Queue.mainQueue())) |> restart).startStrict(next: { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
let interval = pendingDate - currentTime
|
||||
|
@ -82,7 +82,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|> deliverOnMainQueue).start(next: { [weak self] state in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] state in
|
||||
self?.updateState(state: state)
|
||||
}).strict()
|
||||
}
|
||||
@ -124,7 +124,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: isTestingEnvironment, masterDatacenterId: masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: isTestingEnvironment, masterDatacenterId: masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,9 +152,9 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
if !strongSelf.otherAccountPhoneNumbers.1.isEmpty {
|
||||
let _ = (strongSelf.sharedContext.accountManager.transaction { transaction -> Void in
|
||||
transaction.removeAuth()
|
||||
}).start()
|
||||
}).startStandalone()
|
||||
} else {
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .empty)).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
}
|
||||
})
|
||||
if let splashController = splashController {
|
||||
@ -175,14 +175,14 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
|> take(1)
|
||||
|> timeout(2.0, queue: .mainQueue(), alternate: .single(nil))
|
||||
let _ = (authorizationPushConfiguration
|
||||
|> deliverOnMainQueue).start(next: { [weak self] authorizationPushConfiguration in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] authorizationPushConfiguration in
|
||||
if let strongSelf = self {
|
||||
strongSelf.actionDisposable.set((sendAuthorizationCode(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, phoneNumber: number, apiId: strongSelf.apiId, apiHash: strongSelf.apiHash, pushNotificationConfiguration: authorizationPushConfiguration, firebaseSecretStream: strongSelf.sharedContext.firebaseSecretStream, syncContacts: syncContacts, forcedPasswordSetupNotice: { value in
|
||||
guard let entry = CodableEntry(ApplicationSpecificCounterNotice(value: value)) else {
|
||||
return nil
|
||||
}
|
||||
return (ApplicationSpecificNotice.forcedPasswordSetupKey(), entry)
|
||||
}) |> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
}) |> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||
if let strongSelf = self {
|
||||
switch result {
|
||||
case let .sentCode(account):
|
||||
@ -312,12 +312,12 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
})
|
||||
controller.retryResetEmail = { [weak self] in
|
||||
if let self {
|
||||
self.actionDisposable.set(
|
||||
resetLoginEmail(account: self.account, phoneNumber: number, phoneCodeHash: phoneCodeHash).start()
|
||||
resetLoginEmail(account: self.account, phoneNumber: number, phoneCodeHash: phoneCodeHash).startStandalone()
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -328,7 +328,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
if let _ = resetPendingDate {
|
||||
self.actionDisposable.set(
|
||||
(resetLoginEmail(account: self.account, phoneNumber: number, phoneCodeHash: phoneCodeHash)
|
||||
|> deliverOnMainQueue).start(error: { [weak self] error in
|
||||
|> deliverOnMainQueue).startStrict(error: { [weak self] error in
|
||||
if let self, case .alreadyInProgress = error {
|
||||
let formattedNumber = formatPhoneNumber(number)
|
||||
let title = NSAttributedString(string: self.presentationData.strings.Login_Email_PremiumRequiredTitle, font: Font.semibold(self.presentationData.listsFontSize.baseDisplaySize), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
|
||||
@ -342,7 +342,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
} else if let resetAvailablePeriod {
|
||||
if resetAvailablePeriod == 0 {
|
||||
self.actionDisposable.set(
|
||||
resetLoginEmail(account: self.account, phoneNumber: number, phoneCodeHash: phoneCodeHash).start()
|
||||
resetLoginEmail(account: self.account, phoneNumber: number, phoneCodeHash: phoneCodeHash).startStrict()
|
||||
)
|
||||
} else {
|
||||
let pattern = pattern.replacingOccurrences(of: "*", with: "#")
|
||||
@ -362,7 +362,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
self.actionDisposable.set(
|
||||
(resetLoginEmail(account: self.account, phoneNumber: number, phoneCodeHash: phoneCodeHash)
|
||||
|> deliverOnMainQueue).start(error: { [weak self] error in
|
||||
|> deliverOnMainQueue).startStrict(error: { [weak self] error in
|
||||
Queue.mainQueue().async {
|
||||
guard let self, let controller = controller else {
|
||||
return
|
||||
@ -378,7 +378,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
case .codeExpired:
|
||||
text = self.presentationData.strings.Login_CodeExpired
|
||||
let account = self.account
|
||||
let _ = TelegramEngineUnauthorized(account: self.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start()
|
||||
let _ = TelegramEngineUnauthorized(account: self.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
}
|
||||
|
||||
controller.presentInGlobalOverlay(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]))
|
||||
@ -405,7 +405,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
|
||||
if case let .email(_, _, _, _, _, setup) = type, setup, case let .emailVerification(emailCode) = authorizationCode {
|
||||
strongSelf.actionDisposable.set(((verifyLoginEmailSetup(account: strongSelf.account, code: emailCode))
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
|> deliverOnMainQueue).startStrict(error: { error in
|
||||
Queue.mainQueue().async {
|
||||
if let strongSelf = self, let controller = controller {
|
||||
controller.inProgress = false
|
||||
@ -427,7 +427,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
case .codeExpired:
|
||||
text = strongSelf.presentationData.strings.Login_CodeExpired
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
case .timeout:
|
||||
text = strongSelf.presentationData.strings.Login_NetworkError
|
||||
case .invalidEmailToken:
|
||||
@ -452,7 +452,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
return (ApplicationSpecificNotice.forcedPasswordSetupKey(), entry)
|
||||
})
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
|> deliverOnMainQueue).startStrict(next: { result in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -474,7 +474,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let _ = beginSignUp(account: strongSelf.account, data: data).start()
|
||||
let _ = beginSignUp(account: strongSelf.account, data: data).startStandalone()
|
||||
}), TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Login_TermsOfServiceDecline, action: {
|
||||
dismissImpl?()
|
||||
guard let strongSelf = self else {
|
||||
@ -487,7 +487,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
return
|
||||
}
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
})]), on: .root, blockInteraction: false, completion: {})
|
||||
})
|
||||
], actionLayout: .vertical, dismissOnOutsideTap: true)
|
||||
@ -508,7 +508,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
presentAlertImpl()
|
||||
} else {
|
||||
let _ = beginSignUp(account: strongSelf.account, data: data).start()
|
||||
let _ = beginSignUp(account: strongSelf.account, data: data).startStandalone()
|
||||
}
|
||||
case .loggedIn:
|
||||
controller?.animateSuccess()
|
||||
@ -535,7 +535,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
case .codeExpired:
|
||||
text = strongSelf.presentationData.strings.Login_CodeExpired
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
case .invalidEmailToken:
|
||||
text = strongSelf.presentationData.strings.Login_InvalidEmailTokenError
|
||||
case .invalidEmailAddress:
|
||||
@ -582,7 +582,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
} else {
|
||||
controller?.inProgress = true
|
||||
strongSelf.actionDisposable.set((resendAuthorizationCode(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, apiId: strongSelf.apiId, apiHash: strongSelf.apiHash, firebaseSecretStream: strongSelf.sharedContext.firebaseSecretStream)
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
|> deliverOnMainQueue).startStrict(next: { result in
|
||||
controller?.inProgress = false
|
||||
}, error: { error in
|
||||
if let strongSelf = self, let controller = controller {
|
||||
@ -622,7 +622,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
controller.reset = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
}
|
||||
}
|
||||
controller.signInWithApple = { [weak self] in
|
||||
@ -674,7 +674,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
})
|
||||
}
|
||||
controller.proceedWithEmail = { [weak self, weak controller] email in
|
||||
@ -687,7 +687,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
strongSelf.currentEmail = email
|
||||
|
||||
strongSelf.actionDisposable.set((sendLoginEmailCode(account: strongSelf.account, email: email)
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
|> deliverOnMainQueue).startStrict(error: { error in
|
||||
if let strongSelf = self, let controller = controller {
|
||||
controller.inProgress = false
|
||||
|
||||
@ -747,7 +747,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
|
||||
if self.signInWithAppleSetup {
|
||||
self.actionDisposable.set((verifyLoginEmailSetup(account: self.account, code: .appleToken(token))
|
||||
|> deliverOnMainQueue).start(error: { [weak self, weak lastController] error in
|
||||
|> deliverOnMainQueue).startStrict(error: { [weak self, weak lastController] error in
|
||||
if let strongSelf = self, let lastController = lastController {
|
||||
let text: String
|
||||
switch error {
|
||||
@ -774,13 +774,13 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
return nil
|
||||
}
|
||||
return (ApplicationSpecificNotice.forcedPasswordSetupKey(), entry)
|
||||
}).start(next: { [weak self] result in
|
||||
}).startStrict(next: { [weak self] result in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
switch result {
|
||||
case let .signUp(data):
|
||||
let _ = beginSignUp(account: strongSelf.account, data: data).start()
|
||||
let _ = beginSignUp(account: strongSelf.account, data: data).startStandalone()
|
||||
case .loggedIn:
|
||||
break
|
||||
}
|
||||
@ -798,7 +798,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
case .codeExpired:
|
||||
text = strongSelf.presentationData.strings.Login_CodeExpired
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
case .invalidEmailToken:
|
||||
text = strongSelf.presentationData.strings.Login_InvalidEmailTokenError
|
||||
case .invalidEmailAddress:
|
||||
@ -839,13 +839,13 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
})
|
||||
controller.loginWithPassword = { [weak self, weak controller] password in
|
||||
if let strongSelf = self {
|
||||
controller?.inProgress = true
|
||||
|
||||
strongSelf.actionDisposable.set((authorizeWithPassword(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, password: password, syncContacts: syncContacts) |> deliverOnMainQueue).start(error: { error in
|
||||
strongSelf.actionDisposable.set((authorizeWithPassword(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, password: password, syncContacts: syncContacts) |> deliverOnMainQueue).startStrict(error: { error in
|
||||
Queue.mainQueue().async {
|
||||
if let strongSelf = self, let controller = controller {
|
||||
controller.inProgress = false
|
||||
@ -872,18 +872,18 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
if let strongSelf = self, let strongController = controller {
|
||||
strongController.inProgress = true
|
||||
strongSelf.actionDisposable.set((TelegramEngineUnauthorized(account: strongSelf.account).auth.requestTwoStepVerificationPasswordRecoveryCode()
|
||||
|> deliverOnMainQueue).start(next: { pattern in
|
||||
|> deliverOnMainQueue).startStrict(next: { pattern in
|
||||
if let strongSelf = self, let strongController = controller {
|
||||
strongController.inProgress = false
|
||||
|
||||
let _ = (TelegramEngineUnauthorized(account: strongSelf.account).auth.state()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { state in
|
||||
|> deliverOnMainQueue).startStandalone(next: { state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if case let .unauthorized(state) = state, case let .passwordEntry(hint, number, code, _, syncContacts) = state.contents {
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordRecovery(hint: hint, number: number, code: code, emailPattern: pattern, syncContacts: syncContacts))).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordRecovery(hint: hint, number: number, code: code, emailPattern: pattern, syncContacts: syncContacts))).startStandalone()
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -907,7 +907,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
if let strongSelf = self, let strongController = controller {
|
||||
strongController.inProgress = true
|
||||
strongSelf.actionDisposable.set((performAccountReset(account: strongSelf.account)
|
||||
|> deliverOnMainQueue).start(next: {
|
||||
|> deliverOnMainQueue).startStrict(next: {
|
||||
if let strongController = controller {
|
||||
strongController.inProgress = false
|
||||
}
|
||||
@ -954,12 +954,12 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
|
||||
let _ = (TelegramEngineUnauthorized(account: strongSelf.account).auth.state()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { state in
|
||||
|> deliverOnMainQueue).startStandalone(next: { state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if case let .unauthorized(state) = state, case let .passwordRecovery(hint, number, code, _, syncContacts) = state.contents {
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code, suggestReset: true, syncContacts: syncContacts))).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code, suggestReset: true, syncContacts: syncContacts))).startStandalone()
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -984,7 +984,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
})
|
||||
controller.reset = { [weak self, weak controller] in
|
||||
if let strongSelf = self, let strongController = controller {
|
||||
@ -994,7 +994,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
if let strongSelf = self, let strongController = controller {
|
||||
strongController.inProgress = true
|
||||
strongSelf.actionDisposable.set((performAccountReset(account: strongSelf.account)
|
||||
|> deliverOnMainQueue).start(next: {
|
||||
|> deliverOnMainQueue).startStrict(next: {
|
||||
if let strongController = controller {
|
||||
strongController.inProgress = false
|
||||
}
|
||||
@ -1018,7 +1018,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
controller.logout = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1044,7 +1044,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start()
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
}, displayCancel: displayCancel)
|
||||
controller.signUpWithName = { [weak self, weak controller] firstName, lastName, avatarData, avatarAsset, avatarAdjustments in
|
||||
if let strongSelf = self {
|
||||
@ -1112,7 +1112,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
return (ApplicationSpecificNotice.forcedPasswordSetupKey(), entry)
|
||||
})
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
|> deliverOnMainQueue).startStrict(error: { error in
|
||||
Queue.mainQueue().async {
|
||||
if let strongSelf = self, let controller = controller {
|
||||
controller.inProgress = false
|
||||
|
@ -444,7 +444,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
||||
|
||||
if let account = account {
|
||||
self.tokenEventsDisposable.set((account.updateLoginTokenEvents
|
||||
|> deliverOnMainQueue).start(next: { [weak self] _ in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] _ in
|
||||
self?.refreshQrToken()
|
||||
}))
|
||||
}
|
||||
@ -672,19 +672,19 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
self.exportTokenDisposable.set((tokenSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
switch result {
|
||||
case let .displayToken(token):
|
||||
var tokenString = token.value.base64EncodedString()
|
||||
print("export token \(tokenString)")
|
||||
//print("export token \(tokenString)")
|
||||
tokenString = tokenString.replacingOccurrences(of: "+", with: "-")
|
||||
tokenString = tokenString.replacingOccurrences(of: "/", with: "_")
|
||||
let urlString = "tg://login?token=\(tokenString)"
|
||||
let _ = (qrCode(string: urlString, color: .black, backgroundColor: .white, icon: .none)
|
||||
|> deliverOnMainQueue).start(next: { _, generate in
|
||||
|> deliverOnMainQueue).startStrict(next: { _, generate in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -698,7 +698,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
||||
let timestamp = Int32(Date().timeIntervalSince1970)
|
||||
let timeout = max(5, token.validUntil - timestamp)
|
||||
strongSelf.exportTokenDisposable.set((Signal<Never, NoError>.complete()
|
||||
|> delay(Double(timeout), queue: .mainQueue())).start(completed: {
|
||||
|> delay(Double(timeout), queue: .mainQueue())).startStrict(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -709,7 +709,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
||||
strongSelf.account = account
|
||||
strongSelf.accountUpdated?(account)
|
||||
strongSelf.tokenEventsDisposable.set((account.updateLoginTokenEvents
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
|> deliverOnMainQueue).startStrict(next: { _ in
|
||||
self?.refreshQrToken()
|
||||
}))
|
||||
strongSelf.refreshQrToken()
|
||||
|
@ -76,7 +76,7 @@ public final class AvatarVideoNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
if self.useAnimationNode {
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: self.context.account, userLocation: .other, fileReference: stickerPackFileReference(animationFile), resource: chatMessageStickerResource(file: animationFile, small: false)).start())
|
||||
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: self.context.account, userLocation: .other, fileReference: stickerPackFileReference(animationFile), resource: chatMessageStickerResource(file: animationFile, small: false)).startStrict())
|
||||
|
||||
let animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
animationNode.autoplay = false
|
||||
@ -175,7 +175,7 @@ public final class AvatarVideoNode: ASDisplayNode {
|
||||
switch markup.content {
|
||||
case let .emoji(fileId):
|
||||
self.fileDisposable = (self.context.engine.stickers.resolveInlineStickers(fileIds: [fileId])
|
||||
|> deliverOnMainQueue).start(next: { [weak self] files in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] files in
|
||||
if let strongSelf = self, let file = files.values.first {
|
||||
strongSelf.animationFile = file
|
||||
strongSelf.setupAnimation()
|
||||
@ -189,7 +189,7 @@ public final class AvatarVideoNode: ASDisplayNode {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] file in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] file in
|
||||
if let strongSelf = self, let file {
|
||||
strongSelf.animationFile = file
|
||||
strongSelf.setupAnimation()
|
||||
@ -265,7 +265,7 @@ public final class AvatarVideoNode: ASDisplayNode {
|
||||
return playing
|
||||
}
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
|> deliverOnMainQueue).startStrict(completed: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
Queue.mainQueue().after(0.15) {
|
||||
strongSelf.videoNode?.isHidden = false
|
||||
|
@ -70,7 +70,7 @@ private final class MediaPreviewView: SimpleLayer {
|
||||
|> map { image in
|
||||
return image.flatMap(processImage)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] image in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] image in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1180,7 +1180,7 @@ public final class CalendarMessageScreen: ViewController {
|
||||
self.isLoadingMoreDisposable = (self.calendarSource.isLoadingMore
|
||||
|> distinctUntilChanged
|
||||
|> filter { !$0 }
|
||||
|> deliverOnMainQueue).start(next: { [weak self] _ in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1188,7 +1188,7 @@ public final class CalendarMessageScreen: ViewController {
|
||||
}).strict()
|
||||
|
||||
self.stateDisposable = (self.calendarSource.state
|
||||
|> deliverOnMainQueue).start(next: { [weak self] state in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1487,7 +1487,7 @@ public final class CalendarMessageScreen: ViewController {
|
||||
mainPeer: chatPeer
|
||||
)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] info in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] info in
|
||||
guard let strongSelf = self, let info = info else {
|
||||
return
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ public final class CallListController: TelegramBaseController {
|
||||
}
|
||||
|
||||
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
let previousStrings = strongSelf.presentationData.strings
|
||||
@ -217,7 +217,7 @@ public final class CallListController: TelegramBaseController {
|
||||
let _ = (strongSelf.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let strongSelf = self, let peer = peer, let controller = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .calls(messages: messages.map({ $0._asMessage() })), avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||
(strongSelf.navigationController as? NavigationController)?.pushViewController(controller)
|
||||
}
|
||||
@ -335,7 +335,7 @@ public final class CallListController: TelegramBaseController {
|
||||
self?.clearDisposable.set(nil)
|
||||
}
|
||||
strongSelf.clearDisposable.set((signal
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|> deliverOnMainQueue).startStrict(completed: {
|
||||
}))
|
||||
}
|
||||
|
||||
@ -386,7 +386,7 @@ public final class CallListController: TelegramBaseController {
|
||||
controller.navigationPresentation = .modal
|
||||
self.createActionDisposable.set((controller.result
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak controller, weak self] result in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak controller, weak self] result in
|
||||
controller?.dismissSearch()
|
||||
if let strongSelf = self, let (contactPeers, action, _, _, _) = result, let contactPeer = contactPeers.first, case let .peer(peer, _, _) = contactPeer {
|
||||
strongSelf.call(peer.id, isVideo: action == .videoCall, began: {
|
||||
@ -396,7 +396,7 @@ public final class CallListController: TelegramBaseController {
|
||||
|> timeout(1.0, queue: Queue.mainQueue(), alternate: .single(true))
|
||||
|> delay(0.5, queue: Queue.mainQueue())
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
|> deliverOnMainQueue).startStandalone(next: { _ in
|
||||
if let _ = self, let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
||||
if navigationController.viewControllers.last === controller {
|
||||
let _ = navigationController.popViewController(animated: true)
|
||||
@ -467,7 +467,7 @@ public final class CallListController: TelegramBaseController {
|
||||
private func call(_ peerId: EnginePeer.Id, isVideo: Bool, began: (() -> Void)? = nil) {
|
||||
self.peerViewDisposable.set((self.context.account.viewTracker.peerView(peerId)
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] view in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] view in
|
||||
if let strongSelf = self {
|
||||
guard let peer = peerViewMainPeer(view) else {
|
||||
return
|
||||
|
@ -329,7 +329,7 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
let _ = (context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
guard let strongSelf = self, let peer = peer else {
|
||||
return
|
||||
}
|
||||
@ -342,7 +342,7 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: messageIds, type: .forEveryone).start()
|
||||
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: messageIds, type: .forEveryone).startStandalone()
|
||||
}))
|
||||
|
||||
items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_DeleteMessagesForMe, color: .destructive, action: { [weak actionSheet] in
|
||||
@ -352,7 +352,7 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: messageIds, type: .forLocalPeer).start()
|
||||
let _ = strongSelf.context.engine.messages.deleteMessagesInteractively(messageIds: messageIds, type: .forLocalPeer).startStandalone()
|
||||
}))
|
||||
|
||||
actionSheet.setItemGroups([
|
||||
@ -369,10 +369,10 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
if let strongSelf = self {
|
||||
let _ = updateCallListSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, {
|
||||
$0.withUpdatedShowTab(value)
|
||||
}).start()
|
||||
}).startStandalone()
|
||||
|
||||
if value {
|
||||
let _ = ApplicationSpecificNotice.incrementCallsTabTips(accountManager: strongSelf.context.sharedContext.accountManager, count: 4).start()
|
||||
let _ = ApplicationSpecificNotice.incrementCallsTabTips(accountManager: strongSelf.context.sharedContext.accountManager, count: 4).startStandalone()
|
||||
}
|
||||
}
|
||||
}, openGroupCall: { [weak self] peerId in
|
||||
@ -596,7 +596,7 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
self.callListDisposable.set(appliedTransition.start())
|
||||
self.callListDisposable.set(appliedTransition.startStrict())
|
||||
|
||||
self.callListLocationAndType.set(self.currentLocationAndType)
|
||||
|
||||
@ -606,7 +606,7 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|
||||
self.emptyStateDisposable.set((combineLatest(emptySignal, typeSignal, self.statePromise.get()) |> deliverOnMainQueue).start(next: { [weak self] isEmpty, type, state in
|
||||
self.emptyStateDisposable.set((combineLatest(emptySignal, typeSignal, self.statePromise.get()) |> deliverOnMainQueue).startStrict(next: { [weak self] isEmpty, type, state in
|
||||
if let strongSelf = self {
|
||||
strongSelf.updateEmptyPlaceholder(theme: state.presentationData.theme, strings: state.presentationData.strings, type: type, isHidden: !isEmpty)
|
||||
}
|
||||
|
@ -371,20 +371,20 @@ private final class CameraContext {
|
||||
if #available(iOS 13.0, *), let previewView = self.simplePreviewView {
|
||||
if enabled, let secondaryPreviewView = self.secondaryPreviewView {
|
||||
let _ = (combineLatest(previewView.isPreviewing, secondaryPreviewView.isPreviewing)
|
||||
|> map { first, second in
|
||||
|> map { first, second in
|
||||
return first && second
|
||||
}
|
||||
|> filter { $0 }
|
||||
|> take(1)
|
||||
|> delay(0.1, queue: self.queue)
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] _ in
|
||||
|> deliverOn(self.queue)).startStandalone(next: { [weak self] _ in
|
||||
self?.modeChange = .none
|
||||
})
|
||||
} else {
|
||||
let _ = (previewView.isPreviewing
|
||||
|> filter { $0 }
|
||||
|> take(1)
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] _ in
|
||||
|> deliverOn(self.queue)).startStandalone(next: { [weak self] _ in
|
||||
self?.modeChange = .none
|
||||
})
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ private final class ImportManager {
|
||||
return .limitExceeded
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] session in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] session in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -200,7 +200,7 @@ private final class ImportManager {
|
||||
return
|
||||
}
|
||||
self.disposable.set((TelegramEngine(account: self.account).historyImport.startImport(session: session)
|
||||
|> deliverOnMainQueue).start(error: { [weak self] _ in
|
||||
|> deliverOnMainQueue).startStrict(error: { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -848,14 +848,14 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
}
|
||||
|
||||
self.disposable.set((resolvedPeerId
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerId in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] peerId in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let importManager = ImportManager(account: strongSelf.context.account, peerId: peerId, mainFile: strongSelf.mainEntry, archivePath: strongSelf.archivePath, entries: strongSelf.otherEntries)
|
||||
strongSelf.importManager = importManager
|
||||
strongSelf.progressDisposable.set((importManager.state
|
||||
|> deliverOnMainQueue).start(next: { state in
|
||||
|> deliverOnMainQueue).startStrict(next: { state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ public final class ChatListSearchRecentPeersNode: ASDisplayNode {
|
||||
|
||||
let previous: Atomic<[ChatListSearchRecentPeersEntry]> = Atomic(value: [])
|
||||
let firstTime:Atomic<Bool> = Atomic(value: true)
|
||||
peersDisposable.add((combineLatest(queue: .mainQueue(), recent, self.itemCustomWidthValuePromise.get(), self.themeAndStringsPromise.get()) |> deliverOnMainQueue).start(next: { [weak self] peers, itemCustomWidth, themeAndStrings in
|
||||
peersDisposable.add((combineLatest(queue: .mainQueue(), recent, self.itemCustomWidthValuePromise.get(), self.themeAndStringsPromise.get()) |> deliverOnMainQueue).startStrict(next: { [weak self] peers, itemCustomWidth, themeAndStrings in
|
||||
if let strongSelf = self {
|
||||
var entries: [ChatListSearchRecentPeersEntry] = []
|
||||
for peer in peers.0 {
|
||||
@ -348,7 +348,7 @@ public final class ChatListSearchRecentPeersNode: ASDisplayNode {
|
||||
}
|
||||
}))
|
||||
if case .actionSheet = mode {
|
||||
peersDisposable.add(_internal_managedUpdatedRecentPeers(accountPeerId: accountPeerId, postbox: postbox, network: network).start())
|
||||
peersDisposable.add(_internal_managedUpdatedRecentPeers(accountPeerId: accountPeerId, postbox: postbox, network: network).startStrict())
|
||||
}
|
||||
self.disposable.set(peersDisposable)
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public final class ChatSendMessageActionSheetController: ViewController {
|
||||
self.blocksBackgroundWhenInOverlay = true
|
||||
|
||||
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
strongSelf.presentationData = presentationData
|
||||
if strongSelf.isNodeLoaded {
|
||||
|
@ -58,7 +58,7 @@ private func cachedInternalInstantPage(context: AccountContext, url: String) ->
|
||||
if instantPage.isComplete {
|
||||
let _ = updateCachedInstantPage(engine: context.engine, url: cachedUrl, webPage: webPage).start()
|
||||
} else {
|
||||
let _ = (actualizedWebpage(postbox: context.account.postbox, network: context.account.network, webpage: webPage)
|
||||
let _ = (actualizedWebpage(account: context.account, webpage: webPage)
|
||||
|> mapToSignal { webPage -> Signal<Never, NoError> in
|
||||
if case let .Loaded(content) = webPage.content, let instantPage = content.instantPage, instantPage.isComplete {
|
||||
return updateCachedInstantPage(engine: context.engine, url: cachedUrl, webPage: webPage)
|
||||
|
@ -106,7 +106,7 @@ public final class InstantPageController: ViewController {
|
||||
|
||||
self.statusBar.statusBarStyle = .White
|
||||
|
||||
self.webpageDisposable = (actualizedWebpage(postbox: self.context.account.postbox, network: self.context.account.network, webpage: webPage) |> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
self.webpageDisposable = (actualizedWebpage(account: context.account, webpage: webPage) |> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
if let strongSelf = self {
|
||||
strongSelf.webPage = result
|
||||
if strongSelf.isNodeLoaded {
|
||||
|
@ -27,6 +27,8 @@ swift_library(
|
||||
"//submodules/ComponentFlow:ComponentFlow",
|
||||
"//submodules/TelegramUI/Components/EmojiStatusComponent:EmojiStatusComponent",
|
||||
"//submodules/CheckNode",
|
||||
"//submodules/TelegramUI/Components/AnimationCache",
|
||||
"//submodules/TelegramUI/Components/MultiAnimationRenderer",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -17,6 +17,8 @@ import AccountContext
|
||||
import ComponentFlow
|
||||
import EmojiStatusComponent
|
||||
import CheckNode
|
||||
import AnimationCache
|
||||
import MultiAnimationRenderer
|
||||
|
||||
private final class ShimmerEffectNode: ASDisplayNode {
|
||||
private var currentBackgroundColor: UIColor?
|
||||
@ -319,10 +321,126 @@ public struct ItemListPeerItemShimmering {
|
||||
}
|
||||
|
||||
public final class ItemListPeerItem: ListViewItem, ItemListItem {
|
||||
public enum Context {
|
||||
public final class Custom {
|
||||
public let accountPeerId: EnginePeer.Id
|
||||
public let postbox: Postbox
|
||||
public let network: Network
|
||||
public let animationCache: AnimationCache
|
||||
public let animationRenderer: MultiAnimationRenderer
|
||||
public let isPremiumDisabled: Bool
|
||||
public let resolveInlineStickers: ([Int64]) -> Signal<[Int64: TelegramMediaFile], NoError>
|
||||
|
||||
public init(
|
||||
accountPeerId: EnginePeer.Id,
|
||||
postbox: Postbox,
|
||||
network: Network,
|
||||
animationCache: AnimationCache,
|
||||
animationRenderer: MultiAnimationRenderer,
|
||||
isPremiumDisabled: Bool,
|
||||
resolveInlineStickers: @escaping ([Int64]) -> Signal<[Int64: TelegramMediaFile], NoError>
|
||||
) {
|
||||
self.accountPeerId = accountPeerId
|
||||
self.postbox = postbox
|
||||
self.network = network
|
||||
self.animationCache = animationCache
|
||||
self.animationRenderer = animationRenderer
|
||||
self.isPremiumDisabled = isPremiumDisabled
|
||||
self.resolveInlineStickers = resolveInlineStickers
|
||||
}
|
||||
}
|
||||
|
||||
case account(AccountContext)
|
||||
case custom(Custom)
|
||||
|
||||
public var accountPeerId: EnginePeer.Id {
|
||||
switch self {
|
||||
case let .account(context):
|
||||
return context.account.peerId
|
||||
case let .custom(custom):
|
||||
return custom.accountPeerId
|
||||
}
|
||||
}
|
||||
|
||||
public var postbox: Postbox {
|
||||
switch self {
|
||||
case let .account(context):
|
||||
return context.account.postbox
|
||||
case let .custom(custom):
|
||||
return custom.postbox
|
||||
}
|
||||
}
|
||||
|
||||
public var network: Network {
|
||||
switch self {
|
||||
case let .account(context):
|
||||
return context.account.network
|
||||
case let .custom(custom):
|
||||
return custom.network
|
||||
}
|
||||
}
|
||||
|
||||
public var animationCache: AnimationCache {
|
||||
switch self {
|
||||
case let .account(context):
|
||||
return context.animationCache
|
||||
case let .custom(custom):
|
||||
return custom.animationCache
|
||||
}
|
||||
}
|
||||
|
||||
public var animationRenderer: MultiAnimationRenderer {
|
||||
switch self {
|
||||
case let .account(context):
|
||||
return context.animationRenderer
|
||||
case let .custom(custom):
|
||||
return custom.animationRenderer
|
||||
}
|
||||
}
|
||||
|
||||
public var isPremiumDisabled: Bool {
|
||||
switch self {
|
||||
case let .account(context):
|
||||
return PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with({ $0 })).isPremiumDisabled
|
||||
case let .custom(custom):
|
||||
return custom.isPremiumDisabled
|
||||
}
|
||||
}
|
||||
|
||||
public var resolveInlineStickers: ([Int64]) -> Signal<[Int64: TelegramMediaFile], NoError> {
|
||||
switch self {
|
||||
case let .account(context):
|
||||
return { fileIds in
|
||||
return context.engine.stickers.resolveInlineStickers(fileIds: fileIds)
|
||||
}
|
||||
case let .custom(custom):
|
||||
return custom.resolveInlineStickers
|
||||
}
|
||||
}
|
||||
|
||||
public var energyUsageSettings: EnergyUsageSettings {
|
||||
switch self {
|
||||
case let .account(context):
|
||||
return context.sharedContext.energyUsageSettings
|
||||
case .custom:
|
||||
return .default
|
||||
}
|
||||
}
|
||||
|
||||
public var contentSettings: ContentSettings {
|
||||
switch self {
|
||||
case let .account(context):
|
||||
return context.currentContentSettings.with { $0 }
|
||||
case .custom:
|
||||
return .default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let presentationData: ItemListPresentationData
|
||||
let dateTimeFormat: PresentationDateTimeFormat
|
||||
let nameDisplayOrder: PresentationPersonNameOrder
|
||||
let context: AccountContext
|
||||
let context: Context
|
||||
let peer: EnginePeer
|
||||
let threadInfo: EngineMessageHistoryThread.Info?
|
||||
let height: ItemListPeerItemHeight
|
||||
@ -358,7 +476,126 @@ public final class ItemListPeerItem: ListViewItem, ItemListItem {
|
||||
let storyStats: PeerStoryStats?
|
||||
let openStories: ((UIView) -> Void)?
|
||||
|
||||
public init(presentationData: ItemListPresentationData, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, context: AccountContext, peer: EnginePeer, threadInfo: EngineMessageHistoryThread.Info? = nil, height: ItemListPeerItemHeight = .peerList, aliasHandling: ItemListPeerItemAliasHandling = .standard, nameColor: ItemListPeerItemNameColor = .primary, nameStyle: ItemListPeerItemNameStyle = .distinctBold, presence: EnginePeer.Presence?, text: ItemListPeerItemText, label: ItemListPeerItemLabel, editing: ItemListPeerItemEditing, revealOptions: ItemListPeerItemRevealOptions? = nil, switchValue: ItemListPeerItemSwitch?, enabled: Bool, highlighted: Bool = false, selectable: Bool, highlightable: Bool = true, animateFirstAvatarTransition: Bool = true, sectionId: ItemListSectionId, action: (() -> Void)?, setPeerIdWithRevealedOptions: @escaping (EnginePeer.Id?, EnginePeer.Id?) -> Void, removePeer: @escaping (EnginePeer.Id) -> Void, toggleUpdated: ((Bool) -> Void)? = nil, contextAction: ((ASDisplayNode, ContextGesture?) -> Void)? = nil, hasTopStripe: Bool = true, hasTopGroupInset: Bool = true, noInsets: Bool = false, noCorners: Bool = false, tag: ItemListItemTag? = nil, header: ListViewItemHeader? = nil, shimmering: ItemListPeerItemShimmering? = nil, displayDecorations: Bool = true, disableInteractiveTransitionIfNecessary: Bool = false, storyStats: PeerStoryStats? = nil, openStories: ((UIView) -> Void)? = nil) {
|
||||
public init(
|
||||
presentationData: ItemListPresentationData,
|
||||
dateTimeFormat: PresentationDateTimeFormat,
|
||||
nameDisplayOrder: PresentationPersonNameOrder,
|
||||
context: AccountContext,
|
||||
peer: EnginePeer,
|
||||
threadInfo: EngineMessageHistoryThread.Info? = nil,
|
||||
height: ItemListPeerItemHeight = .peerList,
|
||||
aliasHandling: ItemListPeerItemAliasHandling = .standard,
|
||||
nameColor: ItemListPeerItemNameColor = .primary,
|
||||
nameStyle: ItemListPeerItemNameStyle = .distinctBold,
|
||||
presence: EnginePeer.Presence?,
|
||||
text: ItemListPeerItemText,
|
||||
label: ItemListPeerItemLabel,
|
||||
editing: ItemListPeerItemEditing,
|
||||
revealOptions: ItemListPeerItemRevealOptions? = nil,
|
||||
switchValue: ItemListPeerItemSwitch?,
|
||||
enabled: Bool,
|
||||
highlighted: Bool = false,
|
||||
selectable: Bool,
|
||||
highlightable: Bool = true,
|
||||
animateFirstAvatarTransition: Bool = true,
|
||||
sectionId: ItemListSectionId,
|
||||
action: (() -> Void)?,
|
||||
setPeerIdWithRevealedOptions: @escaping (EnginePeer.Id?, EnginePeer.Id?) -> Void,
|
||||
removePeer: @escaping (EnginePeer.Id) -> Void,
|
||||
toggleUpdated: ((Bool) -> Void)? = nil,
|
||||
contextAction: ((ASDisplayNode, ContextGesture?) -> Void)? = nil,
|
||||
hasTopStripe: Bool = true,
|
||||
hasTopGroupInset: Bool = true,
|
||||
noInsets: Bool = false,
|
||||
noCorners: Bool = false,
|
||||
tag: ItemListItemTag? = nil,
|
||||
header: ListViewItemHeader? = nil,
|
||||
shimmering: ItemListPeerItemShimmering? = nil,
|
||||
displayDecorations: Bool = true,
|
||||
disableInteractiveTransitionIfNecessary: Bool = false,
|
||||
storyStats: PeerStoryStats? = nil,
|
||||
openStories: ((UIView) -> Void)? = nil
|
||||
) {
|
||||
self.presentationData = presentationData
|
||||
self.dateTimeFormat = dateTimeFormat
|
||||
self.nameDisplayOrder = nameDisplayOrder
|
||||
self.context = .account(context)
|
||||
self.peer = peer
|
||||
self.threadInfo = threadInfo
|
||||
self.height = height
|
||||
self.aliasHandling = aliasHandling
|
||||
self.nameColor = nameColor
|
||||
self.nameStyle = nameStyle
|
||||
self.presence = presence
|
||||
self.text = text
|
||||
self.label = label
|
||||
self.editing = editing
|
||||
self.revealOptions = revealOptions
|
||||
self.switchValue = switchValue
|
||||
self.enabled = enabled
|
||||
self.highlighted = highlighted
|
||||
self.selectable = selectable
|
||||
self.highlightable = highlightable
|
||||
self.animateFirstAvatarTransition = animateFirstAvatarTransition
|
||||
self.sectionId = sectionId
|
||||
self.action = action
|
||||
self.setPeerIdWithRevealedOptions = setPeerIdWithRevealedOptions
|
||||
self.removePeer = removePeer
|
||||
self.toggleUpdated = toggleUpdated
|
||||
self.contextAction = contextAction
|
||||
self.hasTopStripe = hasTopStripe
|
||||
self.hasTopGroupInset = hasTopGroupInset
|
||||
self.noInsets = noInsets
|
||||
self.noCorners = noCorners
|
||||
self.tag = tag
|
||||
self.header = header
|
||||
self.shimmering = shimmering
|
||||
self.displayDecorations = displayDecorations
|
||||
self.disableInteractiveTransitionIfNecessary = disableInteractiveTransitionIfNecessary
|
||||
self.storyStats = storyStats
|
||||
self.openStories = openStories
|
||||
}
|
||||
|
||||
public init(
|
||||
presentationData: ItemListPresentationData,
|
||||
dateTimeFormat: PresentationDateTimeFormat,
|
||||
nameDisplayOrder: PresentationPersonNameOrder,
|
||||
context: Context,
|
||||
peer: EnginePeer,
|
||||
threadInfo: EngineMessageHistoryThread.Info? = nil,
|
||||
height: ItemListPeerItemHeight = .peerList,
|
||||
aliasHandling: ItemListPeerItemAliasHandling = .standard,
|
||||
nameColor: ItemListPeerItemNameColor = .primary,
|
||||
nameStyle: ItemListPeerItemNameStyle = .distinctBold,
|
||||
presence: EnginePeer.Presence?,
|
||||
text: ItemListPeerItemText,
|
||||
label: ItemListPeerItemLabel,
|
||||
editing: ItemListPeerItemEditing,
|
||||
revealOptions: ItemListPeerItemRevealOptions? = nil,
|
||||
switchValue: ItemListPeerItemSwitch?,
|
||||
enabled: Bool,
|
||||
highlighted: Bool = false,
|
||||
selectable: Bool,
|
||||
highlightable: Bool = true,
|
||||
animateFirstAvatarTransition: Bool = true,
|
||||
sectionId: ItemListSectionId,
|
||||
action: (() -> Void)?,
|
||||
setPeerIdWithRevealedOptions: @escaping (EnginePeer.Id?, EnginePeer.Id?) -> Void,
|
||||
removePeer: @escaping (EnginePeer.Id) -> Void,
|
||||
toggleUpdated: ((Bool) -> Void)? = nil,
|
||||
contextAction: ((ASDisplayNode, ContextGesture?) -> Void)? = nil,
|
||||
hasTopStripe: Bool = true,
|
||||
hasTopGroupInset: Bool = true,
|
||||
noInsets: Bool = false,
|
||||
noCorners: Bool = false,
|
||||
tag: ItemListItemTag? = nil,
|
||||
header: ListViewItemHeader? = nil,
|
||||
shimmering: ItemListPeerItemShimmering? = nil,
|
||||
displayDecorations: Bool = true,
|
||||
disableInteractiveTransitionIfNecessary: Bool = false,
|
||||
storyStats: PeerStoryStats? = nil,
|
||||
openStories: ((UIView) -> Void)? = nil
|
||||
) {
|
||||
self.presentationData = presentationData
|
||||
self.dateTimeFormat = dateTimeFormat
|
||||
self.nameDisplayOrder = nameDisplayOrder
|
||||
@ -666,9 +903,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
var updatedLabelBadgeImage: UIImage?
|
||||
var credibilityIcon: EmojiStatusComponent.Content?
|
||||
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: item.context.currentAppConfiguration.with { $0 })
|
||||
|
||||
if case .threatSelfAsSaved = item.aliasHandling, item.peer.id == item.context.account.peerId {
|
||||
if case .threatSelfAsSaved = item.aliasHandling, item.peer.id == item.context.accountPeerId {
|
||||
} else {
|
||||
if item.peer.isScam {
|
||||
credibilityIcon = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_ScamAccount.uppercased())
|
||||
@ -678,7 +913,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
credibilityIcon = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 20.0, height: 20.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
||||
} else if item.peer.isVerified {
|
||||
credibilityIcon = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
||||
} else if item.peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||
} else if item.peer.isPremium && !item.context.isPremiumDisabled {
|
||||
credibilityIcon = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
||||
}
|
||||
}
|
||||
@ -799,7 +1034,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
|
||||
if let threadInfo = item.threadInfo {
|
||||
titleAttributedString = NSAttributedString(string: threadInfo.title, font: currentBoldFont, textColor: titleColor)
|
||||
} else if item.peer.id == item.context.account.peerId, case .threatSelfAsSaved = item.aliasHandling {
|
||||
} else if item.peer.id == item.context.accountPeerId, case .threatSelfAsSaved = item.aliasHandling {
|
||||
titleAttributedString = NSAttributedString(string: item.presentationData.strings.DialogList_SavedMessages, font: currentBoldFont, textColor: titleColor)
|
||||
} else if item.peer.id.isReplies {
|
||||
titleAttributedString = NSAttributedString(string: item.presentationData.strings.DialogList_Replies, font: currentBoldFont, textColor: titleColor)
|
||||
@ -945,8 +1180,11 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
|
||||
let (labelLayout, labelApply) = makeLabelLayout(TextNodeLayoutArguments(attributedString: labelAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 16.0 - editingOffset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 12.0 - editingOffset - rightInset - labelLayout.size.width - labelInset - titleIconsWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 8.0 - editingOffset - rightInset - labelLayout.size.width - labelInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
let constrainedTitleSize = CGSize(width: params.width - leftInset - 12.0 - editingOffset - rightInset - labelLayout.size.width - labelInset - titleIconsWidth, height: CGFloat.greatestFiniteMagnitude)
|
||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: constrainedTitleSize, alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let constrainedStatusSize = CGSize(width: params.width - leftInset - 8.0 - editingOffset - rightInset - labelLayout.size.width - labelInset, height: CGFloat.greatestFiniteMagnitude)
|
||||
let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: constrainedStatusSize, alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
var insets = itemListNeighborsGroupedInsets(neighbors, params)
|
||||
if !item.hasTopGroupInset {
|
||||
@ -1157,7 +1395,9 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
}
|
||||
|
||||
let credibilityIconComponent = EmojiStatusComponent(
|
||||
context: item.context,
|
||||
postbox: item.context.postbox,
|
||||
energyUsageSettings: item.context.energyUsageSettings,
|
||||
resolveInlineStickers: item.context.resolveInlineStickers,
|
||||
animationCache: animationCache,
|
||||
animationRenderer: animationRenderer,
|
||||
content: credibilityIcon,
|
||||
@ -1315,7 +1555,9 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
}
|
||||
|
||||
let avatarIconComponent = EmojiStatusComponent(
|
||||
context: item.context,
|
||||
postbox: item.context.postbox,
|
||||
energyUsageSettings: item.context.energyUsageSettings,
|
||||
resolveInlineStickers: item.context.resolveInlineStickers,
|
||||
animationCache: item.context.animationCache,
|
||||
animationRenderer: item.context.animationRenderer,
|
||||
content: avatarIconContent,
|
||||
@ -1338,10 +1580,30 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
transition.updateFrame(view: avatarIconComponentView, frame: threadIconFrame)
|
||||
}
|
||||
} else {
|
||||
if item.peer.id == item.context.account.peerId, case .threatSelfAsSaved = item.aliasHandling {
|
||||
strongSelf.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: item.peer, overrideImage: .savedMessagesIcon, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, synchronousLoad: synchronousLoad)
|
||||
if item.peer.id == item.context.accountPeerId, case .threatSelfAsSaved = item.aliasHandling {
|
||||
strongSelf.avatarNode.setPeer(
|
||||
accountPeerId: item.context.accountPeerId,
|
||||
postbox: item.context.postbox,
|
||||
network: item.context.network,
|
||||
contentSettings: item.context.contentSettings,
|
||||
theme: item.presentationData.theme,
|
||||
peer: item.peer,
|
||||
overrideImage: .savedMessagesIcon,
|
||||
emptyColor: item.presentationData.theme.list.mediaPlaceholderColor,
|
||||
synchronousLoad: synchronousLoad
|
||||
)
|
||||
} else if item.peer.id.isReplies {
|
||||
strongSelf.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: item.peer, overrideImage: .repliesIcon, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, synchronousLoad: synchronousLoad)
|
||||
strongSelf.avatarNode.setPeer(
|
||||
accountPeerId: item.context.accountPeerId,
|
||||
postbox: item.context.postbox,
|
||||
network: item.context.network,
|
||||
contentSettings: item.context.contentSettings,
|
||||
theme: item.presentationData.theme,
|
||||
peer: item.peer,
|
||||
overrideImage: .repliesIcon,
|
||||
emptyColor: item.presentationData.theme.list.mediaPlaceholderColor,
|
||||
synchronousLoad: synchronousLoad
|
||||
)
|
||||
} else {
|
||||
var overrideImage: AvatarNodeImageOverride?
|
||||
if item.peer.isDeleted {
|
||||
@ -1353,7 +1615,20 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
if case let .channel(channel) = item.peer, channel.isForum {
|
||||
clipStyle = .roundedRect
|
||||
}
|
||||
strongSelf.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: item.peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: clipStyle, synchronousLoad: synchronousLoad)
|
||||
|
||||
strongSelf.avatarNode.setPeer(
|
||||
accountPeerId: item.context.accountPeerId,
|
||||
postbox: item.context.postbox,
|
||||
network: item.context.network,
|
||||
contentSettings: item.context.contentSettings,
|
||||
theme: item.presentationData.theme,
|
||||
peer: item.peer,
|
||||
overrideImage: overrideImage,
|
||||
emptyColor: item.presentationData.theme.list.mediaPlaceholderColor,
|
||||
clipStyle: clipStyle,
|
||||
synchronousLoad: synchronousLoad
|
||||
)
|
||||
|
||||
strongSelf.avatarNode.setStoryStats(storyStats: item.storyStats.flatMap { storyStats in
|
||||
return AvatarNode.StoryStats(
|
||||
totalCount: storyStats.totalCount,
|
||||
|
@ -1427,7 +1427,7 @@ private final class LimitSheetContent: CombinedComponent {
|
||||
if let link {
|
||||
let linkButton = linkButton.update(
|
||||
component: SolidRoundedButtonComponent(
|
||||
title: link,
|
||||
title: link.replacingOccurrences(of: "https://", with: ""),
|
||||
theme: SolidRoundedButtonComponent.Theme(
|
||||
backgroundColor: theme.list.itemBlocksSeparatorColor.withAlphaComponent(0.3),
|
||||
backgroundColors: [],
|
||||
@ -1627,7 +1627,7 @@ private final class LimitSheetComponent: CombinedComponent {
|
||||
isDisplaying: environment.value.isVisible,
|
||||
isCentered: environment.metrics.widthClass == .regular,
|
||||
hasInputHeight: !environment.inputHeight.isZero,
|
||||
regularMetricsSize: nil,
|
||||
regularMetricsSize: CGSize(width: 430.0, height: 900.0),
|
||||
dismiss: { animated in
|
||||
if animated {
|
||||
animateOut.invoke(Action { _ in
|
||||
|
@ -665,15 +665,7 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
|
||||
|
||||
entries.append(.boostLinkTitle(presentationData.theme, presentationData.strings.Stats_Boosts_LinkHeader))
|
||||
|
||||
if let peer {
|
||||
let link: String
|
||||
if let addressName = peer.addressName, !addressName.isEmpty {
|
||||
link = "t.me/\(addressName)?boost"
|
||||
} else {
|
||||
link = "t.me/c/\(peer.id.id._internalGetInt64Value())?boost"
|
||||
}
|
||||
entries.append(.boostLink(presentationData.theme, link))
|
||||
}
|
||||
entries.append(.boostLink(presentationData.theme, boostData.url))
|
||||
|
||||
entries.append(.boostLinkInfo(presentationData.theme, presentationData.strings.Stats_Boosts_LinkInfo))
|
||||
}
|
||||
@ -735,13 +727,11 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
||||
}, contextAction: { messageId, node, gesture in
|
||||
contextActionImpl?(messageId, node, gesture)
|
||||
}, copyBoostLink: { link in
|
||||
UIPasteboard.general.string = "https://\(link)"
|
||||
UIPasteboard.general.string = link
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.ChannelBoost_BoostLinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }))
|
||||
}, shareBoostLink: { link in
|
||||
let link = "https://\(link)"
|
||||
|
||||
}, shareBoostLink: { link in
|
||||
let shareController = ShareController(context: context, subject: .url(link), updatedPresentationData: updatedPresentationData)
|
||||
shareController.completed = { peerIds in
|
||||
let _ = (context.engine.data.get(
|
||||
|
@ -1142,6 +1142,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-1821037486] = { return Api.messages.TranscribedAudio.parse_transcribedAudio($0) }
|
||||
dict[870003448] = { return Api.messages.TranslatedText.parse_translateResult($0) }
|
||||
dict[1218005070] = { return Api.messages.VotesList.parse_votesList($0) }
|
||||
dict[-44166467] = { return Api.messages.WebPage.parse_webPage($0) }
|
||||
dict[1042605427] = { return Api.payments.BankCardData.parse_bankCardData($0) }
|
||||
dict[-1362048039] = { return Api.payments.ExportedInvoice.parse_exportedInvoice($0) }
|
||||
dict[-1610250415] = { return Api.payments.PaymentForm.parse_paymentForm($0) }
|
||||
@ -1177,7 +1178,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[1862033025] = { return Api.stories.AllStories.parse_allStories($0) }
|
||||
dict[291044926] = { return Api.stories.AllStories.parse_allStoriesNotModified($0) }
|
||||
dict[-203604707] = { return Api.stories.BoostersList.parse_boostersList($0) }
|
||||
dict[1726619631] = { return Api.stories.BoostsStatus.parse_boostsStatus($0) }
|
||||
dict[-440292772] = { return Api.stories.BoostsStatus.parse_boostsStatus($0) }
|
||||
dict[-1021889145] = { return Api.stories.CanApplyBoostResult.parse_canApplyBoostOk($0) }
|
||||
dict[1898726997] = { return Api.stories.CanApplyBoostResult.parse_canApplyBoostReplace($0) }
|
||||
dict[-890861720] = { return Api.stories.PeerStories.parse_peerStories($0) }
|
||||
@ -2017,6 +2018,8 @@ public extension Api {
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.VotesList:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.WebPage:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.BankCardData:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.ExportedInvoice:
|
||||
|
@ -432,6 +432,64 @@ public extension Api.messages {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum WebPage: TypeConstructorDescription {
|
||||
case webPage(webpage: Api.WebPage, chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .webPage(let webpage, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-44166467)
|
||||
}
|
||||
webpage.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .webPage(let webpage, let chats, let users):
|
||||
return ("webPage", [("webpage", webpage as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_webPage(_ reader: BufferReader) -> WebPage? {
|
||||
var _1: Api.WebPage?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.WebPage
|
||||
}
|
||||
var _2: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _3: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.messages.WebPage.webPage(webpage: _1!, chats: _2!, users: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum BankCardData: TypeConstructorDescription {
|
||||
case bankCardData(title: String, openUrls: [Api.BankCardOpenUrl])
|
||||
@ -1678,41 +1736,3 @@ public extension Api.stats {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stats {
|
||||
enum MessageStats: TypeConstructorDescription {
|
||||
case messageStats(viewsGraph: Api.StatsGraph)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .messageStats(let viewsGraph):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1986399595)
|
||||
}
|
||||
viewsGraph.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .messageStats(let viewsGraph):
|
||||
return ("messageStats", [("viewsGraph", viewsGraph as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_messageStats(_ reader: BufferReader) -> MessageStats? {
|
||||
var _1: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.stats.MessageStats.messageStats(viewsGraph: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,41 @@
|
||||
public extension Api.stats {
|
||||
enum MessageStats: TypeConstructorDescription {
|
||||
case messageStats(viewsGraph: Api.StatsGraph)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .messageStats(let viewsGraph):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1986399595)
|
||||
}
|
||||
viewsGraph.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .messageStats(let viewsGraph):
|
||||
return ("messageStats", [("viewsGraph", viewsGraph as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_messageStats(_ reader: BufferReader) -> MessageStats? {
|
||||
var _1: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.stats.MessageStats.messageStats(viewsGraph: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stickers {
|
||||
enum SuggestedShortName: TypeConstructorDescription {
|
||||
case suggestedShortName(shortName: String)
|
||||
@ -346,13 +384,13 @@ public extension Api.stories {
|
||||
}
|
||||
public extension Api.stories {
|
||||
enum BoostsStatus: TypeConstructorDescription {
|
||||
case boostsStatus(flags: Int32, level: Int32, currentLevelBoosts: Int32, boosts: Int32, nextLevelBoosts: Int32?, premiumAudience: Api.StatsPercentValue?)
|
||||
case boostsStatus(flags: Int32, level: Int32, currentLevelBoosts: Int32, boosts: Int32, nextLevelBoosts: Int32?, premiumAudience: Api.StatsPercentValue?, boostUrl: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .boostsStatus(let flags, let level, let currentLevelBoosts, let boosts, let nextLevelBoosts, let premiumAudience):
|
||||
case .boostsStatus(let flags, let level, let currentLevelBoosts, let boosts, let nextLevelBoosts, let premiumAudience, let boostUrl):
|
||||
if boxed {
|
||||
buffer.appendInt32(1726619631)
|
||||
buffer.appendInt32(-440292772)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(level, buffer: buffer, boxed: false)
|
||||
@ -360,14 +398,15 @@ public extension Api.stories {
|
||||
serializeInt32(boosts, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(nextLevelBoosts!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {premiumAudience!.serialize(buffer, true)}
|
||||
serializeString(boostUrl, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .boostsStatus(let flags, let level, let currentLevelBoosts, let boosts, let nextLevelBoosts, let premiumAudience):
|
||||
return ("boostsStatus", [("flags", flags as Any), ("level", level as Any), ("currentLevelBoosts", currentLevelBoosts as Any), ("boosts", boosts as Any), ("nextLevelBoosts", nextLevelBoosts as Any), ("premiumAudience", premiumAudience as Any)])
|
||||
case .boostsStatus(let flags, let level, let currentLevelBoosts, let boosts, let nextLevelBoosts, let premiumAudience, let boostUrl):
|
||||
return ("boostsStatus", [("flags", flags as Any), ("level", level as Any), ("currentLevelBoosts", currentLevelBoosts as Any), ("boosts", boosts as Any), ("nextLevelBoosts", nextLevelBoosts as Any), ("premiumAudience", premiumAudience as Any), ("boostUrl", boostUrl as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,14 +425,17 @@ public extension Api.stories {
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.StatsPercentValue
|
||||
} }
|
||||
var _7: String?
|
||||
_7 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 1) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.stories.BoostsStatus.boostsStatus(flags: _1!, level: _2!, currentLevelBoosts: _3!, boosts: _4!, nextLevelBoosts: _5, premiumAudience: _6)
|
||||
let _c7 = _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.stories.BoostsStatus.boostsStatus(flags: _1!, level: _2!, currentLevelBoosts: _3!, boosts: _4!, nextLevelBoosts: _5, premiumAudience: _6, boostUrl: _7!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
@ -1190,91 +1232,3 @@ public extension Api.upload {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.upload {
|
||||
enum File: TypeConstructorDescription {
|
||||
case file(type: Api.storage.FileType, mtime: Int32, bytes: Buffer)
|
||||
case fileCdnRedirect(dcId: Int32, fileToken: Buffer, encryptionKey: Buffer, encryptionIv: Buffer, fileHashes: [Api.FileHash])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .file(let type, let mtime, let bytes):
|
||||
if boxed {
|
||||
buffer.appendInt32(157948117)
|
||||
}
|
||||
type.serialize(buffer, true)
|
||||
serializeInt32(mtime, buffer: buffer, boxed: false)
|
||||
serializeBytes(bytes, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .fileCdnRedirect(let dcId, let fileToken, let encryptionKey, let encryptionIv, let fileHashes):
|
||||
if boxed {
|
||||
buffer.appendInt32(-242427324)
|
||||
}
|
||||
serializeInt32(dcId, buffer: buffer, boxed: false)
|
||||
serializeBytes(fileToken, buffer: buffer, boxed: false)
|
||||
serializeBytes(encryptionKey, buffer: buffer, boxed: false)
|
||||
serializeBytes(encryptionIv, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(fileHashes.count))
|
||||
for item in fileHashes {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .file(let type, let mtime, let bytes):
|
||||
return ("file", [("type", type as Any), ("mtime", mtime as Any), ("bytes", bytes as Any)])
|
||||
case .fileCdnRedirect(let dcId, let fileToken, let encryptionKey, let encryptionIv, let fileHashes):
|
||||
return ("fileCdnRedirect", [("dcId", dcId as Any), ("fileToken", fileToken as Any), ("encryptionKey", encryptionKey as Any), ("encryptionIv", encryptionIv as Any), ("fileHashes", fileHashes as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_file(_ reader: BufferReader) -> File? {
|
||||
var _1: Api.storage.FileType?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.storage.FileType
|
||||
}
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Buffer?
|
||||
_3 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.upload.File.file(type: _1!, mtime: _2!, bytes: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_fileCdnRedirect(_ reader: BufferReader) -> File? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Buffer?
|
||||
_2 = parseBytes(reader)
|
||||
var _3: Buffer?
|
||||
_3 = parseBytes(reader)
|
||||
var _4: Buffer?
|
||||
_4 = parseBytes(reader)
|
||||
var _5: [Api.FileHash]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.FileHash.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.upload.File.fileCdnRedirect(dcId: _1!, fileToken: _2!, encryptionKey: _3!, encryptionIv: _4!, fileHashes: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,91 @@
|
||||
public extension Api.upload {
|
||||
enum File: TypeConstructorDescription {
|
||||
case file(type: Api.storage.FileType, mtime: Int32, bytes: Buffer)
|
||||
case fileCdnRedirect(dcId: Int32, fileToken: Buffer, encryptionKey: Buffer, encryptionIv: Buffer, fileHashes: [Api.FileHash])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .file(let type, let mtime, let bytes):
|
||||
if boxed {
|
||||
buffer.appendInt32(157948117)
|
||||
}
|
||||
type.serialize(buffer, true)
|
||||
serializeInt32(mtime, buffer: buffer, boxed: false)
|
||||
serializeBytes(bytes, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .fileCdnRedirect(let dcId, let fileToken, let encryptionKey, let encryptionIv, let fileHashes):
|
||||
if boxed {
|
||||
buffer.appendInt32(-242427324)
|
||||
}
|
||||
serializeInt32(dcId, buffer: buffer, boxed: false)
|
||||
serializeBytes(fileToken, buffer: buffer, boxed: false)
|
||||
serializeBytes(encryptionKey, buffer: buffer, boxed: false)
|
||||
serializeBytes(encryptionIv, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(fileHashes.count))
|
||||
for item in fileHashes {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .file(let type, let mtime, let bytes):
|
||||
return ("file", [("type", type as Any), ("mtime", mtime as Any), ("bytes", bytes as Any)])
|
||||
case .fileCdnRedirect(let dcId, let fileToken, let encryptionKey, let encryptionIv, let fileHashes):
|
||||
return ("fileCdnRedirect", [("dcId", dcId as Any), ("fileToken", fileToken as Any), ("encryptionKey", encryptionKey as Any), ("encryptionIv", encryptionIv as Any), ("fileHashes", fileHashes as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_file(_ reader: BufferReader) -> File? {
|
||||
var _1: Api.storage.FileType?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.storage.FileType
|
||||
}
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Buffer?
|
||||
_3 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.upload.File.file(type: _1!, mtime: _2!, bytes: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_fileCdnRedirect(_ reader: BufferReader) -> File? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Buffer?
|
||||
_2 = parseBytes(reader)
|
||||
var _3: Buffer?
|
||||
_3 = parseBytes(reader)
|
||||
var _4: Buffer?
|
||||
_4 = parseBytes(reader)
|
||||
var _5: [Api.FileHash]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.FileHash.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.upload.File.fileCdnRedirect(dcId: _1!, fileToken: _2!, encryptionKey: _3!, encryptionIv: _4!, fileHashes: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.upload {
|
||||
enum WebFile: TypeConstructorDescription {
|
||||
case webFile(size: Int32, mimeType: String, fileType: Api.storage.FileType, mtime: Int32, bytes: Buffer)
|
||||
|
@ -5868,16 +5868,16 @@ public extension Api.functions.messages {
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func getWebPage(url: String, hash: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.WebPage>) {
|
||||
static func getWebPage(url: String, hash: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.WebPage>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(852135825)
|
||||
buffer.appendInt32(-1919511901)
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "messages.getWebPage", parameters: [("url", String(describing: url)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.WebPage? in
|
||||
return (FunctionDescription(name: "messages.getWebPage", parameters: [("url", String(describing: url)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.WebPage? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.WebPage?
|
||||
var result: Api.messages.WebPage?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.WebPage
|
||||
result = Api.parse(reader, signature: signature) as? Api.messages.WebPage
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
@ -492,9 +492,9 @@ final class MediaReferenceRevalidationContext {
|
||||
}
|
||||
}
|
||||
|
||||
func webPage(postbox: Postbox, network: Network, background: Bool, webPage: WebpageReference) -> Signal<TelegramMediaWebpage, RevalidateMediaReferenceError> {
|
||||
func webPage(accountPeerId: EnginePeer.Id, postbox: Postbox, network: Network, background: Bool, webPage: WebpageReference) -> Signal<TelegramMediaWebpage, RevalidateMediaReferenceError> {
|
||||
return self.genericItem(key: .webPage(webPage: webPage), background: background, request: { next, error in
|
||||
return (updatedRemoteWebpage(postbox: postbox, network: network, webPage: webPage)
|
||||
return (updatedRemoteWebpage(postbox: postbox, network: network, accountPeerId: accountPeerId, webPage: webPage)
|
||||
|> mapError { _ -> RevalidateMediaReferenceError in
|
||||
}).start(next: { value in
|
||||
if let value = value {
|
||||
@ -792,7 +792,7 @@ func revalidateMediaResourceReference(accountPeerId: PeerId, postbox: Postbox, n
|
||||
return .fail(.generic)
|
||||
}
|
||||
case let .webPage(webPage, previousMedia):
|
||||
return revalidationContext.webPage(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, webPage: webPage)
|
||||
return revalidationContext.webPage(accountPeerId: accountPeerId, postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, webPage: webPage)
|
||||
|> mapToSignal { result -> Signal<RevalidatedMediaResource, RevalidateMediaReferenceError> in
|
||||
if let updatedResource = findUpdatedMediaResource(media: result, previousMedia: previousMedia, resource: resource) {
|
||||
return .single(RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil))
|
||||
|
@ -9,13 +9,15 @@ public final class ChannelBoostStatus: Equatable {
|
||||
public let currentLevelBoosts: Int
|
||||
public let nextLevelBoosts: Int?
|
||||
public let premiumAudience: StatsPercentValue?
|
||||
public let url: String
|
||||
|
||||
public init(level: Int, boosts: Int, currentLevelBoosts: Int, nextLevelBoosts: Int?, premiumAudience: StatsPercentValue?) {
|
||||
public init(level: Int, boosts: Int, currentLevelBoosts: Int, nextLevelBoosts: Int?, premiumAudience: StatsPercentValue?, url: String) {
|
||||
self.level = level
|
||||
self.boosts = boosts
|
||||
self.currentLevelBoosts = currentLevelBoosts
|
||||
self.nextLevelBoosts = nextLevelBoosts
|
||||
self.premiumAudience = premiumAudience
|
||||
self.url = url
|
||||
}
|
||||
|
||||
public static func ==(lhs: ChannelBoostStatus, rhs: ChannelBoostStatus) -> Bool {
|
||||
@ -34,6 +36,9 @@ public final class ChannelBoostStatus: Equatable {
|
||||
if lhs.premiumAudience != rhs.premiumAudience {
|
||||
return false
|
||||
}
|
||||
if lhs.url != rhs.url {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -57,8 +62,8 @@ func _internal_getChannelBoostStatus(account: Account, peerId: PeerId) -> Signal
|
||||
}
|
||||
|
||||
switch result {
|
||||
case let .boostsStatus(_, level, currentLevelBoosts, boosts, nextLevelBoosts, premiumAudience):
|
||||
return ChannelBoostStatus(level: Int(level), boosts: Int(boosts), currentLevelBoosts: Int(currentLevelBoosts), nextLevelBoosts: nextLevelBoosts.flatMap(Int.init), premiumAudience: premiumAudience.flatMap({ StatsPercentValue(apiPercentValue: $0) }))
|
||||
case let .boostsStatus(_, level, currentLevelBoosts, boosts, nextLevelBoosts, premiumAudience, url):
|
||||
return ChannelBoostStatus(level: Int(level), boosts: Int(boosts), currentLevelBoosts: Int(currentLevelBoosts), nextLevelBoosts: nextLevelBoosts.flatMap(Int.init), premiumAudience: premiumAudience.flatMap({ StatsPercentValue(apiPercentValue: $0) }), url: url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
|
||||
|
||||
public class Serialization: NSObject, MTSerialization {
|
||||
public func currentLayer() -> UInt {
|
||||
return 164
|
||||
return 165
|
||||
}
|
||||
|
||||
public func parseMessage(_ data: Data!) -> Any! {
|
||||
|
@ -74,45 +74,54 @@ public func webpagePreviewWithProgress(account: Account, url: String, webpageId:
|
||||
|> switchToLatest
|
||||
}
|
||||
|
||||
public func actualizedWebpage(postbox: Postbox, network: Network, webpage: TelegramMediaWebpage) -> Signal<TelegramMediaWebpage, NoError> {
|
||||
public func actualizedWebpage(account: Account, webpage: TelegramMediaWebpage) -> Signal<TelegramMediaWebpage, NoError> {
|
||||
if case let .Loaded(content) = webpage.content {
|
||||
return network.request(Api.functions.messages.getWebPage(url: content.url, hash: content.hash))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.WebPage?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<TelegramMediaWebpage, NoError> in
|
||||
if let result = result, let updatedWebpage = telegramMediaWebpageFromApiWebpage(result, url: nil), case .Loaded = updatedWebpage.content, updatedWebpage.webpageId == webpage.webpageId {
|
||||
return postbox.transaction { transaction -> TelegramMediaWebpage in
|
||||
updateMessageMedia(transaction: transaction, id: webpage.webpageId, media: updatedWebpage)
|
||||
return updatedWebpage
|
||||
return account.network.request(Api.functions.messages.getWebPage(url: content.url, hash: content.hash))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.messages.WebPage?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<TelegramMediaWebpage, NoError> in
|
||||
if let result = result {
|
||||
return account.postbox.transaction { transaction -> Signal<TelegramMediaWebpage, NoError> in
|
||||
switch result {
|
||||
case let .webPage(apiWebpage, chats, users):
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: parsedPeers)
|
||||
|
||||
if let updatedWebpage = telegramMediaWebpageFromApiWebpage(apiWebpage, url: nil), case .Loaded = updatedWebpage.content, updatedWebpage.webpageId == webpage.webpageId {
|
||||
return .single(updatedWebpage)
|
||||
} else if case let .webPageNotModified(_, viewsValue) = apiWebpage, let views = viewsValue, case let .Loaded(content) = webpage.content {
|
||||
let updatedContent: TelegramMediaWebpageContent = .Loaded(TelegramMediaWebpageLoadedContent(url: content.url, displayUrl: content.displayUrl, hash: content.hash, type: content.type, websiteName: content.websiteName, title: content.title, text: content.text, embedUrl: content.embedUrl, embedType: content.embedType, embedSize: content.embedSize, duration: content.duration, author: content.author, image: content.image, file: content.file, story: content.story, attributes: content.attributes, instantPage: content.instantPage.flatMap({ InstantPage(blocks: $0.blocks, media: $0.media, isComplete: $0.isComplete, rtl: $0.rtl, url: $0.url, views: views) })))
|
||||
let updatedWebpage = TelegramMediaWebpage(webpageId: webpage.webpageId, content: updatedContent)
|
||||
updateMessageMedia(transaction: transaction, id: webpage.webpageId, media: updatedWebpage)
|
||||
return .single(updatedWebpage)
|
||||
}
|
||||
}
|
||||
} else if let result = result, case let .webPageNotModified(_, viewsValue) = result, let views = viewsValue, case let .Loaded(content) = webpage.content {
|
||||
let updatedContent: TelegramMediaWebpageContent = .Loaded(TelegramMediaWebpageLoadedContent(url: content.url, displayUrl: content.displayUrl, hash: content.hash, type: content.type, websiteName: content.websiteName, title: content.title, text: content.text, embedUrl: content.embedUrl, embedType: content.embedType, embedSize: content.embedSize, duration: content.duration, author: content.author, image: content.image, file: content.file, story: content.story, attributes: content.attributes, instantPage: content.instantPage.flatMap({ InstantPage(blocks: $0.blocks, media: $0.media, isComplete: $0.isComplete, rtl: $0.rtl, url: $0.url, views: views) })))
|
||||
let updatedWebpage = TelegramMediaWebpage(webpageId: webpage.webpageId, content: updatedContent)
|
||||
return postbox.transaction { transaction -> TelegramMediaWebpage in
|
||||
updateMessageMedia(transaction: transaction, id: webpage.webpageId, media: updatedWebpage)
|
||||
return updatedWebpage
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
|> switchToLatest
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
|
||||
func updatedRemoteWebpage(postbox: Postbox, network: Network, webPage: WebpageReference) -> Signal<TelegramMediaWebpage?, NoError> {
|
||||
func updatedRemoteWebpage(postbox: Postbox, network: Network, accountPeerId: EnginePeer.Id, webPage: WebpageReference) -> Signal<TelegramMediaWebpage?, NoError> {
|
||||
if case let .webPage(id, url) = webPage.content {
|
||||
return network.request(Api.functions.messages.getWebPage(url: url, hash: 0))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.WebPage?, NoError> in
|
||||
|> `catch` { _ -> Signal<Api.messages.WebPage?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<TelegramMediaWebpage?, NoError> in
|
||||
if let result = result, let updatedWebpage = telegramMediaWebpageFromApiWebpage(result, url: nil), case .Loaded = updatedWebpage.content, updatedWebpage.webpageId.id == id {
|
||||
if let result = result, case let .webPage(webpage, chats, users) = result, let updatedWebpage = telegramMediaWebpageFromApiWebpage(webpage, url: nil), case .Loaded = updatedWebpage.content, updatedWebpage.webpageId.id == id {
|
||||
return postbox.transaction { transaction -> TelegramMediaWebpage? in
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
||||
if transaction.getMedia(updatedWebpage.webpageId) != nil {
|
||||
updateMessageMedia(transaction: transaction, id: updatedWebpage.webpageId, media: updatedWebpage)
|
||||
}
|
||||
|
@ -1106,20 +1106,14 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
return
|
||||
}
|
||||
|
||||
let link: String
|
||||
if let addressName = peer.addressName, !addressName.isEmpty {
|
||||
link = "t.me/\(peer.addressName ?? "")?boost"
|
||||
} else {
|
||||
link = "t.me/c/\(peer.id.id._internalGetInt64Value())?boost"
|
||||
}
|
||||
|
||||
let link = status.url
|
||||
if let navigationController = self.environment?.controller()?.navigationController as? NavigationController {
|
||||
if let previousController = navigationController.viewControllers.last as? ShareWithPeersScreen {
|
||||
previousController.dismiss()
|
||||
}
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let controller = component.context.sharedContext.makePremiumLimitController(context: component.context, subject: .storiesChannelBoost(peer: peer, isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, boosted: false), count: Int32(status.boosts), forceDark: true, cancel: {}, action: { [weak navigationController] in
|
||||
UIPasteboard.general.string = "https://\(link)"
|
||||
UIPasteboard.general.string = link
|
||||
|
||||
if let previousController = navigationController?.viewControllers.reversed().first(where: { $0 is ShareWithPeersScreen}) as? ShareWithPeersScreen {
|
||||
previousController.dismiss(completion: { [weak navigationController] in
|
||||
|
@ -870,18 +870,24 @@ public final class TextFieldComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
let wasEditing = component.externalState.isEditing
|
||||
let isEditing = self.textView.isFirstResponder
|
||||
|
||||
if self.textView.textContainerInset != component.insets {
|
||||
self.textView.textContainerInset = component.insets
|
||||
}
|
||||
|
||||
var availableSize = availableSize
|
||||
if !isEditing && component.isOneLineWhenUnfocused {
|
||||
availableSize.width += 32.0
|
||||
}
|
||||
|
||||
self.textContainer.size = CGSize(width: availableSize.width - self.textView.textContainerInset.left - self.textView.textContainerInset.right, height: 10000000.0)
|
||||
self.layoutManager.ensureLayout(for: self.textContainer)
|
||||
|
||||
let boundingRect = self.layoutManager.boundingRect(forGlyphRange: NSRange(location: 0, length: self.textStorage.length), in: self.textContainer)
|
||||
let size = CGSize(width: availableSize.width, height: min(availableSize.height, ceil(boundingRect.height) + self.textView.textContainerInset.top + self.textView.textContainerInset.bottom))
|
||||
|
||||
let wasEditing = component.externalState.isEditing
|
||||
let isEditing = self.textView.isFirstResponder
|
||||
|
||||
var refreshScrolling = self.textView.bounds.size != size
|
||||
if component.isOneLineWhenUnfocused && !isEditing && isEditing != wasEditing {
|
||||
refreshScrolling = true
|
||||
@ -953,6 +959,7 @@ public final class TextFieldComponent: Component {
|
||||
if let view = self.ellipsisView.view {
|
||||
if view.superview == nil {
|
||||
view.alpha = 0.0
|
||||
view.isUserInteractionEnabled = false
|
||||
self.textView.addSubview(view)
|
||||
}
|
||||
let ellipsisFrame = CGRect(origin: CGPoint(x: position.x - 8.0, y: position.y), size: ellipsisSize)
|
||||
|
@ -138,7 +138,7 @@ private final class PeerInfoScreenActionItemNode: PeerInfoScreenItemNode {
|
||||
transition.updateFrame(node: self.iconNode, frame: iconFrame)
|
||||
} else if let iconSignal = item.iconSignal {
|
||||
self.iconDisposable.set((iconSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] image in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] image in
|
||||
if let strongSelf = self, let image {
|
||||
strongSelf.iconNode.image = image
|
||||
let iconFrame = CGRect(origin: CGPoint(x: iconInset, y: floorToScreenPixels((height - image.size.height) / 2.0)), size: image.size)
|
||||
|
@ -170,7 +170,7 @@ private final class PeerInfoScreenDisclosureItemNode: PeerInfoScreenItemNode {
|
||||
if previousItem?.text != item.text {
|
||||
self.iconNode.image = nil
|
||||
self.iconDisposable = (iconSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] icon in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] icon in
|
||||
if let self {
|
||||
self.iconNode.image = icon
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ enum PeerInfoScreenMemberItemAction {
|
||||
|
||||
final class PeerInfoScreenMemberItem: PeerInfoScreenItem {
|
||||
let id: AnyHashable
|
||||
let context: AccountContext
|
||||
let context: ItemListPeerItem.Context
|
||||
let enclosingPeer: Peer?
|
||||
let member: PeerInfoMember
|
||||
let badge: String?
|
||||
@ -30,7 +30,7 @@ final class PeerInfoScreenMemberItem: PeerInfoScreenItem {
|
||||
|
||||
init(
|
||||
id: AnyHashable,
|
||||
context: AccountContext,
|
||||
context: ItemListPeerItem.Context,
|
||||
enclosingPeer: Peer?,
|
||||
member: PeerInfoMember,
|
||||
badge: String? = nil,
|
||||
@ -149,7 +149,7 @@ private final class PeerInfoScreenMemberItemNode: PeerInfoScreenItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
let actions = availableActionsForMemberOfPeer(accountPeerId: item.context.account.peerId, peer: item.enclosingPeer, member: item.member)
|
||||
let actions = availableActionsForMemberOfPeer(accountPeerId: item.context.accountPeerId, peer: item.enclosingPeer, member: item.member)
|
||||
|
||||
var options: [ItemListPeerItemRevealOption] = []
|
||||
if actions.contains(.promote) && item.enclosingPeer is TelegramChannel {
|
||||
@ -272,7 +272,7 @@ private final class PeerInfoScreenMemberItemNode: PeerInfoScreenItemNode {
|
||||
}
|
||||
var highlight = point != nil
|
||||
if case .account = item.member {
|
||||
} else if item.context.account.peerId == item.member.id {
|
||||
} else if item.context.accountPeerId == item.member.id {
|
||||
highlight = false
|
||||
}
|
||||
if let point, let itemNode = self.itemNode, let value = itemNode.view.hitTest(self.view.convert(point, to: itemNode.view), with: nil), value is UIControl {
|
||||
|
@ -118,7 +118,7 @@ final class PeerInfoGroupsInCommonPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
self.addSubnode(self.listNode)
|
||||
|
||||
self.disposable = (groupsInCommonContext.state
|
||||
|> deliverOnMainQueue).start(next: { [weak self] state in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] playlistStateAndType in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] playlistStateAndType in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -275,7 +275,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
})
|
||||
return rate
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { baseRate in
|
||||
|> deliverOnMainQueue).startStandalone(next: { baseRate in
|
||||
guard let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType else {
|
||||
return
|
||||
}
|
||||
@ -392,7 +392,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
progressDisposable.dispose()
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { index in
|
||||
|> deliverOnMainQueue).startStandalone(next: { index in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -409,7 +409,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
} else if index.1 {
|
||||
if !progressStarted {
|
||||
progressStarted = true
|
||||
progressDisposable.set(progressSignal.start())
|
||||
progressDisposable.set(progressSignal.startStandalone())
|
||||
}
|
||||
}
|
||||
}, completed: {
|
||||
|
@ -201,7 +201,7 @@ final class PeerInfoMembersPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
self.presentationDataPromise.get(),
|
||||
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] state, presentationData, enclosingPeer in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] state, presentationData, enclosingPeer in
|
||||
guard let strongSelf = self, let enclosingPeer = enclosingPeer else {
|
||||
return
|
||||
}
|
||||
@ -222,6 +222,7 @@ final class PeerInfoMembersPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.disposable?.dispose()
|
||||
}
|
||||
|
||||
func ensureMessageIsVisible(id: MessageId) {
|
||||
|
@ -2854,7 +2854,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}).start(next: { fileAndPackTitle in
|
||||
}).startStrict(next: { fileAndPackTitle in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ private final class PeerInfoMembersContextImpl {
|
||||
self.channelMembersControl = control
|
||||
|
||||
self.peerDisposable.set((context.account.postbox.peerView(id: peerId)
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] view in
|
||||
|> deliverOn(self.queue)).startStrict(next: { [weak self] view in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -223,7 +223,7 @@ private final class PeerInfoMembersContextImpl {
|
||||
}))
|
||||
} else if peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||
self.disposable.set((context.account.postbox.peerView(id: peerId)
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] view in
|
||||
|> deliverOn(self.queue)).startStrict(next: { [weak self] view in
|
||||
guard let strongSelf = self, let cachedData = view.cachedData as? CachedGroupData, let participantsData = cachedData.participants else {
|
||||
return
|
||||
}
|
||||
@ -316,7 +316,7 @@ private final class PeerInfoMembersContextImpl {
|
||||
self.pushState()
|
||||
|
||||
disposable.set((signal
|
||||
|> deliverOn(self.queue)).start(completed: {
|
||||
|> deliverOn(self.queue)).startStrict(completed: {
|
||||
completed()
|
||||
}))
|
||||
}
|
||||
|
@ -421,7 +421,7 @@ private final class PeerInfoPendingPane {
|
||||
self.pane = PeerInfoPaneWrapper(key: key, node: paneNode)
|
||||
self.disposable = (paneNode.isReady
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] _ in
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] _ in
|
||||
self?.isReady = true
|
||||
hasBecomeReady(key)
|
||||
})
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -212,6 +212,13 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? {
|
||||
}
|
||||
}
|
||||
return .share(url: url, text: text, to: to)
|
||||
} else if peerName == "boost" {
|
||||
for queryItem in queryItems {
|
||||
if queryItem.name == "c", let value = queryItem.value, let channelId = Int64(value) {
|
||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
|
||||
return .peer(.id(peerId), .boost)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for queryItem in queryItems {
|
||||
if let value = queryItem.value {
|
||||
@ -444,6 +451,8 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? {
|
||||
return .theme(pathComponents[1])
|
||||
} else if pathComponents[0] == "addlist" || pathComponents[0] == "folder" || pathComponents[0] == "list" {
|
||||
return .chatFolder(slug: pathComponents[1])
|
||||
} else if pathComponents[0] == "boost", pathComponents.count == 2 {
|
||||
return .peer(.name(pathComponents[1]), .boost)
|
||||
} else if pathComponents.count == 3 && pathComponents[0] == "c" {
|
||||
if let channelId = Int64(pathComponents[1]), let messageId = Int32(pathComponents[2]) {
|
||||
var threadId: Int32?
|
||||
|
Loading…
x
Reference in New Issue
Block a user