mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
67c07d35ed
commit
29707a7264
@ -163,10 +163,22 @@ private final class StickerSelectionComponent: Component {
|
|||||||
},
|
},
|
||||||
sendEmoji: { _, _, _ in
|
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
|
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
|
return false
|
||||||
},
|
},
|
||||||
updateChoosingSticker: { _ in },
|
updateChoosingSticker: { _ in },
|
||||||
@ -320,7 +332,7 @@ private final class StickerSelectionComponent: Component {
|
|||||||
inputNodeInteraction: inputNodeInteraction,
|
inputNodeInteraction: inputNodeInteraction,
|
||||||
mode: mappedMode,
|
mode: mappedMode,
|
||||||
stickerActionTitle: presentationData.strings.StickerPack_AddSticker,
|
stickerActionTitle: presentationData.strings.StickerPack_AddSticker,
|
||||||
trendingGifsPromise: Promise(nil),
|
trendingGifsPromise: self.component?.getController()?.node.trendingGifsPromise ?? Promise(nil),
|
||||||
cancel: {
|
cancel: {
|
||||||
},
|
},
|
||||||
peekBehavior: stickerPeekBehavior
|
peekBehavior: stickerPeekBehavior
|
||||||
@ -416,7 +428,7 @@ public class StickerPickerScreen: ViewController {
|
|||||||
private var content: StickerPickerInputData?
|
private var content: StickerPickerInputData?
|
||||||
private let contentDisposable = MetaDisposable()
|
private let contentDisposable = MetaDisposable()
|
||||||
private var hasRecentGifsDisposable: Disposable?
|
private var hasRecentGifsDisposable: Disposable?
|
||||||
private let trendingGifsPromise = Promise<ChatMediaInputGifPaneTrendingState?>(nil)
|
fileprivate let trendingGifsPromise = Promise<ChatMediaInputGifPaneTrendingState?>(nil)
|
||||||
private var scheduledEmojiContentAnimationHint: EmojiPagerContentComponent.ContentAnimation?
|
private var scheduledEmojiContentAnimationHint: EmojiPagerContentComponent.ContentAnimation?
|
||||||
|
|
||||||
private(set) var isExpanded = false
|
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(
|
self.gifInputInteraction = GifPagerContentComponent.InputInteraction(
|
||||||
performItemAction: { [weak self] item, view, rect in
|
performItemAction: { [weak self] item, view, rect in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
|
@ -100,7 +100,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
|
|
||||||
switch self.mode {
|
switch self.mode {
|
||||||
case .rememberPassword, .password:
|
case .rememberPassword, .password, .passwordHint, .emailAddress:
|
||||||
(self.displayNode as? TwoFactorDataInputScreenNode)?.focus()
|
(self.displayNode as? TwoFactorDataInputScreenNode)?.focus()
|
||||||
default:
|
default:
|
||||||
break
|
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)
|
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):
|
case let .emailAddress(password, hint, doneText):
|
||||||
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
||||||
|
(strongSelf.displayNode as? TwoFactorDataInputScreenNode)?.onAction(success: false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: nil))
|
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) {
|
init(sharedContext: SharedAccountContext, presentationData: PresentationData, mode: TwoFactorDataInputMode, action: @escaping () -> Void, skipAction: @escaping () -> Void, changeEmailAction: @escaping () -> Void, resendCodeAction: @escaping () -> Void) {
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
self.mode = mode
|
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)
|
text = NSAttributedString(string: presentationData.strings.TwoFactorSetup_Email_Text, font: Font.regular(16.0), textColor: presentationData.theme.list.itemPrimaryTextColor)
|
||||||
buttonText = presentationData.strings.TwoFactorSetup_Email_Action
|
buttonText = presentationData.strings.TwoFactorSetup_Email_Action
|
||||||
skipActionText = presentationData.strings.TwoFactorSetup_Email_SkipAction
|
skipActionText = presentationData.strings.TwoFactorSetup_Email_SkipAction
|
||||||
|
self.skipIsHiddenUntilError = true
|
||||||
changeEmailActionText = ""
|
changeEmailActionText = ""
|
||||||
resendCodeActionText = ""
|
resendCodeActionText = ""
|
||||||
inputNodes = [
|
inputNodes = [
|
||||||
@ -1538,8 +1542,8 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
|||||||
self.skipActionTitleNode.displaysAsynchronously = false
|
self.skipActionTitleNode.displaysAsynchronously = false
|
||||||
self.skipActionTitleNode.attributedText = NSAttributedString(string: skipActionText, font: Font.regular(16.0), textColor: self.presentationData.theme.list.itemAccentColor)
|
self.skipActionTitleNode.attributedText = NSAttributedString(string: skipActionText, font: Font.regular(16.0), textColor: self.presentationData.theme.list.itemAccentColor)
|
||||||
self.skipActionButtonNode = HighlightTrackingButtonNode()
|
self.skipActionButtonNode = HighlightTrackingButtonNode()
|
||||||
self.skipActionTitleNode.isHidden = skipActionText.isEmpty
|
self.skipActionTitleNode.isHidden = skipActionText.isEmpty || self.skipIsHiddenUntilError
|
||||||
self.skipActionButtonNode.isHidden = skipActionText.isEmpty
|
self.skipActionButtonNode.isHidden = skipActionText.isEmpty || self.skipIsHiddenUntilError
|
||||||
|
|
||||||
self.changeEmailActionTitleNode = ImmediateTextNode()
|
self.changeEmailActionTitleNode = ImmediateTextNode()
|
||||||
self.changeEmailActionTitleNode.isUserInteractionEnabled = false
|
self.changeEmailActionTitleNode.isUserInteractionEnabled = false
|
||||||
@ -1707,8 +1711,8 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
|||||||
case .emailAddress, .updateEmailAddress, .passwordRecovery:
|
case .emailAddress, .updateEmailAddress, .passwordRecovery:
|
||||||
let hasText = strongSelf.inputNodes.contains(where: { !$0.text.isEmpty })
|
let hasText = strongSelf.inputNodes.contains(where: { !$0.text.isEmpty })
|
||||||
strongSelf.buttonNode.isHidden = !hasText
|
strongSelf.buttonNode.isHidden = !hasText
|
||||||
strongSelf.skipActionTitleNode.isHidden = hasText
|
strongSelf.skipActionTitleNode.isHidden = hasText || strongSelf.skipIsHiddenUntilError
|
||||||
strongSelf.skipActionButtonNode.isHidden = hasText
|
strongSelf.skipActionButtonNode.isHidden = hasText || strongSelf.skipIsHiddenUntilError
|
||||||
case let .emailConfirmation(_, _, codeLength, _):
|
case let .emailConfirmation(_, _, codeLength, _):
|
||||||
let text = strongSelf.inputNodes[0].text
|
let text = strongSelf.inputNodes[0].text
|
||||||
let hasText = !text.isEmpty
|
let hasText = !text.isEmpty
|
||||||
@ -1822,6 +1826,19 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
|||||||
|
|
||||||
func onAction(success: Bool) {
|
func onAction(success: Bool) {
|
||||||
switch self.mode {
|
switch self.mode {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
case .rememberPassword:
|
case .rememberPassword:
|
||||||
if !success {
|
if !success {
|
||||||
self.skipActionTitleNode.isHidden = false
|
self.skipActionTitleNode.isHidden = false
|
||||||
|
@ -401,7 +401,8 @@ public final class PeerListItemComponent: Component {
|
|||||||
let labelData: (String, Bool)
|
let labelData: (String, Bool)
|
||||||
if let presence = component.presence {
|
if let presence = component.presence {
|
||||||
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
|
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 {
|
} else if let subtitle = component.subtitle {
|
||||||
labelData = (subtitle, false)
|
labelData = (subtitle, false)
|
||||||
} else {
|
} else {
|
||||||
|
@ -32,6 +32,7 @@ swift_library(
|
|||||||
"//submodules/AppBundle:AppBundle",
|
"//submodules/AppBundle:AppBundle",
|
||||||
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
||||||
"//submodules/AttachmentUI:AttachmentUI",
|
"//submodules/AttachmentUI:AttachmentUI",
|
||||||
|
"//submodules/RadialStatusNode:RadialStatusNode",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -7,6 +7,7 @@ import SwiftSignalKit
|
|||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import CheckNode
|
import CheckNode
|
||||||
import PhotoResources
|
import PhotoResources
|
||||||
|
import RadialStatusNode
|
||||||
|
|
||||||
final class WebSearchItem: GridItem {
|
final class WebSearchItem: GridItem {
|
||||||
var section: GridSection?
|
var section: GridSection?
|
||||||
@ -44,6 +45,7 @@ final class WebSearchItemNode: GridItemNode {
|
|||||||
private let imageNodeBackground: ASDisplayNode
|
private let imageNodeBackground: ASDisplayNode
|
||||||
private let imageNode: TransformImageNode
|
private let imageNode: TransformImageNode
|
||||||
private var checkNode: CheckNode?
|
private var checkNode: CheckNode?
|
||||||
|
private var statusNode: RadialStatusNode?
|
||||||
|
|
||||||
private(set) var item: WebSearchItem?
|
private(set) var item: WebSearchItem?
|
||||||
private var currentDimensions: CGSize?
|
private var currentDimensions: CGSize?
|
||||||
@ -81,6 +83,32 @@ final class WebSearchItemNode: GridItemNode {
|
|||||||
self.imageNode.view.addGestureRecognizer(recognizer)
|
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) {
|
func setup(item: WebSearchItem, synchronousLoad: Bool) {
|
||||||
if self.item !== item {
|
if self.item !== item {
|
||||||
var updateImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>?
|
var updateImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user