mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
72ed83c99a
40 changed files with 411 additions and 161 deletions
|
|
@ -1980,7 +1980,15 @@ private final class NotificationServiceHandler {
|
|||
}
|
||||
if enableInlineEmoji, let textEntitiesAttribute = message.textEntitiesAttribute, let author = message.author {
|
||||
let authorTitle = author.debugDisplayTitle
|
||||
let messagePrefix = "\(authorTitle): "
|
||||
var needsPrefix = false
|
||||
if message.id.peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||
needsPrefix = true
|
||||
} else if let channel = message.peers[message.id.peerId] as? TelegramChannel {
|
||||
if case .group = channel.info {
|
||||
needsPrefix = true
|
||||
}
|
||||
}
|
||||
let messagePrefix = needsPrefix ? "\(authorTitle): " : ""
|
||||
let messagePrefixLength = (messagePrefix as NSString).length
|
||||
for entity in textEntitiesAttribute.entities {
|
||||
if case let .CustomEmoji(_, fileId) = entity.type {
|
||||
|
|
|
|||
|
|
@ -203,56 +203,87 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, U
|
|||
/// Collect all accessibliity elements for a given view and view node
|
||||
static void CollectAccessibilityElementsForView(UIView *view, NSMutableArray *elements)
|
||||
{
|
||||
ASDisplayNodeCAssertNotNil(elements, @"Should pass in a NSMutableArray");
|
||||
|
||||
ASDisplayNode *node = view.asyncdisplaykit_node;
|
||||
|
||||
static Class displayListViewClass = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
displayListViewClass = NSClassFromString(@"Display.ListView");
|
||||
});
|
||||
BOOL anySubNodeIsCollection = (nil != ASDisplayNodeFindFirstNode(node,
|
||||
^BOOL(ASDisplayNode *nodeToCheck) {
|
||||
ASDisplayNodeCAssertNotNil(elements, @"Should pass in a NSMutableArray");
|
||||
|
||||
ASDisplayNode *node = view.asyncdisplaykit_node;
|
||||
|
||||
static Class displayListViewClass = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
displayListViewClass = NSClassFromString(@"Display.ListView");
|
||||
});
|
||||
BOOL anySubNodeIsCollection = (nil != ASDisplayNodeFindFirstNode(node,
|
||||
^BOOL(ASDisplayNode *nodeToCheck) {
|
||||
if (displayListViewClass != nil && [nodeToCheck isKindOfClass:displayListViewClass]) {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
/*return ASDynamicCast(nodeToCheck, ASCollectionNode) != nil ||
|
||||
ASDynamicCast(nodeToCheck, ASTableNode) != nil;*/
|
||||
}));
|
||||
|
||||
if (node.isAccessibilityContainer && !anySubNodeIsCollection) {
|
||||
CollectAccessibilityElementsForContainer(node, view, elements);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle rasterize case
|
||||
if (node.rasterizesSubtree) {
|
||||
CollectUIAccessibilityElementsForNode(node, node, view, elements);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!node.isLayerBacked) {
|
||||
for (UIView *subview in node.view.subviews) {
|
||||
ASDisplayNode *subnode = subview.asyncdisplaykit_node;
|
||||
if (subnode) {
|
||||
if (subnode.isAccessibilityElement) {
|
||||
// An accessiblityElement can either be a UIView or a UIAccessibilityElement
|
||||
if (subnode.isLayerBacked) {
|
||||
// No view for layer backed nodes exist. It's necessary to create a UIAccessibilityElement that represents this node
|
||||
UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:subnode containerNode:node];
|
||||
[elements addObject:accessiblityElement];
|
||||
} else {
|
||||
// Accessiblity element is not layer backed just add the view as accessibility element
|
||||
[elements addObject:subnode.view];
|
||||
}
|
||||
} else if (subnode.isLayerBacked) {
|
||||
// Go down the hierarchy of the layer backed subnode and collect all of the UIAccessibilityElement
|
||||
CollectUIAccessibilityElementsForNode(subnode, node, view, elements);
|
||||
} else if ([subnode accessibilityElementCount] > 0) {
|
||||
// UIView is itself a UIAccessibilityContainer just add it
|
||||
[elements addObject:subnode.view];
|
||||
}
|
||||
} else {
|
||||
// Plain UIView without an associated ASDisplayNode
|
||||
if (subview.isAccessibilityElement) {
|
||||
[elements addObject:subview];
|
||||
} else if ([subview accessibilityElementCount] > 0) {
|
||||
[elements addObject:subview];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ASDisplayNode *subnode in node.subnodes) {
|
||||
if (subnode.isAccessibilityElement) {
|
||||
// An accessiblityElement can either be a UIView or a UIAccessibilityElement
|
||||
if (subnode.isLayerBacked) {
|
||||
// No view for layer backed nodes exist. It's necessary to create a UIAccessibilityElement that represents this node
|
||||
UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:subnode containerNode:node];
|
||||
[elements addObject:accessiblityElement];
|
||||
} else {
|
||||
// Accessiblity element is not layer backed just add the view as accessibility element
|
||||
[elements addObject:subnode.view];
|
||||
}
|
||||
} else if (subnode.isLayerBacked) {
|
||||
// Go down the hierarchy of the layer backed subnode and collect all of the UIAccessibilityElement
|
||||
CollectUIAccessibilityElementsForNode(subnode, node, view, elements);
|
||||
} else if ([subnode accessibilityElementCount] > 0) {
|
||||
// UIView is itself a UIAccessibilityContainer just add it
|
||||
[elements addObject:subnode.view];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
/*return ASDynamicCast(nodeToCheck, ASCollectionNode) != nil ||
|
||||
ASDynamicCast(nodeToCheck, ASTableNode) != nil;*/
|
||||
}));
|
||||
|
||||
if (node.isAccessibilityContainer && !anySubNodeIsCollection) {
|
||||
CollectAccessibilityElementsForContainer(node, view, elements);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle rasterize case
|
||||
if (node.rasterizesSubtree) {
|
||||
CollectUIAccessibilityElementsForNode(node, node, view, elements);
|
||||
return;
|
||||
}
|
||||
|
||||
for (ASDisplayNode *subnode in node.subnodes) {
|
||||
if (subnode.isAccessibilityElement) {
|
||||
|
||||
// An accessiblityElement can either be a UIView or a UIAccessibilityElement
|
||||
if (subnode.isLayerBacked) {
|
||||
// No view for layer backed nodes exist. It's necessary to create a UIAccessibilityElement that represents this node
|
||||
UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:subnode containerNode:node];
|
||||
[elements addObject:accessiblityElement];
|
||||
} else {
|
||||
// Accessiblity element is not layer backed just add the view as accessibility element
|
||||
[elements addObject:subnode.view];
|
||||
}
|
||||
} else if (subnode.isLayerBacked) {
|
||||
// Go down the hierarchy of the layer backed subnode and collect all of the UIAccessibilityElement
|
||||
CollectUIAccessibilityElementsForNode(subnode, node, view, elements);
|
||||
} else if ([subnode accessibilityElementCount] > 0) {
|
||||
// UIView is itself a UIAccessibilityContainer just add it
|
||||
[elements addObject:subnode.view];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@interface _ASDisplayView () {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ public final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDeco
|
|||
|
||||
private(set) var isAnimating = false
|
||||
|
||||
public var hitTestSize: CGFloat?
|
||||
|
||||
public typealias BlobRange = (min: CGFloat, max: CGFloat)
|
||||
|
||||
public init(
|
||||
|
|
@ -224,6 +226,15 @@ public final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDeco
|
|||
|
||||
self.updateBlobsState()
|
||||
}
|
||||
|
||||
override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
if let hitTestSize = self.hitTestSize {
|
||||
if !CGSize(width: hitTestSize, height: hitTestSize).centered(in: self.bounds).contains(point) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return super.hitTest(point, with: event)
|
||||
}
|
||||
}
|
||||
|
||||
final class BlobNode: ASDisplayNode {
|
||||
|
|
|
|||
|
|
@ -896,7 +896,7 @@ public final class ReactionButtonAsyncNode: ContextControllerSourceView {
|
|||
)
|
||||
}
|
||||
counterLayout = counterValue
|
||||
if spec.component.count != 0 {
|
||||
if spec.component.count != 0 || hasTitle {
|
||||
size.width += spacing + counterValue.size.width
|
||||
} else {
|
||||
size.width -= 1.0
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||
case experimentalCompatibility(Bool)
|
||||
case enableDebugDataDisplay(Bool)
|
||||
case fakeGlass(Bool)
|
||||
case forceClearGlass(Bool)
|
||||
case browserExperiment(Bool)
|
||||
case allForumsHaveTabs(Bool)
|
||||
case enableReactionOverrides(Bool)
|
||||
|
|
@ -135,7 +136,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||
return DebugControllerSection.web.rawValue
|
||||
case .keepChatNavigationStack, .skipReadHistory, .alwaysDisplayTyping, .debugRatingLayout, .crashOnSlowQueries, .crashOnMemoryPressure:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .clearTips, .resetNotifications, .crash, .fillLocalSavedMessageCache, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .resetTagHoles, .reindexUnread, .resetCacheIndex, .reindexCache, .resetBiometricsData, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .compressedEmojiCache, .storiesJpegExperiment, .checkSerializedData, .enableQuickReactionSwitch, .experimentalCompatibility, .enableDebugDataDisplay, .fakeGlass, .browserExperiment, .allForumsHaveTabs, .enableReactionOverrides, .restorePurchases, .disableReloginTokens, .liveStreamV2, .experimentalCallMute, .playerV2, .devRequests, .enableUpdates, .pwa, .enableLocalTranslation:
|
||||
case .clearTips, .resetNotifications, .crash, .fillLocalSavedMessageCache, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .resetTagHoles, .reindexUnread, .resetCacheIndex, .reindexCache, .resetBiometricsData, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .compressedEmojiCache, .storiesJpegExperiment, .checkSerializedData, .enableQuickReactionSwitch, .experimentalCompatibility, .enableDebugDataDisplay, .fakeGlass, .forceClearGlass, .browserExperiment, .allForumsHaveTabs, .enableReactionOverrides, .restorePurchases, .disableReloginTokens, .liveStreamV2, .experimentalCallMute, .playerV2, .devRequests, .enableUpdates, .pwa, .enableLocalTranslation:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .logTranslationRecognition, .resetTranslationStates:
|
||||
return DebugControllerSection.translation.rawValue
|
||||
|
|
@ -228,24 +229,26 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||
return 38
|
||||
case .fakeGlass:
|
||||
return 39
|
||||
case .browserExperiment:
|
||||
case .forceClearGlass:
|
||||
return 40
|
||||
case .allForumsHaveTabs:
|
||||
case .browserExperiment:
|
||||
return 41
|
||||
case .enableReactionOverrides:
|
||||
case .allForumsHaveTabs:
|
||||
return 42
|
||||
case .restorePurchases:
|
||||
case .enableReactionOverrides:
|
||||
return 43
|
||||
case .logTranslationRecognition:
|
||||
case .restorePurchases:
|
||||
return 44
|
||||
case .resetTranslationStates:
|
||||
case .logTranslationRecognition:
|
||||
return 45
|
||||
case .compressedEmojiCache:
|
||||
case .resetTranslationStates:
|
||||
return 46
|
||||
case .storiesJpegExperiment:
|
||||
case .compressedEmojiCache:
|
||||
return 47
|
||||
case .disableReloginTokens:
|
||||
case .storiesJpegExperiment:
|
||||
return 48
|
||||
case .disableReloginTokens:
|
||||
return 49
|
||||
case .checkSerializedData:
|
||||
return 50
|
||||
case .enableQuickReactionSwitch:
|
||||
|
|
@ -1279,6 +1282,16 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||
})
|
||||
}).start()
|
||||
})
|
||||
case let .forceClearGlass(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, systemStyle: .glass, title: "Force clear glass", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
||||
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
|
||||
var settings = settings?.get(ExperimentalUISettings.self) ?? ExperimentalUISettings.defaultSettings
|
||||
settings.forceClearGlass = value
|
||||
return PreferencesEntry(settings)
|
||||
})
|
||||
}).start()
|
||||
})
|
||||
case let .browserExperiment(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, systemStyle: .glass, title: "Inline UI", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
||||
|
|
@ -1555,6 +1568,7 @@ private func debugControllerEntries(context: AccountContext?, sharedContext: Sha
|
|||
entries.append(.experimentalCompatibility(experimentalSettings.experimentalCompatibility))
|
||||
entries.append(.enableDebugDataDisplay(experimentalSettings.enableDebugDataDisplay))
|
||||
entries.append(.fakeGlass(experimentalSettings.fakeGlass))
|
||||
entries.append(.forceClearGlass(experimentalSettings.forceClearGlass))
|
||||
#if DEBUG
|
||||
entries.append(.browserExperiment(experimentalSettings.browserExperiment))
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1340,13 +1340,14 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, ASScroll
|
|||
isOpen: false
|
||||
))),
|
||||
action: { [weak self] in
|
||||
guard let self, let buttonPanelView = self.buttonPanel.view as? GlassControlPanelComponent.View, let centerItemView = buttonPanelView.centerItemView else {
|
||||
guard let self, let buttonPanelView = self.buttonPanel.view as? GlassControlPanelComponent.View else {
|
||||
return
|
||||
}
|
||||
guard let itemView = centerItemView.itemView(id: AnyHashable("settings")) else {
|
||||
return
|
||||
if let centerItemView = buttonPanelView.centerItemView, let itemView = centerItemView.itemView(id: AnyHashable("settings")) {
|
||||
self.settingsButtonPressed(sourceView: itemView)
|
||||
} else if let rightItemView = buttonPanelView.rightItemView, let itemView = rightItemView.itemView(id: AnyHashable("settings")) {
|
||||
self.settingsButtonPressed(sourceView: itemView)
|
||||
}
|
||||
self.settingsButtonPressed(sourceView: itemView)
|
||||
}
|
||||
))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1469,8 +1469,14 @@ public class GalleryController: ViewController, StandalonePresentableController,
|
|||
}
|
||||
|
||||
self.galleryNode.controlsVisibilityChanged = { [weak self] visible in
|
||||
self?.prefersOnScreenNavigationHidden = !visible
|
||||
self?.galleryNode.pager.centralItemNode()?.controlsVisibilityUpdated(isVisible: visible)
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.prefersOnScreenNavigationHidden = !visible
|
||||
|
||||
self.galleryNode.pager.forEachItemNode { itemNode in
|
||||
itemNode.controlsVisibilityUpdated(isVisible: visible)
|
||||
}
|
||||
}
|
||||
|
||||
self.galleryNode.updateOrientation = { [weak self] orientation in
|
||||
|
|
|
|||
|
|
@ -3350,7 +3350,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||
if isSelected && value == nil {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: .white)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}), action: { _, f in
|
||||
f(.default)
|
||||
|
|
@ -3383,7 +3383,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||
if isSelected {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: .white)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { [weak strongSelf] _, f in
|
||||
f(.default)
|
||||
|
|
@ -3437,7 +3437,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||
if isSelected {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: .white)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
|
|
|||
|
|
@ -83,12 +83,14 @@ final class PeerChatTopTaggedMessageIdsTable: Table {
|
|||
let currentTopMessageId = self.get(peerId: message.id.peerId, threadId: message.threadId, namespace: message.id.namespace)
|
||||
if currentTopMessageId == nil || currentTopMessageId! < message.id {
|
||||
self.set(peerId: message.id.peerId, threadId: message.threadId, namespace: message.id.namespace, id: message.id)
|
||||
self.set(peerId: message.id.peerId, threadId: 0, namespace: message.id.namespace, id: message.id)
|
||||
}
|
||||
}
|
||||
case let .Remove(indices):
|
||||
for (index, _, threadId) in indices {
|
||||
if let messageId = self.get(peerId: index.id.peerId, threadId: threadId, namespace: index.id.namespace), index.id == messageId {
|
||||
self.set(peerId: index.id.peerId, threadId: threadId, namespace: index.id.namespace, id: nil)
|
||||
self.set(peerId: index.id.peerId, threadId: 0, namespace: index.id.namespace, id: nil)
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
|
@ -110,8 +112,12 @@ final class PeerChatTopTaggedMessageIdsTable: Table {
|
|||
if let maybeMessageId = maybeMessageId {
|
||||
var messageIdId: Int32 = maybeMessageId.id
|
||||
self.valueBox.set(self.table, key: self.key(combinedId: record.peerAndThreadId, namespace: record.namespace), value: MemoryBuffer(memory: &messageIdId, capacity: 4, length: 4, freeWhenDone: false))
|
||||
if record.peerAndThreadId.threadId != nil {
|
||||
self.valueBox.set(self.table, key: self.key(combinedId: PeerAndThreadId(peerId: record.peerAndThreadId.peerId, threadId: 0), namespace: record.namespace), value: MemoryBuffer(memory: &messageIdId, capacity: 4, length: 4, freeWhenDone: false))
|
||||
}
|
||||
} else {
|
||||
self.valueBox.remove(self.table, key: self.key(combinedId: record.peerAndThreadId, namespace: record.namespace), secure: false)
|
||||
self.valueBox.remove(self.table, key: self.key(combinedId: PeerAndThreadId(peerId: record.peerAndThreadId.peerId, threadId: 0), namespace: record.namespace), secure: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3507,7 +3507,13 @@ final class PostboxImpl {
|
|||
}
|
||||
if let peerId = mainPeerIdForTopTaggedMessages {
|
||||
for namespace in topTaggedMessageIdNamespaces {
|
||||
if let messageId = self.peerChatTopTaggedMessageIdsTable.get(peerId: peerId.peerId, threadId: peerId.threadId, namespace: namespace) {
|
||||
var messageId: MessageId?
|
||||
messageId = self.peerChatTopTaggedMessageIdsTable.get(peerId: peerId.peerId, threadId: peerId.threadId, namespace: namespace)
|
||||
if messageId == nil && peerId.threadId == nil {
|
||||
messageId = self.peerChatTopTaggedMessageIdsTable.get(peerId: peerId.peerId, threadId: 0, namespace: namespace)
|
||||
}
|
||||
|
||||
if let messageId {
|
||||
if let index = self.messageHistoryIndexTable.getIndex(messageId) {
|
||||
if let message = self.messageHistoryTable.getMessage(index) {
|
||||
topTaggedMessages[namespace] = MessageHistoryTopTaggedMessage.intermediate(message)
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ extension VideoChatScreenComponent.View {
|
|||
if isSelected {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: .white)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
|
@ -730,7 +730,7 @@ extension VideoChatScreenComponent.View {
|
|||
if output == currentOutput {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.actionSheet.primaryTextColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
|
@ -763,7 +763,7 @@ extension VideoChatScreenComponent.View {
|
|||
items.append(.separator)
|
||||
items.append(.action(ContextMenuActionItem(text: environment.strings.VoiceChat_SpeakPermissionEveryone, icon: { theme in
|
||||
if isMuted {
|
||||
return nil
|
||||
return UIImage()
|
||||
} else {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.actionSheet.primaryTextColor)
|
||||
}
|
||||
|
|
@ -777,7 +777,7 @@ extension VideoChatScreenComponent.View {
|
|||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: environment.strings.VoiceChat_SpeakPermissionAdmin, icon: { theme in
|
||||
if !isMuted {
|
||||
return nil
|
||||
return UIImage()
|
||||
} else {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.actionSheet.primaryTextColor)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ private final class VoiceChatShareScreenContextItemNode: ASDisplayNode, ContextM
|
|||
}
|
||||
|
||||
func canBeHighlighted() -> Bool {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
func updateIsHighlighted(isHighlighted: Bool) {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public func stringForFullAuthorName(message: EngineMessage, strings: Presentatio
|
|||
} else if author.isDeleted {
|
||||
authorName = strings.User_DeletedAccount
|
||||
} else {
|
||||
authorName = author.compactDisplayTitle
|
||||
authorName = author.displayTitle(strings: strings, displayOrder: nameDisplayOrder)
|
||||
}
|
||||
if let peer = message.peers[message.id.peerId].flatMap(EnginePeer.init), author.id != peer.id {
|
||||
authorString = [authorName, peer.displayTitle(strings: strings, displayOrder: nameDisplayOrder)]
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ final class BoostSlowModeButton: HighlightTrackingButtonNode {
|
|||
self?.requestUpdate()
|
||||
}, queue: .mainQueue())
|
||||
self.updateTimer?.start()
|
||||
} else {
|
||||
text = stringForDuration(0)
|
||||
}
|
||||
} else {
|
||||
self.updateTimer?.invalidate()
|
||||
|
|
@ -115,7 +117,7 @@ final class BoostSlowModeButton: HighlightTrackingButtonNode {
|
|||
self.textNode.segments = segments
|
||||
|
||||
let textSize = self.textNode.updateLayout(size: CGSize(width: 200.0, height: 100.0), animated: true)
|
||||
let totalSize = CGSize(width: textSize.width > 0.0 ? textSize.width + 38.0 : 33.0, height: 33.0)
|
||||
let totalSize = CGSize(width: textSize.width > 0.0 ? textSize.width + 38.0 : 40.0, height: 40.0)
|
||||
|
||||
self.containerNode.bounds = CGRect(origin: .zero, size: totalSize)
|
||||
self.containerNode.position = CGPoint(x: totalSize.width / 2.0, y: totalSize.height / 2.0)
|
||||
|
|
|
|||
|
|
@ -1172,9 +1172,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
self.touchDownGestureRecognizer = recognizer
|
||||
|
||||
textInputNode.textView.accessibilityHint = self.textPlaceholderNode.attributedText?.string
|
||||
|
||||
self.isAccessibilityContainer = true
|
||||
self.accessibilityElements = [textInputNode.textView]
|
||||
}
|
||||
|
||||
private func textFieldMaxHeight(_ maxHeight: CGFloat, metrics: LayoutMetrics, bottomInset: CGFloat) -> CGFloat {
|
||||
|
|
@ -2206,9 +2203,11 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
|
||||
var rightSlowModeInset: CGFloat = 0.0
|
||||
var slowModeButtonSize: CGSize = .zero
|
||||
if let presentationInterfaceState = self.presentationInterfaceState, (presentationInterfaceState.boostsToUnrestrict ?? 0) > 0 {
|
||||
var hasSlowmodeButton = false
|
||||
if let presentationInterfaceState = self.presentationInterfaceState, (presentationInterfaceState.boostsToUnrestrict ?? 0) > 0, presentationInterfaceState.slowmodeState != nil {
|
||||
slowModeButtonSize = self.slowModeButton.update(size: CGSize(width: width, height: 40.0), interfaceState: presentationInterfaceState)
|
||||
rightSlowModeInset = max(0.0, slowModeButtonSize.width - 33.0)
|
||||
rightSlowModeInset = max(0.0, slowModeButtonSize.width + 4.0)
|
||||
hasSlowmodeButton = true
|
||||
}
|
||||
self.rightSlowModeInset = rightSlowModeInset
|
||||
|
||||
|
|
@ -2395,7 +2394,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
if additionalSideInsets.right > 0.0 {
|
||||
textFieldInsets.right += additionalSideInsets.right / 3.0
|
||||
}
|
||||
if inputHasText || self.extendedSearchLayout || hasMediaDraft || hasForward {
|
||||
if inputHasText || self.extendedSearchLayout || hasMediaDraft || hasForward || hasSlowmodeButton {
|
||||
} else {
|
||||
if let customRightAction = self.customRightAction, case .empty = customRightAction {
|
||||
textFieldInsets.right = 8.0
|
||||
|
|
@ -3023,6 +3022,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
var nextButtonTopRight = CGPoint(x: textInputContainerBackgroundFrame.width - accessoryButtonInset, y: textInputContainerBackgroundFrame.height - minimalInputHeight)
|
||||
if self.extendedSearchLayout {
|
||||
nextButtonTopRight.x -= 46.0
|
||||
} else if hasSlowmodeButton {
|
||||
} else if inputHasText || hasMediaDraft || hasForward {
|
||||
nextButtonTopRight.x -= sendActionButtonsSize.width
|
||||
}
|
||||
|
|
@ -3172,7 +3172,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
}
|
||||
|
||||
var mediaActionButtonsFrame = CGRect(origin: CGPoint(x: textInputContainerBackgroundFrame.maxX + 6.0, y: textInputContainerBackgroundFrame.maxY - mediaActionButtonsSize.height), size: mediaActionButtonsSize)
|
||||
if inputHasText || self.extendedSearchLayout || hasMediaDraft || interfaceState.interfaceState.forwardMessageIds != nil {
|
||||
if inputHasText || self.extendedSearchLayout || hasMediaDraft || interfaceState.interfaceState.forwardMessageIds != nil || hasSlowmodeButton {
|
||||
mediaActionButtonsFrame.origin.x = width + 8.0
|
||||
}
|
||||
transition.updateFrame(node: self.mediaActionButtons, frame: mediaActionButtonsFrame)
|
||||
|
|
@ -3235,7 +3235,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
self.sendActionButtons.updateAbsoluteRect(CGRect(x: rect.origin.x + sendActionButtonsFrame.origin.x, y: rect.origin.y + sendActionButtonsFrame.origin.y, width: sendActionButtonsFrame.width, height: sendActionButtonsFrame.height), within: containerSize, transition: transition)
|
||||
}
|
||||
|
||||
let slowModeButtonFrame = CGRect(origin: CGPoint(x: hideOffset.x + width - rightInset - 5.0 - slowModeButtonSize.width + composeButtonsOffset, y: hideOffset.y + panelHeight - minimalHeight + 6.0), size: slowModeButtonSize)
|
||||
let slowModeButtonFrame = CGRect(origin: CGPoint(x: hideOffset.x + width - rightInset - 5.0 - slowModeButtonSize.width + composeButtonsOffset, y: hideOffset.y + panelHeight - minimalHeight), size: slowModeButtonSize)
|
||||
transition.updateFrame(node: self.slowModeButton, frame: slowModeButtonFrame)
|
||||
|
||||
if let _ = interfaceState.inputTextPanelState.mediaRecordingState {
|
||||
|
|
@ -4381,7 +4381,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
}
|
||||
})
|
||||
|
||||
blurTransitionOut.animateBlur(layer: self.sendActionButtons.sendContainerNode.layer, fromRadius: 0.0, toRadius: sendButtonBlurOut)
|
||||
blurTransitionOut.setBlur(layer: self.sendActionButtons.sendContainerNode.layer, radius: sendButtonBlurOut)
|
||||
|
||||
if let sendButtonRadialStatusNode = self.sendActionButtons.sendButtonRadialStatusNode {
|
||||
alphaTransition.updateAlpha(node: sendButtonRadialStatusNode, alpha: 0.0)
|
||||
|
|
@ -4412,7 +4412,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
if (hasText || keepSendButtonEnabled && !mediaInputIsActive && !hasSlowModeButton) {
|
||||
if self.sendActionButtons.sendContainerNode.alpha.isZero && self.rightSlowModeInset.isZero {
|
||||
alphaTransition.updateAlpha(node: self.sendActionButtons.sendContainerNode, alpha: 1.0)
|
||||
blurTransitionIn.animateBlur(layer: self.sendActionButtons.sendContainerNode.layer, fromRadius: sendButtonBlurOut, toRadius: 0.0)
|
||||
blurTransitionIn.setBlur(layer: self.sendActionButtons.sendContainerNode.layer, radius: 0.0)
|
||||
transition.animatePositionAdditive(layer: self.sendActionButtons.sendButton.imageNode.layer, offset: CGPoint(x: -22.0, y: 18.0))
|
||||
if let sendButtonRadialStatusNode = self.sendActionButtons.sendButtonRadialStatusNode {
|
||||
alphaTransition.updateAlpha(node: sendButtonRadialStatusNode, alpha: 1.0)
|
||||
|
|
@ -4427,7 +4427,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
strongSelf.applyUpdateSendButtonIcon()
|
||||
}
|
||||
})
|
||||
blurTransitionOut.animateBlur(layer: self.sendActionButtons.sendContainerNode.layer, fromRadius: 0.0, toRadius: sendButtonBlurOut)
|
||||
blurTransitionOut.setBlur(layer: self.sendActionButtons.sendContainerNode.layer, radius: sendButtonBlurOut)
|
||||
if let sendButtonRadialStatusNode = self.sendActionButtons.sendButtonRadialStatusNode {
|
||||
alphaTransition.updateAlpha(node: sendButtonRadialStatusNode, alpha: 0.0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ public final class ChatTextInputMediaRecordingButton: TGModernConversationInputM
|
|||
)
|
||||
let theme = self.hidesOnLock ? defaultDarkColorPresentationTheme : self.theme
|
||||
blobView.setColor(theme.chat.inputPanel.actionControlFillColor)
|
||||
blobView.hitTestSize = 110.0
|
||||
self.micDecorationValue = blobView
|
||||
return blobView
|
||||
}
|
||||
|
|
|
|||
|
|
@ -549,18 +549,18 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode {
|
|||
shimmeringForegroundColor = presentationData.theme.contextMenu.primaryColor.withMultipliedAlpha(0.07)
|
||||
}
|
||||
|
||||
let textLeftInset: CGFloat
|
||||
let textRightInset: CGFloat = 8.0
|
||||
var textLeftInset: CGFloat = horizontalInset
|
||||
|
||||
if let _ = self.iconNode.image {
|
||||
textLeftInset = iconSize.width + 18.0
|
||||
} else {
|
||||
textLeftInset = 0.0
|
||||
textLeftInset = 60.0
|
||||
}
|
||||
|
||||
let makeTextLayout = TextNodeWithEntities.asyncLayout(self.textNode)
|
||||
let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: attributedText, backgroundColor: nil, minimumNumberOfLines: 0, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - horizontalInset * 2.0 - textLeftInset, height: .greatestFiniteMagnitude), alignment: .left, lineSpacing: 0.12, cutout: nil, insets: UIEdgeInsets(), lineColor: nil, textShadowColor: nil, textStroke: nil))
|
||||
let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: attributedText, backgroundColor: nil, minimumNumberOfLines: 0, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - textLeftInset - textRightInset, height: .greatestFiniteMagnitude), alignment: .left, lineSpacing: 0.12, cutout: nil, insets: UIEdgeInsets(), lineColor: nil, textShadowColor: nil, textStroke: nil))
|
||||
let _ = textApply(self.arguments?.withUpdatedPlaceholderColor(shimmeringForegroundColor))
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: horizontalInset + textLeftInset, y: topInset), size: textLayout.size)
|
||||
let textFrame = CGRect(origin: CGPoint(x: textLeftInset, y: topInset), size: textLayout.size)
|
||||
transition.updateFrame(node: self.textNode.textNode, frame: textFrame)
|
||||
if textFrame.size.height.isZero {
|
||||
self.textNode.textNode.alpha = 0.0
|
||||
|
|
|
|||
|
|
@ -827,6 +827,17 @@ public final class ContextControllerActionsListStackItem: ContextControllerActio
|
|||
self.addSubnode(item.node)
|
||||
}
|
||||
|
||||
if let tipSignal = tipSignal {
|
||||
self.tipDisposable = (tipSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] tip in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.tip = tip
|
||||
requestUpdate(.immediate)
|
||||
}).strict()
|
||||
}
|
||||
|
||||
requestUpdateAction = { [weak self] id, action in
|
||||
guard let self else {
|
||||
return
|
||||
|
|
@ -981,17 +992,26 @@ public final class ContextControllerActionsListStackItem: ContextControllerActio
|
|||
if let tip = self.tip {
|
||||
let tipNode: InnerTextSelectionTipContainerNode
|
||||
var tipTransition = transition
|
||||
if let current = self.tipNode {
|
||||
if let current = self.tipNode, current.tip == tip {
|
||||
tipNode = current
|
||||
} else {
|
||||
tipTransition = .immediate
|
||||
|
||||
let previousTipNode = self.tipNode
|
||||
tipNode = InnerTextSelectionTipContainerNode(presentationData: presentationData, tip: tip, isInline: true)
|
||||
self.addSubnode(tipNode)
|
||||
self.tipNode = tipNode
|
||||
let getController = self.getController
|
||||
tipNode.requestDismiss = { completion in
|
||||
getController()?.dismiss(completion: completion)
|
||||
}
|
||||
self.addSubnode(tipNode)
|
||||
self.tipNode = tipNode
|
||||
|
||||
if let previousTipNode = previousTipNode {
|
||||
previousTipNode.animateTransitionInside(other: tipNode)
|
||||
previousTipNode.removeFromSupernode()
|
||||
|
||||
tipNode.animateContentIn()
|
||||
}
|
||||
}
|
||||
|
||||
let tipSeparatorNode: ContextControllerActionsListSeparatorItemNode
|
||||
|
|
@ -1004,12 +1024,15 @@ public final class ContextControllerActionsListStackItem: ContextControllerActio
|
|||
}
|
||||
|
||||
let (tipSeparatorMinSize, tipSeparatorApply) = tipSeparatorNode.update(presentationData: presentationData, constrainedSize: CGSize(width: combinedSize.width, height: 10.0))
|
||||
tipSeparatorNode.isHidden = self.itemNodes.isEmpty
|
||||
let tipSeparatorSize = CGSize(width: combinedSize.width, height: tipSeparatorMinSize.height)
|
||||
tipSeparatorApply(tipSeparatorSize, tipTransition)
|
||||
let tipSeparatorFrame = CGRect(origin: nextItemOrigin, size: tipSeparatorSize)
|
||||
tipTransition.updateFrame(node: tipSeparatorNode, frame: tipSeparatorFrame)
|
||||
nextItemOrigin.y += tipSeparatorSize.height
|
||||
combinedSize.height += tipSeparatorSize.height
|
||||
if !tipSeparatorNode.isHidden {
|
||||
nextItemOrigin.y += tipSeparatorSize.height
|
||||
combinedSize.height += tipSeparatorSize.height
|
||||
}
|
||||
|
||||
let tipSize = tipNode.updateLayout(widthClass: .compact, presentation: .inline, width: combinedSize.width, transition: tipTransition)
|
||||
let tipFrame = CGRect(origin: nextItemOrigin, size: tipSize)
|
||||
|
|
@ -1488,7 +1511,6 @@ public final class ContextControllerActionsStackNodeImpl: ASDisplayNode, Context
|
|||
}
|
||||
}
|
||||
|
||||
self.sourceExtractableContainer = nil
|
||||
self.contentContainer.frame = CGRect(origin: CGPoint(), size: sourceSize)
|
||||
self.contentContainer.layer.cornerRadius = normalCornerRadius
|
||||
|
||||
|
|
@ -1553,7 +1575,7 @@ public final class ContextControllerActionsStackNodeImpl: ASDisplayNode, Context
|
|||
self.backgroundView.update(size: size, cornerRadius: min(30.0, size.height * 0.5), isDark: presentationData.theme.overallDarkAppearance, tintColor: .init(kind: .panel), isInteractive: true, transition: transition)
|
||||
|
||||
if let sourceExtractableContainer = self.sourceExtractableContainer {
|
||||
transition.setFrame(view: sourceExtractableContainer.extractableContentView, frame: CGRect(origin: CGPoint(), size: size))
|
||||
transition.setFrame(view: sourceExtractableContainer.extractableContentView, frame: CGRect(origin: CGPoint(x: self.backgroundContainerInset, y: self.backgroundContainerInset), size: size))
|
||||
sourceExtractableContainer.updateState(state: .extracted(size: size, cornerRadius: min(30.0, size.height * 0.5), state: .animatedIn), transition: .transition(transition.containedViewLayoutTransition), completion: nil)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1206,7 +1206,6 @@ private final class CraftGiftPageContent: Component {
|
|||
}
|
||||
if let _ = view {
|
||||
if case let .gift(gift) = component.result {
|
||||
//TODO:localize
|
||||
let giftController = GiftViewScreen(
|
||||
context: component.context,
|
||||
subject: .profileGift(component.context.account.peerId, gift),
|
||||
|
|
@ -1834,6 +1833,7 @@ private final class SheetContainerComponent: CombinedComponent {
|
|||
state.updated(transition: .spring(duration: 0.3))
|
||||
} else if state.displayFailure {
|
||||
craftAnotherGift()
|
||||
dismiss(true)
|
||||
} else {
|
||||
HapticFeedback().impact(.medium)
|
||||
|
||||
|
|
@ -1884,6 +1884,10 @@ private final class SheetContainerComponent: CombinedComponent {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Queue.mainQueue().after(1.0) {
|
||||
craftContext.reload()
|
||||
}
|
||||
}, error: { error in
|
||||
switch error {
|
||||
case .craftFailed:
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ private func actionForAttribute(attribute: StarGift.UniqueGift.Attribute, presen
|
|||
return ContextMenuActionItem(text: title, entities: entities, entityFiles: entityFiles, enableEntityAnimations: false, customTextInsets: UIEdgeInsets(top: 0.0, left: 18.0 + 5.0, bottom: 0.0, right: 0.0), parseMarkdown: true, icon: { _ in
|
||||
return nil
|
||||
}, additionalLeftIcon: { theme in
|
||||
return isSelected ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return isSelected ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
getController()?.dismiss(result: .dismissWithoutContent, completion: nil)
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ private func actionForAttribute(attribute: StarGift.UniqueGift.Attribute, presen
|
|||
return ContextMenuActionItem(text: title, entities: entities, icon: { _ in
|
||||
return generateGradientFilledCircleImage(diameter: 24.0, colors: [UIColor(rgb: UInt32(bitPattern: innerColor)).cgColor, UIColor(rgb: UInt32(bitPattern: outerColor)).cgColor])
|
||||
}, additionalLeftIcon: { theme in
|
||||
return isSelected ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return isSelected ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
getController()?.dismiss(result: .dismissWithoutContent, completion: nil)
|
||||
|
||||
|
|
|
|||
|
|
@ -437,7 +437,21 @@ public class GlassBackgroundView: UIView {
|
|||
if let legacyView = self.legacyView {
|
||||
switch shape {
|
||||
case let .roundedRect(cornerRadius):
|
||||
legacyView.update(size: size, cornerRadius: cornerRadius, transition: transition)
|
||||
let style: LegacyGlassView.Style
|
||||
switch tintColor.kind {
|
||||
case .panel:
|
||||
style = .normal
|
||||
case .clear:
|
||||
style = .clear
|
||||
case let .custom(styleValue, _):
|
||||
switch styleValue {
|
||||
case .clear:
|
||||
style = .clear
|
||||
case .default:
|
||||
style = .normal
|
||||
}
|
||||
}
|
||||
legacyView.update(size: size, cornerRadius: cornerRadius, style: style, transition: transition)
|
||||
}
|
||||
transition.setFrame(view: legacyView, frame: CGRect(origin: CGPoint(), size: size))
|
||||
transition.setAlpha(view: legacyView, alpha: isVisible ? 1.0 : 0.0)
|
||||
|
|
@ -512,19 +526,28 @@ public class GlassBackgroundView: UIView {
|
|||
|
||||
if let foregroundView = self.foregroundView {
|
||||
let fillColor: UIColor
|
||||
let borderWidthFactor: CGFloat
|
||||
switch tintColor.kind {
|
||||
case .panel:
|
||||
borderWidthFactor = 1.0
|
||||
if isDark {
|
||||
fillColor = UIColor(white: 1.0, alpha: 1.0).mixedWith(.black, alpha: 1.0 - 0.11).withAlphaComponent(0.85)
|
||||
} else {
|
||||
fillColor = UIColor(white: 1.0, alpha: 0.7)
|
||||
}
|
||||
case .clear:
|
||||
borderWidthFactor = 2.0
|
||||
fillColor = UIColor(white: 1.0, alpha: 0.0)
|
||||
case let .custom(_, color):
|
||||
case let .custom(style, color):
|
||||
fillColor = color
|
||||
switch style {
|
||||
case .clear:
|
||||
borderWidthFactor = 2.0
|
||||
case .default:
|
||||
borderWidthFactor = 1.0
|
||||
}
|
||||
}
|
||||
foregroundView.image = GlassBackgroundView.generateLegacyGlassImage(size: CGSize(width: outerCornerRadius * 2.0, height: outerCornerRadius * 2.0), inset: shadowInset, isDark: isDark, fillColor: fillColor)
|
||||
foregroundView.image = GlassBackgroundView.generateLegacyGlassImage(size: CGSize(width: outerCornerRadius * 2.0, height: outerCornerRadius * 2.0), inset: shadowInset, borderWidthFactor: borderWidthFactor, isDark: isDark, fillColor: fillColor)
|
||||
transition.setAlpha(view: foregroundView, alpha: isVisible ? 1.0 : 0.0)
|
||||
} else {
|
||||
if let nativeParamsView = self.nativeParamsView, let nativeView = self.nativeView {
|
||||
|
|
@ -565,11 +588,21 @@ public class GlassBackgroundView: UIView {
|
|||
|
||||
if glassEffect == nil {
|
||||
if nativeView.effect is UIGlassEffect {
|
||||
if transition.animation.isImmediate {
|
||||
nativeView.effect = nil
|
||||
} else {
|
||||
transition.animateView {
|
||||
if #available(iOS 26.1, *) {
|
||||
if transition.animation.isImmediate {
|
||||
nativeView.effect = nil
|
||||
} else {
|
||||
transition.animateView {
|
||||
nativeView.effect = nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if transition.animation.isImmediate {
|
||||
nativeView.effect = UIVisualEffect()
|
||||
} else {
|
||||
transition.animateView {
|
||||
nativeView.effect = UIVisualEffect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -598,6 +631,9 @@ public class GlassBackgroundView: UIView {
|
|||
}
|
||||
}
|
||||
|
||||
if let nativeParamsView = self.nativeParamsView {
|
||||
transition.setFrame(view: nativeParamsView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: size))
|
||||
}
|
||||
transition.setFrame(view: self.maskContainerView, frame: CGRect(origin: CGPoint(), size: CGSize(width: size.width + shadowInset * 2.0, height: size.height + shadowInset * 2.0)))
|
||||
transition.setFrame(view: self.maskContentView, frame: CGRect(origin: CGPoint(x: shadowInset, y: shadowInset), size: size))
|
||||
if let foregroundView = self.foregroundView {
|
||||
|
|
@ -631,7 +667,7 @@ public final class GlassBackgroundContainerView: UIView {
|
|||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
if #available(iOS 26.0, *) {
|
||||
if #available(iOS 26.0, *), !GlassBackgroundView.useCustomGlassImpl {
|
||||
let effect = UIGlassContainerEffect()
|
||||
effect.spacing = 7.0
|
||||
let nativeView = UIVisualEffectView(effect: effect)
|
||||
|
|
@ -707,6 +743,9 @@ public final class GlassBackgroundContainerView: UIView {
|
|||
nativeParamsView.lumaMin = 0.8
|
||||
nativeParamsView.lumaMax = 0.801
|
||||
}
|
||||
if let nativeParamsView = self.nativeParamsView {
|
||||
transition.setFrame(view: nativeParamsView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: size))
|
||||
}
|
||||
|
||||
transition.animateView {
|
||||
nativeView.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
|
@ -768,7 +807,7 @@ private extension CGContext {
|
|||
}
|
||||
|
||||
public extension GlassBackgroundView {
|
||||
static func generateLegacyGlassImage(size: CGSize, inset: CGFloat, isDark: Bool, fillColor: UIColor) -> UIImage {
|
||||
static func generateLegacyGlassImage(size: CGSize, inset: CGFloat, borderWidthFactor: CGFloat = 1.0, isDark: Bool, fillColor: UIColor) -> UIImage {
|
||||
var size = size
|
||||
if size == .zero {
|
||||
size = CGSize(width: 2.0, height: 2.0)
|
||||
|
|
@ -908,7 +947,7 @@ public extension GlassBackgroundView {
|
|||
var ellipseRect = CGRect(origin: CGPoint(), size: size).insetBy(dx: inset, dy: inset)
|
||||
context.fillEllipse(in: ellipseRect)
|
||||
|
||||
let lineWidth: CGFloat = isDark ? 0.8 : 0.8
|
||||
let lineWidth: CGFloat = (isDark ? 0.8 : 0.8) * borderWidthFactor
|
||||
let strokeColor: UIColor
|
||||
let blendMode: CGBlendMode
|
||||
let baseAlpha: CGFloat = isDark ? 0.3 : 0.6
|
||||
|
|
@ -956,20 +995,6 @@ public extension GlassBackgroundView {
|
|||
|
||||
context.resetClip()
|
||||
context.setBlendMode(.normal)
|
||||
|
||||
//let image = makeInnerShadowPillImageExact(size: CGSize(width: size.width - inset * 2.0, height: size.height - inset * 2.0), scale: UIScreenScale, glossColor: UIColor(white: 1.0, alpha: 1.0), borderWidth: 1.33)
|
||||
/*let image = generateCircleImage(diameter: size.width - inset * 2.0, lineWidth: 0.5, color: UIColor(white: 1.0, alpha: 1.0))!
|
||||
|
||||
if s == 0.0 && abs(a - 0.7) < 0.1 && !isDark {
|
||||
image.draw(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: inset, dy: inset), blendMode: .normal, alpha: 1.0)
|
||||
} else if s <= 0.3 && !isDark {
|
||||
image.draw(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: inset, dy: inset), blendMode: .normal, alpha: 0.7)
|
||||
} else if b >= 0.2 {
|
||||
let maxAlpha: CGFloat = isDark ? 0.7 : 0.8
|
||||
image.draw(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: inset, dy: inset), blendMode: .overlay, alpha: max(0.5, min(1.0, maxAlpha * s)))
|
||||
} else {
|
||||
image.draw(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: inset, dy: inset), blendMode: .normal, alpha: 0.5)
|
||||
}*/
|
||||
}
|
||||
innerImage.draw(in: CGRect(origin: CGPoint(), size: size))
|
||||
}.stretchableImage(withLeftCapWidth: Int(size.width * 0.5), topCapHeight: Int(size.height * 0.5))
|
||||
|
|
|
|||
|
|
@ -81,13 +81,20 @@ private final class BackdropLayerDelegate: NSObject, CALayerDelegate {
|
|||
}
|
||||
|
||||
final class LegacyGlassView: UIView {
|
||||
enum Style {
|
||||
case normal
|
||||
case clear
|
||||
}
|
||||
|
||||
private struct Params: Equatable {
|
||||
let size: CGSize
|
||||
let cornerRadius: CGFloat
|
||||
let style: Style
|
||||
|
||||
init(size: CGSize, cornerRadius: CGFloat) {
|
||||
init(size: CGSize, cornerRadius: CGFloat, style: Style) {
|
||||
self.size = size
|
||||
self.cornerRadius = cornerRadius
|
||||
self.style = style
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,19 +116,8 @@ final class LegacyGlassView: UIView {
|
|||
self.layer.addSublayer(backdropLayer)
|
||||
backdropLayer.delegate = self.backdropLayerDelegate
|
||||
|
||||
let blur: CGFloat
|
||||
let scale: CGFloat
|
||||
|
||||
blur = 2.0
|
||||
scale = 1.0
|
||||
|
||||
invokeBackdropLayerSetScaleMethod(object: backdropLayer, scale: scale)
|
||||
backdropLayer.rasterizationScale = scale
|
||||
|
||||
if let blurFilter = CALayer.blur() {
|
||||
blurFilter.setValue(blur as NSNumber, forKey: "inputRadius")
|
||||
backdropLayer.filters = [blurFilter]
|
||||
}
|
||||
invokeBackdropLayerSetScaleMethod(object: backdropLayer, scale: 1.0)
|
||||
backdropLayer.rasterizationScale = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -129,8 +125,9 @@ final class LegacyGlassView: UIView {
|
|||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func update(size: CGSize, cornerRadius: CGFloat, transition: ComponentTransition) {
|
||||
let params = Params(size: size, cornerRadius: cornerRadius)
|
||||
func update(size: CGSize, cornerRadius: CGFloat, style: Style, transition: ComponentTransition) {
|
||||
let params = Params(size: size, cornerRadius: cornerRadius, style: style)
|
||||
let previousParams = self.params
|
||||
if self.params == params {
|
||||
return
|
||||
}
|
||||
|
|
@ -140,6 +137,18 @@ final class LegacyGlassView: UIView {
|
|||
return
|
||||
}
|
||||
|
||||
if previousParams?.style != style {
|
||||
if let blurFilter = CALayer.blur() {
|
||||
switch style {
|
||||
case .clear:
|
||||
blurFilter.setValue(6.0 as NSNumber, forKey: "inputRadius")
|
||||
case .normal:
|
||||
blurFilter.setValue(2.0 as NSNumber, forKey: "inputRadius")
|
||||
}
|
||||
backdropLayer.filters = [blurFilter]
|
||||
}
|
||||
}
|
||||
|
||||
transition.setCornerRadius(layer: self.layer, cornerRadius: cornerRadius)
|
||||
transition.setFrame(layer: backdropLayer, frame: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
|
|
|
|||
|
|
@ -228,6 +228,7 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon
|
|||
replaceImpl = { [weak controller] c in
|
||||
controller?.replace(with: c)
|
||||
}
|
||||
strongSelf.peerSelectionNode.pushedController = controller
|
||||
strongSelf.push(controller)
|
||||
} else {
|
||||
strongSelf.selectTab(id: id)
|
||||
|
|
@ -306,7 +307,7 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon
|
|||
return
|
||||
}
|
||||
|
||||
if mainChannel.hasPermission(.manageDirect) {
|
||||
if !mainChannel.isMonoForum || mainChannel.hasPermission(.manageDirect) {
|
||||
let displayPeer = EnginePeer(mainChannel)
|
||||
|
||||
let controller = PeerSelectionControllerImpl(
|
||||
|
|
@ -330,6 +331,7 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon
|
|||
)
|
||||
)
|
||||
controller.peerSelected = self.peerSelected
|
||||
self.peerSelectionNode.pushedController = controller
|
||||
self.push(controller)
|
||||
} else {
|
||||
peerSelected(.channel(peer), threadId)
|
||||
|
|
@ -373,6 +375,7 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon
|
|||
)
|
||||
)
|
||||
controller.peerSelected = strongSelf.peerSelected
|
||||
strongSelf.peerSelectionNode.pushedController = controller
|
||||
strongSelf.push(controller)
|
||||
} else {
|
||||
peerSelected(peer, threadId)
|
||||
|
|
@ -626,4 +629,16 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
override public func dismiss(completion: (() -> Void)? = nil) {
|
||||
guard let navigationController = self.navigationController as? NavigationController else {
|
||||
return
|
||||
}
|
||||
var viewControllers = navigationController.viewControllers
|
||||
viewControllers.removeAll(where: { $0 === self })
|
||||
if let pushedController = self.peerSelectionNode.pushedController {
|
||||
viewControllers.removeAll(where: { $0 === pushedController })
|
||||
}
|
||||
navigationController.setViewControllers(viewControllers, animated: true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||
|
||||
private var countPanelNode: PeersCountPanelNode?
|
||||
|
||||
weak var pushedController: ViewController?
|
||||
|
||||
private var readyValue = Promise<Bool>()
|
||||
var ready: Signal<Bool, NoError> {
|
||||
return self.readyValue.get()
|
||||
|
|
@ -286,10 +288,12 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||
return
|
||||
}
|
||||
self.chatListNode?.clearHighlightAnimated(true)
|
||||
self.mainContainerNode?.currentItemNode.clearHighlightAnimated(true)
|
||||
self.requestOpenPeer?(mainPeer, peer.id.toInt64())
|
||||
})
|
||||
} else {
|
||||
self.chatListNode?.clearHighlightAnimated(true)
|
||||
self.mainContainerNode?.currentItemNode.clearHighlightAnimated(true)
|
||||
self.requestOpenPeer?(peer, threadId)
|
||||
}
|
||||
}
|
||||
|
|
@ -348,6 +352,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||
replaceImpl = { [weak controller] c in
|
||||
controller?.replace(with: c)
|
||||
}
|
||||
strongSelf.pushedController = controller
|
||||
strongSelf.controller?.push(controller)
|
||||
}
|
||||
self.addSubnode(mainContainerNode)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/TelegramAccountAuxiliaryMethods",
|
||||
"//submodules/TelegramUI/Components/PeerSelectionController",
|
||||
"//submodules/TelegramUI/Components/ContextMenuScreen",
|
||||
"//submodules/TelegramUI/Components/NavigationBarImpl",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import TelegramUIDeclareEncodables
|
|||
import TelegramAccountAuxiliaryMethods
|
||||
import PeerSelectionController
|
||||
import ContextMenuScreen
|
||||
import NavigationBarImpl
|
||||
|
||||
private var installedSharedLogger = false
|
||||
|
||||
|
|
@ -194,6 +195,10 @@ public class ShareRootControllerImpl {
|
|||
public init(initializationData: ShareRootControllerInitializationData, getExtensionContext: @escaping () -> NSExtensionContext?) {
|
||||
self.initializationData = initializationData
|
||||
self.getExtensionContext = getExtensionContext
|
||||
|
||||
defaultNavigationBarImpl = { presentationData in
|
||||
return NavigationBarImpl(presentationData: presentationData)
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ public final class VideoPlaybackControlsComponent: Component {
|
|||
self.leftIconView.update(size: leftButtonFrame.size)
|
||||
transition.setAlpha(view: self.leftIconView, alpha: areSideButtonsVisible ? 1.0 : 0.0)
|
||||
transition.setBlur(layer: self.leftIconView.layer, radius: areSideButtonsVisible ? 0.0 : 10.0)
|
||||
self.leftButtonBackgroundView.isUserInteractionEnabled = areSideButtonsVisible
|
||||
|
||||
transition.setFrame(view: self.rightButtonBackgroundView, frame: rightButtonFrame)
|
||||
self.rightButtonBackgroundView.update(size: rightButtonFrame.size, cornerRadius: rightButtonFrame.height * 0.5, isDark: true, tintColor: buttonsTintColor, isInteractive: true, isVisible: areSideButtonsVisible, transition: transition)
|
||||
|
|
@ -174,6 +175,7 @@ public final class VideoPlaybackControlsComponent: Component {
|
|||
self.rightIconView.update(size: rightButtonFrame.size)
|
||||
transition.setAlpha(view: self.rightIconView, alpha: areSideButtonsVisible ? 1.0 : 0.0)
|
||||
transition.setBlur(layer: self.rightIconView.layer, radius: areSideButtonsVisible ? 0.0 : 10.0)
|
||||
self.rightButtonBackgroundView.isUserInteractionEnabled = areSideButtonsVisible
|
||||
|
||||
transition.setFrame(view: self.centerButtonBackgroundView, frame: centerButtonFrame)
|
||||
self.centerButtonBackgroundView.update(size: centerButtonFrame.size, cornerRadius: centerButtonFrame.height * 0.5, isDark: true, tintColor: buttonsTintColor, isInteractive: true, isVisible: component.isVisible, transition: transition)
|
||||
|
|
|
|||
|
|
@ -379,6 +379,9 @@ extension ChatControllerImpl {
|
|||
if previousState.chatTitleContent != contentData.state.chatTitleContent {
|
||||
animated = true
|
||||
}
|
||||
if previousState.slowmodeState != contentData.state.slowmodeState || previousState.boostsToUnrestrict != contentData.state.boostsToUnrestrict {
|
||||
animated = true
|
||||
}
|
||||
|
||||
var transition: ContainedViewLayoutTransition = animated ? .animated(duration: 0.4, curve: .spring) : .immediate
|
||||
if let forceAnimationTransition {
|
||||
|
|
|
|||
|
|
@ -743,6 +743,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
if !self.presentationData.theme.overallDarkAppearance {
|
||||
preferredGlassType = .default
|
||||
}
|
||||
if self.context.sharedContext.immediateExperimentalUISettings.forceClearGlass {
|
||||
preferredGlassType = .clear
|
||||
}
|
||||
if self.presentationInterfaceState.preferredGlassType != preferredGlassType {
|
||||
self.updateChatPresentationInterfaceState(transition: .immediate, interactive: false, { state in
|
||||
return state.updatedPreferredGlassType(preferredGlassType)
|
||||
|
|
@ -6411,6 +6414,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
if !self.presentationData.theme.overallDarkAppearance {
|
||||
preferredGlassType = .default
|
||||
}
|
||||
if self.context.sharedContext.immediateExperimentalUISettings.forceClearGlass {
|
||||
preferredGlassType = .clear
|
||||
}
|
||||
self.updateChatPresentationInterfaceState(animated: false, interactive: false, { state in
|
||||
var state = state
|
||||
state = state.updatedPresentationReady(self.didSetPresentationData)
|
||||
|
|
|
|||
|
|
@ -2324,8 +2324,12 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
|
|||
}
|
||||
|
||||
var keyboardButtonsMessage = view.topTaggedMessages.first
|
||||
if keyboardButtonsMessage != nil && keyboardButtonsMessage?.threadId != chatLocation.threadId {
|
||||
keyboardButtonsMessage = nil
|
||||
if let keyboardButtonsMessageValue = keyboardButtonsMessage {
|
||||
if keyboardButtonsMessageValue.threadId != chatLocation.threadId {
|
||||
if chatLocation.threadId != nil {
|
||||
keyboardButtonsMessage = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if let keyboardButtonsMessageValue = keyboardButtonsMessage, keyboardButtonsMessageValue.isRestricted(platform: "ios", contentSettings: context.currentContentSettings.with({ $0 })) {
|
||||
keyboardButtonsMessage = nil
|
||||
|
|
@ -3903,7 +3907,9 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
|
|||
loadState = .messages
|
||||
} else if let historyView = strongSelf.historyView {
|
||||
if historyView.filteredEntries.isEmpty {
|
||||
if let firstEntry = historyView.originalView.entries.first {
|
||||
if historyView.originalView.isLoading {
|
||||
loadState = .loading(false)
|
||||
} else if let firstEntry = historyView.originalView.entries.first {
|
||||
var emptyType = ChatHistoryNodeLoadState.EmptyType.generic
|
||||
for media in firstEntry.message.media {
|
||||
if let action = media as? TelegramMediaAction {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ final class NotificationItemContainerNode: ASDisplayNode {
|
|||
if let contentNode = self.contentNode {
|
||||
let inset: CGFloat = 8.0
|
||||
|
||||
var contentInsets = UIEdgeInsets(top: inset, left: inset + layout.safeInsets.left, bottom: inset, right: inset + layout.safeInsets.right)
|
||||
var contentInsets = UIEdgeInsets(top: inset + layout.safeInsets.left, left: inset, bottom: inset, right: inset + layout.safeInsets.right)
|
||||
|
||||
if let statusBarHeight = layout.statusBarHeight, statusBarHeight >= 39.0 {
|
||||
if layout.deviceMetrics.hasDynamicIsland {
|
||||
|
|
@ -109,7 +109,7 @@ final class NotificationItemContainerNode: ASDisplayNode {
|
|||
}
|
||||
}
|
||||
|
||||
let containerWidth = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: layout.safeInsets.left)
|
||||
let containerWidth = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: 0.0)
|
||||
|
||||
let contentWidth = containerWidth - contentInsets.left - contentInsets.right
|
||||
let contentHeight = contentNode.updateLayout(width: contentWidth, transition: transition)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||
public var debugRatingLayout: Bool
|
||||
public var enableUpdates: Bool
|
||||
public var enablePWA: Bool
|
||||
public var forceClearGlass: Bool
|
||||
|
||||
public static var defaultSettings: ExperimentalUISettings {
|
||||
return ExperimentalUISettings(
|
||||
|
|
@ -117,7 +118,8 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||
allForumsHaveTabs: false,
|
||||
debugRatingLayout: false,
|
||||
enableUpdates: false,
|
||||
enablePWA: false
|
||||
enablePWA: false,
|
||||
forceClearGlass: false
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -166,7 +168,8 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||
allForumsHaveTabs: Bool,
|
||||
debugRatingLayout: Bool,
|
||||
enableUpdates: Bool,
|
||||
enablePWA: Bool
|
||||
enablePWA: Bool,
|
||||
forceClearGlass: Bool
|
||||
) {
|
||||
self.keepChatNavigationStack = keepChatNavigationStack
|
||||
self.skipReadHistory = skipReadHistory
|
||||
|
|
@ -213,6 +216,7 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||
self.debugRatingLayout = debugRatingLayout
|
||||
self.enableUpdates = enableUpdates
|
||||
self.enablePWA = enablePWA
|
||||
self.forceClearGlass = forceClearGlass
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
|
|
@ -263,6 +267,7 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||
self.debugRatingLayout = try container.decodeIfPresent(Bool.self, forKey: "debugRatingLayout") ?? false
|
||||
self.enableUpdates = try container.decodeIfPresent(Bool.self, forKey: "enableUpdates") ?? false
|
||||
self.enablePWA = try container.decodeIfPresent(Bool.self, forKey: "enablePWA") ?? false
|
||||
self.forceClearGlass = try container.decodeIfPresent(Bool.self, forKey: "forceClearGlass") ?? false
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
|
|
@ -313,6 +318,7 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||
try container.encodeIfPresent(self.debugRatingLayout, forKey: "debugRatingLayout")
|
||||
try container.encodeIfPresent(self.enableUpdates, forKey: "enableUpdates")
|
||||
try container.encodeIfPresent(self.enablePWA, forKey: "enablePWA")
|
||||
try container.encodeIfPresent(self.forceClearGlass, forKey: "forceClearGlass")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#import "NSWeakReference.h"
|
||||
#import <UIKitRuntimeUtils/UIKitUtils.h>
|
||||
#import <dlfcn.h>
|
||||
|
||||
@interface UIViewControllerPresentingProxy : UIViewController
|
||||
|
||||
|
|
@ -457,8 +458,6 @@ static NSMutableDictionary<NSString *, TrustedWebRecord *> *trustedWebRecords()
|
|||
return value;
|
||||
}
|
||||
|
||||
void WKWebsiteDataStoreReinitializeAppBoundDomains(CFTypeRef dataStoreRef);
|
||||
|
||||
@implementation WebHelpers
|
||||
|
||||
+ (NSArray<NSString *> * _Nonnull)threadSafeTrustedDomains {
|
||||
|
|
@ -504,7 +503,16 @@ void WKWebsiteDataStoreReinitializeAppBoundDomains(CFTypeRef dataStoreRef);
|
|||
}
|
||||
|
||||
+ (void)forceRefreshTrustedDomains:(WKWebsiteDataStore * _Nonnull)websiteDataStore {
|
||||
WKWebsiteDataStoreReinitializeAppBoundDomains((__bridge CFTypeRef)(websiteDataStore));
|
||||
static void (*reinitializeFunction)(CFTypeRef dataStoreRef) = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *nameString = [NSString stringWithFormat:@"WK%@", @"WebsiteDataStoreReinitializeAppBoundDomains"];
|
||||
reinitializeFunction = dlsym(RTLD_DEFAULT, [nameString UTF8String]);
|
||||
});
|
||||
|
||||
if (reinitializeFunction) {
|
||||
reinitializeFunction((__bridge CFTypeRef)(websiteDataStore));
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -513,8 +521,10 @@ void WKWebsiteDataStoreReinitializeAppBoundDomains(CFTypeRef dataStoreRef);
|
|||
|
||||
- (id)_65087dc8_objectForInfoDictionaryKey:(NSString *)key {
|
||||
if ([key isEqualToString:@"WKAppBoundDomains"]) {
|
||||
//NSLog(@"Returning trusted domains: %@", [WebHelpers threadSafeTrustedDomains]);
|
||||
return [WebHelpers threadSafeTrustedDomains];
|
||||
NSArray *result = [WebHelpers threadSafeTrustedDomains];
|
||||
if (result.count != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return [self _65087dc8_objectForInfoDictionaryKey:key];
|
||||
}
|
||||
|
|
|
|||
1
third-party/libyuv/BUILD
vendored
1
third-party/libyuv/BUILD
vendored
|
|
@ -25,6 +25,7 @@ arch_specific_cflags = select({
|
|||
"@build_bazel_rules_apple//apple:ios_arm64": common_flags + arm64_specific_flags,
|
||||
"//build-system:ios_sim_arm64": common_flags + arm64_specific_flags,
|
||||
"@build_bazel_rules_apple//apple:ios_x86_64": common_flags + x86_64_specific_flags,
|
||||
"//conditions:default": common_flags,
|
||||
})
|
||||
|
||||
cc_library(
|
||||
|
|
|
|||
18
third-party/opus/BUILD
vendored
18
third-party/opus/BUILD
vendored
|
|
@ -29,6 +29,10 @@ genrule(
|
|||
BUILD_ARCH="sim_arm64"
|
||||
elif [ "$(TARGET_CPU)" == "ios_x86_64" ]; then
|
||||
BUILD_ARCH="x86_64"
|
||||
elif [ "$(TARGET_CPU)" == "k8" ] || [ "$(TARGET_CPU)" == "x86_64" ]; then
|
||||
BUILD_ARCH="linux_x86_64"
|
||||
elif [ "$(TARGET_CPU)" == "aarch64" ] || [ "$(TARGET_CPU)" == "arm64" ]; then
|
||||
BUILD_ARCH="linux_arm64"
|
||||
else
|
||||
echo "Unsupported architecture $(TARGET_CPU)"
|
||||
fi
|
||||
|
|
@ -63,6 +67,20 @@ cc_library(
|
|||
srcs = [":Public/opus/lib/lib" + x + ".a" for x in libs],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "opus_cc",
|
||||
hdrs = [":Public/opus/" + x for x in headers],
|
||||
includes = [
|
||||
"Public",
|
||||
],
|
||||
deps = [
|
||||
":opus_lib",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
|
||||
objc_library(
|
||||
name = "opus",
|
||||
module_name = "opus",
|
||||
|
|
|
|||
24
third-party/opus/build-opus-bazel.sh
vendored
24
third-party/opus/build-opus-bazel.sh
vendored
|
|
@ -12,8 +12,6 @@ OPT_CFLAGS="-Os -g"
|
|||
OPT_LDFLAGS=""
|
||||
OPT_CONFIG_ARGS=""
|
||||
|
||||
DEVELOPER=`xcode-select -print-path`
|
||||
|
||||
OUTPUTDIR="$BUILD_DIR/Public"
|
||||
|
||||
# where we will keep our sources and build from.
|
||||
|
|
@ -28,7 +26,27 @@ mkdir -p $INTERDIR
|
|||
tar zxf "$BUILD_DIR/$SOURCE_CODE_ARCHIVE" -C $SRCDIR
|
||||
cd "${SRCDIR}/opus-"*
|
||||
|
||||
if [ "${ARCH}" == "x86_64" ]; then
|
||||
if [ "${ARCH}" = "linux_x86_64" ] || [ "${ARCH}" = "linux_arm64" ]; then
|
||||
mkdir -p "${INTERDIR}"
|
||||
|
||||
# Keep it simple and portable for container builds.
|
||||
./configure \
|
||||
--disable-shared \
|
||||
--enable-static \
|
||||
--with-pic \
|
||||
--disable-extra-programs \
|
||||
--disable-doc \
|
||||
--disable-asm \
|
||||
--enable-intrinsics \
|
||||
${OPT_CONFIG_ARGS} \
|
||||
--prefix="${INTERDIR}" \
|
||||
CFLAGS="$CFLAGS ${OPT_CFLAGS} -fPIC" \
|
||||
LDFLAGS="$LDFLAGS ${OPT_LDFLAGS}"
|
||||
|
||||
make -j"$(getconf _NPROCESSORS_ONLN || echo 4)"
|
||||
make install
|
||||
exit 0
|
||||
elif [ "${ARCH}" == "x86_64" ]; then
|
||||
PLATFORM="iphonesimulator"
|
||||
EXTRA_CFLAGS="-arch ${ARCH}"
|
||||
EXTRA_CONFIG="--host=x86_64-apple-darwin"
|
||||
|
|
|
|||
8
third-party/webrtc/absl/BUILD
vendored
8
third-party/webrtc/absl/BUILD
vendored
|
|
@ -355,9 +355,15 @@ absl_sources = [
|
|||
"absl/types/bad_variant_access.cc",
|
||||
]
|
||||
|
||||
absl_inc_files = [
|
||||
f
|
||||
for f in glob(["absl/**/*.inc"])
|
||||
if f not in absl_headers
|
||||
]
|
||||
|
||||
cc_library(
|
||||
name = "absl",
|
||||
hdrs = absl_headers,
|
||||
hdrs = absl_headers + absl_inc_files,
|
||||
srcs = absl_sources,
|
||||
cxxopts = [
|
||||
"-std=c++17",
|
||||
|
|
|
|||
1
third-party/webrtc/crc32c/BUILD
vendored
1
third-party/webrtc/crc32c/BUILD
vendored
|
|
@ -6,6 +6,7 @@ arch_specific_crc32c_sources = select({
|
|||
"//build-system:ios_sim_arm64": [
|
||||
"third_party/crc32c/src/crc32c_arm64.cc",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
})
|
||||
|
||||
crc32c_sources = ["third_party/crc32c/src/" + x for x in [
|
||||
|
|
|
|||
1
third-party/webrtc/libsrtp/BUILD
vendored
1
third-party/webrtc/libsrtp/BUILD
vendored
|
|
@ -37,6 +37,7 @@ arm64_specific_flags = [
|
|||
arch_specific_cflags = select({
|
||||
"@build_bazel_rules_apple//apple:ios_arm64": common_flags + arm64_specific_flags,
|
||||
"//build-system:ios_sim_arm64": common_flags + arm64_specific_flags,
|
||||
"//conditions:default": [],
|
||||
})
|
||||
|
||||
optimization_flags = select({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"app": "12.4",
|
||||
"app": "12.4.1",
|
||||
"xcode": "26.2",
|
||||
"bazel": "8.4.2:45e9388abf21d1107e146ea366ad080eb93cb6a5f3a4a3b048f78de0bc3faffa",
|
||||
"macos": "26"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue