Various fixes

This commit is contained in:
Ilya Laktyushin 2023-09-01 03:33:28 +04:00
parent 4b5ccefbc8
commit 46f9dd3af2
11 changed files with 239 additions and 49 deletions

View File

@ -63,7 +63,7 @@ public enum LegacyICloudFilePickerMode {
} }
} }
public func legacyICloudFilePicker(theme: PresentationTheme, mode: LegacyICloudFilePickerMode = .default, documentTypes: [String] = ["public.item"], forceDarkTheme: Bool = false, completion: @escaping ([URL]) -> Void) -> ViewController { public func legacyICloudFilePicker(theme: PresentationTheme, mode: LegacyICloudFilePickerMode = .default, documentTypes: [String] = ["public.item"], forceDarkTheme: Bool = false, dismissed: @escaping () -> Void = {}, completion: @escaping ([URL]) -> Void) -> ViewController {
var dismissImpl: (() -> Void)? var dismissImpl: (() -> Void)?
let legacyController = LegacyICloudFileController(presentation: .modal(animateIn: true), theme: theme, completion: { urls in let legacyController = LegacyICloudFileController(presentation: .modal(animateIn: true), theme: theme, completion: { urls in
dismissImpl?() dismissImpl?()
@ -96,6 +96,7 @@ public func legacyICloudFilePicker(theme: PresentationTheme, mode: LegacyICloudF
if let legacyController = legacyController { if let legacyController = legacyController {
legacyController.dismiss() legacyController.dismiss()
} }
dismissed()
} }
legacyController.bind(controller: UIViewController()) legacyController.bind(controller: UIViewController())
return legacyController return legacyController

View File

@ -412,6 +412,7 @@ private final class LocationPickerContext: AttachmentMediaPickerContext {
public func storyLocationPickerController( public func storyLocationPickerController(
context: AccountContext, context: AccountContext,
location: CLLocationCoordinate2D?, location: CLLocationCoordinate2D?,
dismissed: @escaping () -> Void,
completion: @escaping (TelegramMediaMap, Int64?, String?, String?, String?) -> Void completion: @escaping (TelegramMediaMap, Int64?, String?, String?, String?) -> Void
) -> ViewController { ) -> ViewController {
let presentationData = context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkColorPresentationTheme) let presentationData = context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkColorPresentationTheme)
@ -427,5 +428,8 @@ public func storyLocationPickerController(
} }
controller.navigationPresentation = .flatModal controller.navigationPresentation = .flatModal
controller.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait) controller.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
controller.didDismiss = {
dismissed()
}
return controller return controller
} }

View File

@ -0,0 +1,20 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "ContextReferenceButtonComponent",
module_name = "ContextReferenceButtonComponent",
srcs = glob([
"Sources/**/*.swift",
]),
copts = [
"-warnings-as-errors",
],
deps = [
"//submodules/Display",
"//submodules/ComponentFlow",
"//submodules/ContextUI",
],
visibility = [
"//visibility:public",
],
)

View File

@ -0,0 +1,123 @@
import Foundation
import UIKit
import Display
import ComponentFlow
public final class ContextReferenceButtonComponent: Component {
let content: AnyComponent<Empty>
let tag: AnyObject?
let minSize: CGSize?
let action: (UIView, ContextGesture?) -> Void
public init(
content: AnyComponent<Empty>,
tag: AnyObject? = nil,
minSize: CGSize?,
action: @escaping (UIView, ContextGesture?) -> Void
) {
self.content = content
self.tag = tag
self.minSize = minSize
self.action = action
}
public static func ==(lhs: ContextReferenceButtonComponent, rhs: ContextReferenceButtonComponent) -> Bool {
if lhs.content != rhs.content {
return false
}
if lhs.tag !== rhs.tag {
return false
}
if lhs.minSize != rhs.minSize {
return false
}
return true
}
public final class View: UIView, ComponentTaggedView {
let buttonView: HighlightableButtonNode
let sourceView: ContextControllerSourceNode
let contextContentView: ContextReferenceContentNode
private let componentView: ComponentView<Empty>
private var component: ContextReferenceButtonComponent?
public func matches(tag: Any) -> Bool {
if let component = self.component, let componentTag = component.tag {
let tag = tag as AnyObject
if componentTag === tag {
return true
}
}
return false
}
public init() {
self.componentView = ComponentView()
self.buttonView = HighlightableButtonNode()
self.sourceView = ContextControllerSourceNode()
self.contextContentView = ContextReferenceContentNode()
super.init(frame: CGRect())
self.addSubview(self.buttonView.view)
self.buttonView.addSubnode(self.sourceView)
self.sourceView.addSubnode(self.contextContentView)
self.sourceView.activated = { [weak self] gesture, _ in
if let self, let component = self.component {
component.action(self, gesture)
}
}
self.buttonView.addTarget(self, action: #selector(self.pressed), forControlEvents: .touchUpInside)
}
required init?(coder aDecoder: NSCoder) {
preconditionFailure()
}
@objc private func pressed() {
self.component?.action(self, nil)
}
public func update(component: ContextReferenceButtonComponent, availableSize: CGSize, transition: Transition) -> CGSize {
self.component = component
let componentSize = self.componentView.update(
transition: transition,
component: component.content,
environment: {},
containerSize: availableSize
)
var size = componentSize
if let minSize = component.minSize {
size.width = max(size.width, minSize.width)
size.height = max(size.height, minSize.height)
}
if let componentView = self.componentView.view {
componentView.isUserInteractionEnabled = false
if componentView.superview == nil {
self.contextContentView.view.addSubview(componentView)
}
transition.setFrame(view: componentView, frame: CGRect(origin: CGPoint(x: floor((size.width - componentSize.width) / 2.0), y: floor((size.height - componentSize.height) / 2.0)), size: componentSize))
}
transition.setFrame(view: self.buttonView.view, frame: CGRect(origin: .zero, size: size))
transition.setFrame(view: self.sourceView.view, frame: CGRect(origin: .zero, size: size))
transition.setFrame(view: self.contextContentView.view, frame: CGRect(origin: .zero, size: size))
return size
}
}
public func makeView() -> View {
return View()
}
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
return view.update(component: self, availableSize: availableSize, transition: transition)
}
}

View File

@ -181,9 +181,9 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView {
likeAction: nil, likeAction: nil,
likeOptionsAction: nil, likeOptionsAction: nil,
inputModeAction: nil, inputModeAction: nil,
timeoutAction: self.chatLocation.peerId?.namespace == Namespaces.Peer.CloudUser ? { [weak self] sourceView in timeoutAction: self.chatLocation.peerId?.namespace == Namespaces.Peer.CloudUser ? { [weak self] sourceView, gesture in
if let self { if let self {
self.presentTimeoutSetup(sourceView: sourceView) self.presentTimeoutSetup(sourceView: sourceView, gesture: gesture)
} }
} : nil, } : nil,
forwardAction: nil, forwardAction: nil,
@ -235,7 +235,7 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView {
return inputPanelSize.height - 8.0 return inputPanelSize.height - 8.0
} }
private func presentTimeoutSetup(sourceView: UIView) { private func presentTimeoutSetup(sourceView: UIView, gesture: ContextGesture?) {
self.hapticFeedback.impact(.light) self.hapticFeedback.impact(.light)
var items: [ContextMenuItem] = [] var items: [ContextMenuItem] = []
@ -284,7 +284,7 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView {
updateTimeout(nil) updateTimeout(nil)
}))) })))
let contextController = ContextController(presentationData: presentationData, source: .reference(HeaderContextReferenceContentSource(sourceView: sourceView)), items: .single(ContextController.Items(content: .list(items))), gesture: nil) let contextController = ContextController(presentationData: presentationData, source: .reference(HeaderContextReferenceContentSource(sourceView: sourceView)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
self.present(contextController) self.present(contextController)
} }

View File

@ -1117,7 +1117,7 @@ final class MediaEditorScreenComponent: Component {
} }
} }
}, },
timeoutAction: isEditingStory ? nil : { [weak self] view in timeoutAction: isEditingStory ? nil : { [weak self] view, gesture in
guard let self, let controller = self.environment?.controller() as? MediaEditorScreen else { guard let self, let controller = self.environment?.controller() as? MediaEditorScreen else {
return return
} }
@ -1130,7 +1130,7 @@ final class MediaEditorScreenComponent: Component {
} else { } else {
hasPremium = false hasPremium = false
} }
controller?.presentTimeoutSetup(sourceView: view, hasPremium: hasPremium) controller?.presentTimeoutSetup(sourceView: view, gesture: gesture, hasPremium: hasPremium)
}) })
}, },
forwardAction: nil, forwardAction: nil,
@ -2972,7 +2972,15 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
location = draft.location location = draft.location
} }
} }
let locationController = storyLocationPickerController(context: self.context, location: location, completion: { [weak self] location, queryId, resultId, address, countryCode in let locationController = storyLocationPickerController(
context: self.context,
location: location,
dismissed: { [weak self] in
if let self {
self.mediaEditor?.play()
}
},
completion: { [weak self] location, queryId, resultId, address, countryCode in
if let self { if let self {
let emojiFile: Signal<TelegramMediaFile?, NoError> let emojiFile: Signal<TelegramMediaFile?, NoError>
if let countryCode { if let countryCode {
@ -3050,7 +3058,13 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
func presentAudioPicker() { func presentAudioPicker() {
self.controller?.present(legacyICloudFilePicker(theme: self.presentationData.theme, mode: .import, documentTypes: ["public.mp3"], forceDarkTheme: true, completion: { [weak self] urls in self.controller?.present(legacyICloudFilePicker(theme: self.presentationData.theme, mode: .import, documentTypes: ["public.mp3"], forceDarkTheme: true, dismissed: { [weak self] in
if let self {
Queue.mainQueue().after(0.1) {
self.mediaEditor?.play()
}
}
}, completion: { [weak self] urls in
guard let self, let mediaEditor = self.mediaEditor, !urls.isEmpty, let url = urls.first else { guard let self, let mediaEditor = self.mediaEditor, !urls.isEmpty, let url = urls.first else {
return return
} }
@ -3075,10 +3089,6 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
self.requestUpdate(transition: .easeInOut(duration: 0.2)) self.requestUpdate(transition: .easeInOut(duration: 0.2))
Queue.mainQueue().after(0.1) {
self.mediaEditor?.play()
}
}), in: .window(.root)) }), in: .window(.root))
} }
@ -3096,7 +3106,13 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
action: { [weak self] f in action: { [weak self] f in
f.dismissWithResult(.default) f.dismissWithResult(.default)
if let self { if let self {
self.mediaEditor?.setAudioTrack(nil) if let mediaEditor = self.mediaEditor {
mediaEditor.setAudioTrack(nil)
if !mediaEditor.sourceIsVideo && !mediaEditor.isPlaying {
mediaEditor.play()
}
}
self.requestUpdate(transition: .easeInOut(duration: 0.25)) self.requestUpdate(transition: .easeInOut(duration: 0.25))
} }
} }
@ -3887,7 +3903,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
}) })
} }
func presentTimeoutSetup(sourceView: UIView, hasPremium: Bool) { func presentTimeoutSetup(sourceView: UIView, gesture: ContextGesture?, hasPremium: Bool) {
self.hapticFeedback.impact(.light) self.hapticFeedback.impact(.light)
var items: [ContextMenuItem] = [] var items: [ContextMenuItem] = []
@ -3908,7 +3924,6 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkPresentationTheme) let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkPresentationTheme)
let title = presentationData.strings.Story_Editor_ExpirationText let title = presentationData.strings.Story_Editor_ExpirationText
let currentValue = self.state.privacy.timeout let currentValue = self.state.privacy.timeout
let currentArchived = self.state.privacy.pin
let emptyAction: ((ContextMenuActionItem.Action) -> Void)? = nil let emptyAction: ((ContextMenuActionItem.Action) -> Void)? = nil
items.append(.action(ContextMenuActionItem(text: title, textLayout: .multiline, textFont: .small, icon: { _ in return nil }, action: emptyAction))) items.append(.action(ContextMenuActionItem(text: title, textLayout: .multiline, textFont: .small, icon: { _ in return nil }, action: emptyAction)))
@ -3944,7 +3959,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
}))) })))
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Story_Editor_ExpirationValue(24), icon: { theme in items.append(.action(ContextMenuActionItem(text: presentationData.strings.Story_Editor_ExpirationValue(24), icon: { theme in
return currentValue == 86400 && !currentArchived ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil return currentValue == 86400 ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
}, action: { _, a in }, action: { _, a in
a(.default) a(.default)
@ -3966,7 +3981,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
}))) })))
let contextController = ContextController(presentationData: presentationData, source: .reference(HeaderContextReferenceContentSource(controller: self, sourceView: sourceView)), items: .single(ContextController.Items(content: .list(items))), gesture: nil) let contextController = ContextController(presentationData: presentationData, source: .reference(HeaderContextReferenceContentSource(controller: self, sourceView: sourceView)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
self.present(contextController, in: .window(.root)) self.present(contextController, in: .window(.root))
} }

View File

@ -37,6 +37,8 @@ swift_library(
"//submodules/AnimatedCountLabelNode", "//submodules/AnimatedCountLabelNode",
"//submodules/TelegramUI/Components/MessageInputActionButtonComponent", "//submodules/TelegramUI/Components/MessageInputActionButtonComponent",
"//submodules/SearchPeerMembers", "//submodules/SearchPeerMembers",
"//submodules/ContextUI",
"//submodules/TelegramUI/Components/ContextReferenceButtonComponent",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -18,6 +18,9 @@ import AudioToolbox
import AnimatedTextComponent import AnimatedTextComponent
import AnimatedCountLabelNode import AnimatedCountLabelNode
import MessageInputActionButtonComponent import MessageInputActionButtonComponent
import ContextReferenceButtonComponent
private let timeoutButtonTag = GenericComponentViewTag()
public final class MessageInputPanelComponent: Component { public final class MessageInputPanelComponent: Component {
public struct ContextQueryTypes: OptionSet { public struct ContextQueryTypes: OptionSet {
@ -120,7 +123,7 @@ public final class MessageInputPanelComponent: Component {
public let likeAction: (() -> Void)? public let likeAction: (() -> Void)?
public let likeOptionsAction: ((UIView, ContextGesture?) -> Void)? public let likeOptionsAction: ((UIView, ContextGesture?) -> Void)?
public let inputModeAction: (() -> Void)? public let inputModeAction: (() -> Void)?
public let timeoutAction: ((UIView) -> Void)? public let timeoutAction: ((UIView, ContextGesture?) -> Void)?
public let forwardAction: (() -> Void)? public let forwardAction: (() -> Void)?
public let moreAction: ((UIView, ContextGesture?) -> Void)? public let moreAction: ((UIView, ContextGesture?) -> Void)?
public let presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)? public let presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)?
@ -172,7 +175,7 @@ public final class MessageInputPanelComponent: Component {
likeAction: (() -> Void)?, likeAction: (() -> Void)?,
likeOptionsAction: ((UIView, ContextGesture?) -> Void)?, likeOptionsAction: ((UIView, ContextGesture?) -> Void)?,
inputModeAction: (() -> Void)?, inputModeAction: (() -> Void)?,
timeoutAction: ((UIView) -> Void)?, timeoutAction: ((UIView, ContextGesture?) -> Void)?,
forwardAction: (() -> Void)?, forwardAction: (() -> Void)?,
moreAction: ((UIView, ContextGesture?) -> Void)?, moreAction: ((UIView, ContextGesture?) -> Void)?,
presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)?, presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)?,
@ -1458,7 +1461,7 @@ public final class MessageInputPanelComponent: Component {
if let timeoutAction = component.timeoutAction, let timeoutValue = component.timeoutValue { if let timeoutAction = component.timeoutAction, let timeoutValue = component.timeoutValue {
let timeoutButtonSize = self.timeoutButton.update( let timeoutButtonSize = self.timeoutButton.update(
transition: transition, transition: transition,
component: AnyComponent(Button( component: AnyComponent(ContextReferenceButtonComponent(
content: AnyComponent( content: AnyComponent(
TimeoutContentComponent( TimeoutContentComponent(
color: .white, color: .white,
@ -1467,13 +1470,12 @@ public final class MessageInputPanelComponent: Component {
value: timeoutValue value: timeoutValue
) )
), ),
action: { [weak self] in tag: timeoutButtonTag,
guard let self, let timeoutButtonView = self.timeoutButton.view else { minSize: CGSize(width: 32.0, height: 32.0),
return action: { view, gesture in
} timeoutAction(view, gesture)
timeoutAction(timeoutButtonView)
} }
).minSize(CGSize(width: 32.0, height: 32.0))), )),
environment: {}, environment: {},
containerSize: CGSize(width: 32.0, height: 32.0) containerSize: CGSize(width: 32.0, height: 32.0)
) )

View File

@ -78,13 +78,13 @@ public final class TimeoutContentComponent: Component {
if let textView = self.text.view, let snapshotView = textView.snapshotView(afterScreenUpdates: false) { if let textView = self.text.view, let snapshotView = textView.snapshotView(afterScreenUpdates: false) {
snapshotView.frame = textView.frame snapshotView.frame = textView.frame
self.addSubview(snapshotView) self.addSubview(snapshotView)
snapshotView.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: 3.0), duration: 0.2, removeOnCompletion: false, additive: true) snapshotView.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: -3.0), duration: 0.2, removeOnCompletion: false, additive: true)
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in
snapshotView.removeFromSuperview() snapshotView.removeFromSuperview()
}) })
textView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) textView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
textView.layer.animatePosition(from: CGPoint(x: 0.0, y: -3.0), to: .zero, duration: 0.2, additive: true) textView.layer.animatePosition(from: CGPoint(x: 0.0, y: 3.0), to: .zero, duration: 0.2, additive: true)
} }
} }
} }

View File

@ -503,6 +503,8 @@ final class ShareWithPeersScreenComponent: Component {
let translation = recognizer.translation(in: self) let translation = recognizer.translation(in: self)
self.dismissPanState = DismissPanState(translation: translation.y) self.dismissPanState = DismissPanState(translation: translation.y)
self.state?.updated(transition: .immediate) self.state?.updated(transition: .immediate)
self.updateModalOverlayTransition(transition: .immediate)
case .cancelled, .ended: case .cancelled, .ended:
if self.dismissPanState != nil { if self.dismissPanState != nil {
let translation = recognizer.translation(in: self) let translation = recognizer.translation(in: self)
@ -512,8 +514,13 @@ final class ShareWithPeersScreenComponent: Component {
if translation.y > 100.0 || velocity.y > 10.0 { if translation.y > 100.0 || velocity.y > 10.0 {
controller.requestDismiss() controller.requestDismiss()
Queue.mainQueue().justDispatch {
controller.updateModalStyleOverlayTransitionFactor(0.0, transition: .animated(duration: 0.3, curve: .spring))
}
} else { } else {
self.state?.updated(transition: Transition(animation: .curve(duration: 0.3, curve: .spring))) let transition = Transition(animation: .curve(duration: 0.3, curve: .spring))
self.state?.updated(transition: transition)
self.updateModalOverlayTransition(transition: transition)
} }
} }
default: default:
@ -782,7 +789,7 @@ final class ShareWithPeersScreenComponent: Component {
guard let self else { guard let self else {
return return
} }
let controller = ShareWithPeersScreen( let peersController = ShareWithPeersScreen(
context: component.context, context: component.context,
initialPrivacy: EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: []), initialPrivacy: EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: []),
stateContext: stateContext, stateContext: stateContext,
@ -797,10 +804,40 @@ final class ShareWithPeersScreenComponent: Component {
self.state?.updated(transition: .spring(duration: 0.4)) self.state?.updated(transition: .spring(duration: 0.4))
} }
) )
self.environment?.controller()?.push(controller) if let controller = self.environment?.controller() as? ShareWithPeersScreen {
controller.dismissAllTooltips()
controller.push(peersController)
}
}) })
} }
private func updateModalOverlayTransition(transition: Transition) {
guard let _ = self.component, let environment = self.environment, let itemLayout = self.itemLayout else {
return
}
var topOffset = -self.scrollView.bounds.minY + itemLayout.topInset
topOffset = max(0.0, topOffset)
if let dismissPanState = self.dismissPanState {
topOffset += dismissPanState.translation
}
let topOffsetDistance: CGFloat = min(200.0, floor(itemLayout.containerSize.height * 0.25))
var topOffsetFraction = topOffset / topOffsetDistance
topOffsetFraction = max(0.0, min(1.0, topOffsetFraction))
let transitionFactor: CGFloat = 1.0 - topOffsetFraction
if let controller = environment.controller() {
Queue.mainQueue().justDispatch {
var transition = transition
if controller.modalStyleOverlayTransitionFactor.isZero && transitionFactor > 0.0, transition.animation.isImmediate {
transition = .spring(duration: 0.4)
}
controller.updateModalStyleOverlayTransitionFactor(transitionFactor, transition: transition.containedViewLayoutTransition)
}
}
}
private func updateScrolling(transition: Transition) { private func updateScrolling(transition: Transition) {
guard let component = self.component, let environment = self.environment, let itemLayout = self.itemLayout else { guard let component = self.component, let environment = self.environment, let itemLayout = self.itemLayout else {
return return
@ -819,21 +856,7 @@ final class ShareWithPeersScreenComponent: Component {
var bottomAlpha: CGFloat = bottomDistance / bottomAlphaDistance var bottomAlpha: CGFloat = bottomDistance / bottomAlphaDistance
bottomAlpha = max(0.0, min(1.0, bottomAlpha)) bottomAlpha = max(0.0, min(1.0, bottomAlpha))
let topOffsetDistance: CGFloat = min(200.0, floor(itemLayout.containerSize.height * 0.25)) self.updateModalOverlayTransition(transition: transition)
self.topOffsetDistance = topOffsetDistance
var topOffsetFraction = topOffset / topOffsetDistance
topOffsetFraction = max(0.0, min(1.0, topOffsetFraction))
let transitionFactor: CGFloat = 1.0 - topOffsetFraction
if let controller = environment.controller() {
Queue.mainQueue().justDispatch {
var transition = transition
if controller.modalStyleOverlayTransitionFactor.isZero && transitionFactor > 0.0, transition.animation.isImmediate {
transition = .spring(duration: 0.4)
}
controller.updateModalStyleOverlayTransitionFactor(transitionFactor, transition: transition.containedViewLayoutTransition)
}
}
var visibleBounds = self.scrollView.bounds var visibleBounds = self.scrollView.bounds
visibleBounds.origin.y -= itemLayout.topInset visibleBounds.origin.y -= itemLayout.topInset
@ -1043,7 +1066,7 @@ final class ShareWithPeersScreenComponent: Component {
if isStories { if isStories {
let _ = self.presentSendAsPeer() let _ = self.presentSendAsPeer()
} else { } else {
self.hapticFeedback.tap() self.hapticFeedback.impact(.light)
self.environment?.controller()?.dismiss() self.environment?.controller()?.dismiss()
self.component?.peerCompletion(peer.id) self.component?.peerCompletion(peer.id)
} }

View File

@ -2045,7 +2045,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
if isSecretMedia { if isSecretMedia {
let remainingTime: Int32? let remainingTime: Int32?
if let (maybeBeginTime, timeout) = secretBeginTimeAndTimeout { if let (maybeBeginTime, timeout) = secretBeginTimeAndTimeout, Int32(timeout) != viewOnceTimeout {
if let beginTime = maybeBeginTime { if let beginTime = maybeBeginTime {
let elapsedTime = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 - beginTime let elapsedTime = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 - beginTime
remainingTime = Int32(max(0.0, timeout - elapsedTime)) remainingTime = Int32(max(0.0, timeout - elapsedTime))