Various fixes

This commit is contained in:
Ilya Laktyushin 2023-08-08 15:20:07 +02:00
parent 67c07d35ed
commit 29707a7264
5 changed files with 105 additions and 36 deletions

View File

@ -163,10 +163,22 @@ private final class StickerSelectionComponent: Component {
},
sendEmoji: { _, _, _ in
},
sendGif: { _, _, _, _, _ in
sendGif: { [weak self] file, _, _, _, _ in
if let self, let controller = self.component?.getController() {
controller.completion(.video(file.media))
controller.dismiss(animated: true)
}
return false
},
sendBotContextResultAsGif: { _, _, _, _, _, _ in
sendBotContextResultAsGif: { [weak self] collection, result, _, _, _, _ in
if let self, let controller = self.component?.getController() {
if case let .internalReference(reference) = result {
if let file = reference.file {
controller.completion(.video(file))
controller.dismiss(animated: true)
}
}
}
return false
},
updateChoosingSticker: { _ in },
@ -320,7 +332,7 @@ private final class StickerSelectionComponent: Component {
inputNodeInteraction: inputNodeInteraction,
mode: mappedMode,
stickerActionTitle: presentationData.strings.StickerPack_AddSticker,
trendingGifsPromise: Promise(nil),
trendingGifsPromise: self.component?.getController()?.node.trendingGifsPromise ?? Promise(nil),
cancel: {
},
peekBehavior: stickerPeekBehavior
@ -416,7 +428,7 @@ public class StickerPickerScreen: ViewController {
private var content: StickerPickerInputData?
private let contentDisposable = MetaDisposable()
private var hasRecentGifsDisposable: Disposable?
private let trendingGifsPromise = Promise<ChatMediaInputGifPaneTrendingState?>(nil)
fileprivate let trendingGifsPromise = Promise<ChatMediaInputGifPaneTrendingState?>(nil)
private var scheduledEmojiContentAnimationHint: EmojiPagerContentComponent.ContentAnimation?
private(set) var isExpanded = false
@ -584,6 +596,16 @@ public class StickerPickerScreen: ViewController {
})
}
self.trendingGifsPromise.set(.single(nil))
self.trendingGifsPromise.set(paneGifSearchForQuery(context: context, query: "", offset: nil, incompleteResults: true, delayRequest: false, updateActivity: nil)
|> map { items -> ChatMediaInputGifPaneTrendingState? in
if let items = items {
return ChatMediaInputGifPaneTrendingState(files: items.files, nextOffset: items.nextOffset)
} else {
return nil
}
})
self.gifInputInteraction = GifPagerContentComponent.InputInteraction(
performItemAction: { [weak self] item, view, rect in
guard let self else {

View File

@ -100,7 +100,7 @@ public final class TwoFactorDataInputScreen: ViewController {
super.viewWillAppear(animated)
switch self.mode {
case .rememberPassword, .password:
case .rememberPassword, .password, .passwordHint, .emailAddress:
(self.displayNode as? TwoFactorDataInputScreenNode)?.focus()
default:
break
@ -210,6 +210,7 @@ public final class TwoFactorDataInputScreen: ViewController {
navigationController.replaceController(strongSelf, with: TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .passwordHint(recovery: recovery, password: values[0], doneText: doneText), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation), animated: true)
case let .emailAddress(password, hint, doneText):
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
(strongSelf.displayNode as? TwoFactorDataInputScreenNode)?.onAction(success: false)
return
}
let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: nil))
@ -1303,6 +1304,8 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
}
}
private var skipIsHiddenUntilError = false
init(sharedContext: SharedAccountContext, presentationData: PresentationData, mode: TwoFactorDataInputMode, action: @escaping () -> Void, skipAction: @escaping () -> Void, changeEmailAction: @escaping () -> Void, resendCodeAction: @escaping () -> Void) {
self.presentationData = presentationData
self.mode = mode
@ -1413,6 +1416,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
text = NSAttributedString(string: presentationData.strings.TwoFactorSetup_Email_Text, font: Font.regular(16.0), textColor: presentationData.theme.list.itemPrimaryTextColor)
buttonText = presentationData.strings.TwoFactorSetup_Email_Action
skipActionText = presentationData.strings.TwoFactorSetup_Email_SkipAction
self.skipIsHiddenUntilError = true
changeEmailActionText = ""
resendCodeActionText = ""
inputNodes = [
@ -1538,8 +1542,8 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
self.skipActionTitleNode.displaysAsynchronously = false
self.skipActionTitleNode.attributedText = NSAttributedString(string: skipActionText, font: Font.regular(16.0), textColor: self.presentationData.theme.list.itemAccentColor)
self.skipActionButtonNode = HighlightTrackingButtonNode()
self.skipActionTitleNode.isHidden = skipActionText.isEmpty
self.skipActionButtonNode.isHidden = skipActionText.isEmpty
self.skipActionTitleNode.isHidden = skipActionText.isEmpty || self.skipIsHiddenUntilError
self.skipActionButtonNode.isHidden = skipActionText.isEmpty || self.skipIsHiddenUntilError
self.changeEmailActionTitleNode = ImmediateTextNode()
self.changeEmailActionTitleNode.isUserInteractionEnabled = false
@ -1707,8 +1711,8 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
case .emailAddress, .updateEmailAddress, .passwordRecovery:
let hasText = strongSelf.inputNodes.contains(where: { !$0.text.isEmpty })
strongSelf.buttonNode.isHidden = !hasText
strongSelf.skipActionTitleNode.isHidden = hasText
strongSelf.skipActionButtonNode.isHidden = hasText
strongSelf.skipActionTitleNode.isHidden = hasText || strongSelf.skipIsHiddenUntilError
strongSelf.skipActionButtonNode.isHidden = hasText || strongSelf.skipIsHiddenUntilError
case let .emailConfirmation(_, _, codeLength, _):
let text = strongSelf.inputNodes[0].text
let hasText = !text.isEmpty
@ -1822,35 +1826,48 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
func onAction(success: Bool) {
switch self.mode {
case .rememberPassword:
if !success {
case .emailAddress:
if !success {
self.inputNodes.first?.layer.addShakeAnimation()
HapticFeedback().error()
if self.skipIsHiddenUntilError {
self.skipIsHiddenUntilError = false
self.skipActionTitleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.skipActionTitleNode.layer.animateScale(from: 0.1, to: 1.0, duration: 0.2)
self.skipActionTitleNode.isHidden = false
self.skipActionButtonNode.isHidden = false
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
transition.updateAlpha(node: self.buttonNode, alpha: 0.0)
transition.updateAlpha(node: self.skipActionTitleNode, alpha: 1.0)
if let snapshotView = self.textNode.view.snapshotContentTree() {
snapshotView.frame = self.textNode.view.frame
self.textNode.view.superview?.addSubview(snapshotView)
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak snapshotView] _ in
snapshotView?.removeFromSuperview()
})
self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
}
self.textNode.attributedText = NSAttributedString(string: self.presentationData.strings.TwoFactorRemember_WrongPassword, font: Font.regular(16.0), textColor: self.presentationData.theme.list.itemDestructiveColor)
self.inputNodes.first?.isFailed = true
if let (layout, navigationHeight) = self.validLayout {
self.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate)
}
}
default:
break
}
case .rememberPassword:
if !success {
self.skipActionTitleNode.isHidden = false
self.skipActionButtonNode.isHidden = false
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
transition.updateAlpha(node: self.buttonNode, alpha: 0.0)
transition.updateAlpha(node: self.skipActionTitleNode, alpha: 1.0)
if let snapshotView = self.textNode.view.snapshotContentTree() {
snapshotView.frame = self.textNode.view.frame
self.textNode.view.superview?.addSubview(snapshotView)
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak snapshotView] _ in
snapshotView?.removeFromSuperview()
})
self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
}
self.textNode.attributedText = NSAttributedString(string: self.presentationData.strings.TwoFactorRemember_WrongPassword, font: Font.regular(16.0), textColor: self.presentationData.theme.list.itemDestructiveColor)
self.inputNodes.first?.isFailed = true
if let (layout, navigationHeight) = self.validLayout {
self.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate)
}
}
default:
break
}
}

View File

@ -401,7 +401,8 @@ public final class PeerListItemComponent: Component {
let labelData: (String, Bool)
if let presence = component.presence {
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
labelData = stringAndActivityForUserPresence(strings: component.strings, dateTimeFormat: PresentationDateTimeFormat(), presence: presence, relativeTo: Int32(timestamp))
let dateTimeFormat = component.context.sharedContext.currentPresentationData.with { $0 }.dateTimeFormat
labelData = stringAndActivityForUserPresence(strings: component.strings, dateTimeFormat: dateTimeFormat, presence: presence, relativeTo: Int32(timestamp))
} else if let subtitle = component.subtitle {
labelData = (subtitle, false)
} else {

View File

@ -32,6 +32,7 @@ swift_library(
"//submodules/AppBundle:AppBundle",
"//submodules/PresentationDataUtils:PresentationDataUtils",
"//submodules/AttachmentUI:AttachmentUI",
"//submodules/RadialStatusNode:RadialStatusNode",
],
visibility = [
"//visibility:public",

View File

@ -7,6 +7,7 @@ import SwiftSignalKit
import TelegramPresentationData
import CheckNode
import PhotoResources
import RadialStatusNode
final class WebSearchItem: GridItem {
var section: GridSection?
@ -44,6 +45,7 @@ final class WebSearchItemNode: GridItemNode {
private let imageNodeBackground: ASDisplayNode
private let imageNode: TransformImageNode
private var checkNode: CheckNode?
private var statusNode: RadialStatusNode?
private(set) var item: WebSearchItem?
private var currentDimensions: CGSize?
@ -81,6 +83,32 @@ final class WebSearchItemNode: GridItemNode {
self.imageNode.view.addGestureRecognizer(recognizer)
}
func updateProgress(_ value: Float?, animated: Bool) {
if let value {
let statusNode: RadialStatusNode
if let current = self.statusNode {
statusNode = current
} else {
statusNode = RadialStatusNode(backgroundNodeColor: UIColor(rgb: 0x000000, alpha: 0.6))
statusNode.isUserInteractionEnabled = false
self.addSubnode(statusNode)
self.statusNode = statusNode
}
let adjustedProgress = max(0.027, CGFloat(value))
let state: RadialStatusNodeState = .progress(color: .white, lineWidth: nil, value: adjustedProgress, cancelEnabled: true, animateRotation: true)
statusNode.transitionToState(state)
} else if let statusNode = self.statusNode {
self.statusNode = nil
if animated {
statusNode.transitionToState(.none, animated: true, completion: { [weak statusNode] in
statusNode?.removeFromSupernode()
})
} else {
statusNode.removeFromSupernode()
}
}
}
func setup(item: WebSearchItem, synchronousLoad: Bool) {
if self.item !== item {
var updateImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>?