mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-05 05:51:42 +00:00
Merge commit 'bc1598bb926aee4267a278857463f8ce8ac1dec9'
This commit is contained in:
commit
24260d3652
@ -102,7 +102,7 @@ final class CameraDeviceContext {
|
||||
return 30.0
|
||||
}
|
||||
switch DeviceModel.current {
|
||||
case .iPhone15ProMax, .iPhone14ProMax, .iPhone13ProMax, .iPhone16ProMax:
|
||||
case .iPhone15ProMax, .iPhone14ProMax, .iPhone13ProMax, .iPhone16ProMax, .iPhone17Pro, .iPhone17ProMax:
|
||||
return 60.0
|
||||
default:
|
||||
return 30.0
|
||||
|
||||
@ -132,7 +132,6 @@ final class ComposePollScreenComponent: Component {
|
||||
private var reactionSelectionControl: ComponentView<Empty>?
|
||||
|
||||
private var isUpdating: Bool = false
|
||||
private var ignoreScrolling: Bool = false
|
||||
private var previousHadInputHeight: Bool = false
|
||||
|
||||
private var component: ComposePollScreenComponent?
|
||||
@ -467,21 +466,6 @@ final class ComposePollScreenComponent: Component {
|
||||
self.endEditing(true)
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
if !self.ignoreScrolling {
|
||||
self.updateScrolling(transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateScrolling(transition: ComponentTransition) {
|
||||
let navigationAlphaDistance: CGFloat = 16.0
|
||||
let navigationAlpha: CGFloat = max(0.0, min(1.0, self.scrollView.contentOffset.y / navigationAlphaDistance))
|
||||
if let controller = self.environment?.controller(), let navigationBar = controller.navigationBar {
|
||||
transition.setAlpha(layer: navigationBar.backgroundNode.layer, alpha: navigationAlpha)
|
||||
transition.setAlpha(layer: navigationBar.stripeNode.layer, alpha: navigationAlpha)
|
||||
}
|
||||
}
|
||||
|
||||
func isPanGestureEnabled() -> Bool {
|
||||
if self.inputMediaNode != nil {
|
||||
return false
|
||||
@ -1627,7 +1611,6 @@ final class ComposePollScreenComponent: Component {
|
||||
}
|
||||
self.previousHadInputHeight = (inputHeight > 0.0)
|
||||
|
||||
self.ignoreScrolling = true
|
||||
let previousBounds = self.scrollView.bounds
|
||||
let contentSize = CGSize(width: availableSize.width, height: contentHeight)
|
||||
if self.scrollView.frame != CGRect(origin: CGPoint(), size: availableSize) {
|
||||
@ -1762,9 +1745,6 @@ final class ComposePollScreenComponent: Component {
|
||||
transition.animateBoundsOrigin(view: self.scrollView, from: CGPoint(x: 0.0, y: offsetY), to: CGPoint(), additive: true)
|
||||
}
|
||||
}
|
||||
self.ignoreScrolling = false
|
||||
|
||||
self.updateScrolling(transition: transition)
|
||||
|
||||
if isEditing {
|
||||
if let controller = environment.controller() as? ComposePollScreen {
|
||||
|
||||
@ -23,10 +23,12 @@ open class SwitchNode: ASDisplayNode {
|
||||
public var frameColor = UIColor(rgb: 0xe0e0e0) {
|
||||
didSet {
|
||||
if self.isNodeLoaded {
|
||||
if oldValue != self.frameColor {
|
||||
(self.view as! UISwitch).tintColor = self.frameColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public var handleColor = UIColor(rgb: 0xffffff) {
|
||||
didSet {
|
||||
if self.isNodeLoaded {
|
||||
@ -37,10 +39,12 @@ open class SwitchNode: ASDisplayNode {
|
||||
public var contentColor = UIColor(rgb: 0x42d451) {
|
||||
didSet {
|
||||
if self.isNodeLoaded {
|
||||
if oldValue != self.contentColor {
|
||||
(self.view as! UISwitch).onTintColor = self.contentColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var _isOn: Bool = false
|
||||
public var isOn: Bool {
|
||||
|
||||
@ -129,8 +129,17 @@ final class VideoAdComponent: Component {
|
||||
self.imageNode.setSignal(signal)
|
||||
}
|
||||
|
||||
let color = UIColor(rgb: 0x64d2ff)
|
||||
if self.adIcon == nil {
|
||||
self.adIcon = generateAdIcon(color: color, strings: component.strings)
|
||||
}
|
||||
|
||||
let leftInset: CGFloat = media != nil ? 51.0 : 16.0
|
||||
let rightInset: CGFloat = 60.0
|
||||
var titleRightInset: CGFloat = 0.0
|
||||
if let adIcon = self.adIcon {
|
||||
titleRightInset += adIcon.size.width + 16.0
|
||||
}
|
||||
|
||||
let titleSize = self.title.update(
|
||||
transition: .immediate,
|
||||
@ -138,7 +147,7 @@ final class VideoAdComponent: Component {
|
||||
MultilineTextComponent(text: .plain(NSAttributedString(string: titleString, font: Font.semibold(14.0), textColor: .white)))
|
||||
),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - leftInset - rightInset, height: availableSize.height)
|
||||
containerSize: CGSize(width: availableSize.width - leftInset - rightInset - titleRightInset, height: availableSize.height)
|
||||
)
|
||||
|
||||
let textColor = UIColor.white
|
||||
@ -194,11 +203,6 @@ final class VideoAdComponent: Component {
|
||||
textView.frame = textFrame
|
||||
}
|
||||
|
||||
let color = UIColor(rgb: 0x64d2ff)
|
||||
if self.adIcon == nil {
|
||||
self.adIcon = generateAdIcon(color: color, strings: component.strings)
|
||||
}
|
||||
|
||||
let buttonSize = self.button.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
|
||||
@ -85,7 +85,6 @@ final class ComposeTodoScreenComponent: Component {
|
||||
private let doneButton = ComponentView<Empty>()
|
||||
|
||||
private var isUpdating: Bool = false
|
||||
private var ignoreScrolling: Bool = false
|
||||
private var previousHadInputHeight: Bool = false
|
||||
|
||||
private var component: ComposeTodoScreenComponent?
|
||||
@ -381,25 +380,10 @@ final class ComposeTodoScreenComponent: Component {
|
||||
return true
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
if !self.ignoreScrolling {
|
||||
self.updateScrolling(transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
||||
self.endEditing(true)
|
||||
}
|
||||
|
||||
private func updateScrolling(transition: ComponentTransition) {
|
||||
let navigationAlphaDistance: CGFloat = 16.0
|
||||
let navigationAlpha: CGFloat = max(0.0, min(1.0, self.scrollView.contentOffset.y / navigationAlphaDistance))
|
||||
if let controller = self.environment?.controller(), let navigationBar = controller.navigationBar {
|
||||
transition.setAlpha(layer: navigationBar.backgroundNode.layer, alpha: navigationAlpha)
|
||||
transition.setAlpha(layer: navigationBar.stripeNode.layer, alpha: navigationAlpha)
|
||||
}
|
||||
}
|
||||
|
||||
func isPanGestureEnabled() -> Bool {
|
||||
if self.inputMediaNode != nil {
|
||||
return false
|
||||
@ -1511,7 +1495,6 @@ final class ComposeTodoScreenComponent: Component {
|
||||
}
|
||||
self.previousHadInputHeight = (inputHeight > 0.0)
|
||||
|
||||
self.ignoreScrolling = true
|
||||
let previousBounds = self.scrollView.bounds
|
||||
let contentSize = CGSize(width: availableSize.width, height: contentHeight)
|
||||
if self.scrollView.frame != CGRect(origin: CGPoint(), size: availableSize) {
|
||||
@ -1548,9 +1531,6 @@ final class ComposeTodoScreenComponent: Component {
|
||||
transition.animateBoundsOrigin(view: self.scrollView, from: CGPoint(x: 0.0, y: offsetY), to: CGPoint(), additive: true)
|
||||
}
|
||||
}
|
||||
self.ignoreScrolling = false
|
||||
|
||||
self.updateScrolling(transition: transition)
|
||||
|
||||
if isEditing {
|
||||
if let controller = environment.controller() as? ComposeTodoScreen {
|
||||
@ -1662,14 +1642,6 @@ final class ComposeTodoScreenComponent: Component {
|
||||
self.addSubview(doneButtonView)
|
||||
}
|
||||
transition.setFrame(view: doneButtonView, frame: doneButtonFrame)
|
||||
|
||||
if isValid {
|
||||
doneButtonView.layer.filters = []
|
||||
} else {
|
||||
if (doneButtonView.layer.filters ?? []).isEmpty, let monochrome = CALayer.monochrome() {
|
||||
doneButtonView.layer.filters = [monochrome]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let currentEditingTag = self.currentEditingTag, previousEditingTag !== currentEditingTag, self.currentInputMode != .keyboard {
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
#include <metal_stdlib>
|
||||
#include "EditorCommon.h"
|
||||
#include "EditorUtils.h"
|
||||
|
||||
using namespace metal;
|
||||
|
||||
kernel void morphologyMaximumFilter(texture2d<float, access::sample> inputTexture [[texture(0)]],
|
||||
texture2d<float, access::write> outputTexture [[texture(1)]],
|
||||
constant float& radius [[buffer(0)]],
|
||||
uint2 gid [[thread_position_in_grid]]) {
|
||||
uint2 size = uint2(inputTexture.get_width(), inputTexture.get_height());
|
||||
uint2 pos = gid;
|
||||
|
||||
float maxIntensity = 0.0;
|
||||
int kernelRadius = int(radius);
|
||||
|
||||
for (int y = -kernelRadius; y <= kernelRadius; ++y) {
|
||||
for (int x = -kernelRadius; x <= kernelRadius; ++x) {
|
||||
uint2 samplePos = pos + uint2(x, y);
|
||||
|
||||
if (samplePos.x >= 0 && samplePos.y >= 0 && samplePos.x < size.x && samplePos.y < size.y) {
|
||||
float intensity = inputTexture.read(samplePos).a;
|
||||
if (intensity > maxIntensity) {
|
||||
maxIntensity = intensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
outputTexture.write(maxIntensity, gid);
|
||||
}
|
||||
|
||||
fragment half4 stickerOutlineFragmentShader(RasterizerData in [[stage_in]],
|
||||
texture2d<half, access::sample> sourceTexture [[texture(0)]],
|
||||
texture2d<half, access::sample> maskTexture [[texture(1)]]
|
||||
)
|
||||
{
|
||||
constexpr sampler colorSampler(min_filter::linear, mag_filter::linear, address::clamp_to_zero);
|
||||
constexpr sampler maskSampler(min_filter::linear, mag_filter::linear, address::clamp_to_zero);
|
||||
|
||||
half4 color = sourceTexture.sample(colorSampler, in.texCoord);
|
||||
half intensity = maskTexture.sample(maskSampler, in.texCoord).r;
|
||||
|
||||
half4 result = half4(intensity, intensity, intensity, max(color.a, intensity));
|
||||
result.r = mix(result.r, color.r, color.a);
|
||||
result.g = mix(result.g, color.g, color.a);
|
||||
result.b = mix(result.b, color.b, color.a);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -85,6 +85,7 @@ public final class SearchInputPanelComponent: Component {
|
||||
|
||||
public final class View: UIView, UITextFieldDelegate {
|
||||
private let edgeEffectView: EdgeEffectView
|
||||
private let containerView: GlassBackgroundContainerView
|
||||
private let backgroundView: GlassBackgroundView
|
||||
|
||||
private let icon = ComponentView<Empty>()
|
||||
@ -106,13 +107,15 @@ public final class SearchInputPanelComponent: Component {
|
||||
override init(frame: CGRect) {
|
||||
self.edgeEffectView = EdgeEffectView()
|
||||
|
||||
self.containerView = GlassBackgroundContainerView()
|
||||
self.backgroundView = GlassBackgroundView()
|
||||
self.textField = TextField()
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.addSubview(self.edgeEffectView)
|
||||
self.addSubview(self.backgroundView)
|
||||
self.addSubview(self.containerView)
|
||||
self.containerView.contentView.addSubview(self.backgroundView)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
@ -196,7 +199,7 @@ public final class SearchInputPanelComponent: Component {
|
||||
let fieldFrame = CGRect(origin: CGPoint(x: edgeInsets.left, y: edgeInsets.top), size: CGSize(width: availableSize.width - edgeInsets.left - edgeInsets.right - fieldHeight - buttonSpacing, height: fieldHeight))
|
||||
let cancelButtonFrame = CGRect(origin: CGPoint(x: edgeInsets.left + fieldFrame.width + buttonSpacing, y: edgeInsets.top), size: CGSize(width: fieldHeight, height: fieldHeight))
|
||||
|
||||
self.backgroundView.update(size: fieldFrame.size, cornerRadius: fieldFrame.height * 0.5, isDark: component.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: backgroundColor), transition: transition)
|
||||
self.backgroundView.update(size: fieldFrame.size, cornerRadius: fieldFrame.height * 0.5, isDark: component.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: backgroundColor), isInteractive: true, transition: transition)
|
||||
transition.setFrame(view: self.backgroundView, frame: fieldFrame)
|
||||
|
||||
let fieldSideInset: CGFloat = 41.0
|
||||
@ -299,7 +302,7 @@ public final class SearchInputPanelComponent: Component {
|
||||
)
|
||||
if let cancelButtonView = self.cancelButton.view {
|
||||
if cancelButtonView.superview == nil {
|
||||
self.addSubview(cancelButtonView)
|
||||
self.containerView.contentView.addSubview(cancelButtonView)
|
||||
}
|
||||
transition.setFrame(view: cancelButtonView, frame: cancelButtonFrame)
|
||||
}
|
||||
@ -313,6 +316,9 @@ public final class SearchInputPanelComponent: Component {
|
||||
transition.setFrame(view: self.edgeEffectView, frame: edgeEffectFrame)
|
||||
self.edgeEffectView.update(content: edgeColor, blur: true, rect: edgeEffectFrame, edge: .bottom, edgeSize: edgeEffectFrame.height, transition: transition)
|
||||
|
||||
transition.setFrame(view: self.containerView, frame: CGRect(origin: .zero, size: size))
|
||||
self.containerView.update(size: size, isDark: component.theme.overallDarkAppearance, transition: transition)
|
||||
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,16 @@ func openWebAppImpl(
|
||||
presentationData = context.sharedContext.currentPresentationData.with({ $0 })
|
||||
}
|
||||
|
||||
var skipTermsOfService = skipTermsOfService
|
||||
if let whiteListedBots = context.currentAppConfiguration.with({ $0 }).data?["whitelisted_bots"] as? [Double] {
|
||||
let botId = botPeer.id.id._internalGetInt64Value()
|
||||
for bot in whiteListedBots {
|
||||
if Int64(bot) == botId {
|
||||
skipTermsOfService = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let botName: String
|
||||
let botAddress: String
|
||||
let botVerified: Bool
|
||||
@ -530,6 +540,16 @@ public extension ChatControllerImpl {
|
||||
peerId = botPeer.id
|
||||
}
|
||||
|
||||
var skipTermsOfService = false
|
||||
if let whiteListedBots = context.currentAppConfiguration.with({ $0 }).data?["whitelisted_bots"] as? [Double] {
|
||||
let botId = botPeer.id.id._internalGetInt64Value()
|
||||
for bot in whiteListedBots {
|
||||
if Int64(bot) == botId {
|
||||
skipTermsOfService = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chatController?.attachmentController?.dismiss(animated: true, completion: nil)
|
||||
|
||||
let updatedPresentationData = chatController?.updatedPresentationData
|
||||
@ -656,6 +676,9 @@ public extension ChatControllerImpl {
|
||||
} else {
|
||||
openBotApp(false, false, appSettings)
|
||||
}
|
||||
} else {
|
||||
if skipTermsOfService {
|
||||
openBotApp(true, false, appSettings)
|
||||
} else {
|
||||
let controller = webAppLaunchConfirmationController(context: context, updatedPresentationData: updatedPresentationData, peer: botPeer, requestWriteAccess: botApp.flags.contains(.notActivated) && botApp.flags.contains(.requiresWriteAccess), completion: { allowWrite in
|
||||
let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: context.sharedContext.accountManager, peerId: botPeer.id).startStandalone()
|
||||
@ -669,6 +692,7 @@ public extension ChatControllerImpl {
|
||||
})
|
||||
parentController?.present(controller, in: .window(.root))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
openBotApp(false, false, appSettings)
|
||||
}
|
||||
|
||||
@ -1378,14 +1378,14 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
let _ = (self.context.engine.messages.attachMenuBots()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] attachMenuBots in
|
||||
guard let self else {
|
||||
guard let self, let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
let currentTimestamp = CACurrentMediaTime()
|
||||
var fillData = false
|
||||
|
||||
let attachMenuBot = attachMenuBots.first(where: { $0.peer.id == botId && !$0.flags.contains(.notActivated) })
|
||||
if isAttachMenu || attachMenuBot != nil {
|
||||
if isAttachMenu || attachMenuBot != nil || controller.isWhiteListedBot {
|
||||
if let lastTouchTimestamp = self.webView?.lastTouchTimestamp, currentTimestamp < lastTouchTimestamp + 10.0 {
|
||||
self.webView?.lastTouchTimestamp = nil
|
||||
fillData = true
|
||||
@ -3492,6 +3492,18 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
return false
|
||||
}
|
||||
|
||||
private var isWhiteListedBot: Bool {
|
||||
if let whiteListedBots = self.context.currentAppConfiguration.with({ $0 }).data?["whitelisted_bots"] as? [Double] {
|
||||
let botId = self.botId.id._internalGetInt64Value()
|
||||
for bot in whiteListedBots {
|
||||
if Int64(bot) == botId {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func beforeMaximize(navigationController: NavigationController, completion: @escaping () -> Void) {
|
||||
switch self.source {
|
||||
case .generic, .settings:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user