From 4a13c3830aae716d1da784e1bba92550eaac5f51 Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Fri, 26 Dec 2025 20:29:30 +0800 Subject: [PATCH] Glass --- .../Telegram-iOS/en.lproj/Localizable.strings | 9 +- .../Sources/BotCheckoutHeaderItem.swift | 2 +- .../Sources/BotCheckoutPriceItem.swift | 2 +- .../Sources/BotCheckoutTipItem.swift | 2 +- .../CallListUI/Sources/CallListCallItem.swift | 2 +- .../Sources/CallListController.swift | 9 +- .../Sources/CallListControllerNode.swift | 13 + .../Sources/CallListGroupCallItem.swift | 2 +- .../CallListUI/Sources/CallListHoleItem.swift | 2 +- .../ChatListFilterSettingsHeaderItem.swift | 2 +- submodules/ChatListSearchItemHeader/BUILD | 9 +- .../Sources/ChatListSearchItemHeader.swift | 6 + .../ChatListAdditionalCategoryItem.swift | 2 +- .../Sources/ChatListController.swift | 41 +- .../Sources/ChatListControllerNode.swift | 2 +- .../ChatListFilterPresetCategoryItem.swift | 2 +- .../ChatListFilterPresetListItem.swift | 2 +- ...hatListFilterPresetListSuggestedItem.swift | 2 +- .../ChatListFilterTagSectionHeaderItem.swift | 2 +- .../Sources/ChatListRecentPeersListItem.swift | 2 +- .../Sources/ChatListSearchListPaneNode.swift | 2 +- .../ItemListFilterTitleInputItem.swift | 2 +- .../Node/ChatListArchiveInfoItem.swift | 2 +- .../Node/ChatListEmptyHeaderItem.swift | 2 +- .../Sources/Node/ChatListEmptyInfoItem.swift | 4 +- .../Sources/Node/ChatListHoleItem.swift | 4 +- .../Sources/Node/ChatListItem.swift | 2 +- .../Sources/ContactAddItem.swift | 2 +- .../Sources/ContactListActionItem.swift | 2 +- .../Sources/ContactListNode.swift | 3 - .../Sources/LimitedPermissionItem.swift | 2 +- .../Sources/ContactsPeerItem.swift | 2 +- submodules/Display/Source/ListView.swift | 75 +- .../Display/Source/ListViewItemHeader.swift | 55 +- .../Display/Source/ListViewItemNode.swift | 52 +- submodules/Display/Source/NavigationBar.swift | 2 + .../Display/Source/ViewController.swift | 10 + .../Sources/HashtagSearchController.swift | 2 +- .../Sources/HashtagSearchRecentListNode.swift | 2 +- .../Sources/HorizontalPeerItem.swift | 2 +- .../Sources/AdditionalLinkItem.swift | 2 +- .../Sources/InviteLinkHeaderItem.swift | 2 +- .../Sources/InviteLinkInviteHeaderItem.swift | 2 +- .../Sources/InviteLinkInviteManageItem.swift | 2 +- .../ItemListFolderInviteLinkItem.swift | 2 +- .../ItemListFolderInviteLinkListItem.swift | 2 +- .../ItemListInviteLinkDateLimitItem.swift | 2 +- .../Sources/ItemListInviteLinkItem.swift | 2 +- .../ItemListInviteLinkUsageLimitItem.swift | 2 +- .../Sources/ItemListInviteRequestItem.swift | 2 +- .../ItemListPermanentInviteLinkItem.swift | 2 +- .../Sources/ItemListAddressItem.swift | 2 +- .../Sources/ItemListAvatarAndNameItem.swift | 2 +- .../Sources/ItemListPeerActionItem.swift | 6 +- .../Sources/ItemListPeerItem.swift | 2 +- .../Sources/ItemListStickerPackItem.swift | 2 +- ...ItemListControllerSegmentedTitleView.swift | 2 +- .../Sources/Items/ItemListActionItem.swift | 2 +- .../Items/ItemListActivityTextItem.swift | 2 +- .../Sources/Items/ItemListCheckboxItem.swift | 2 +- .../Items/ItemListDisclosureItem.swift | 2 +- .../Sources/Items/ItemListEditableItem.swift | 4 +- .../Items/ItemListExpandableSwitchItem.swift | 2 +- .../Sources/Items/ItemListInfoItem.swift | 2 +- .../Items/ItemListMultilineInputItem.swift | 2 +- .../Items/ItemListMultilineTextItem.swift | 2 +- .../Items/ItemListPlaceholderItem.swift | 2 +- .../Items/ItemListSectionHeaderItem.swift | 2 +- .../Items/ItemListSingleLineInputItem.swift | 2 +- .../Sources/Items/ItemListSwitchItem.swift | 2 +- .../Sources/Items/ItemListTextItem.swift | 2 +- .../Items/ItemListTextWithLabelItem.swift | 2 +- .../Sources/ItemListVenueItem.swift | 2 +- .../Sources/ListMessageHoleItem.swift | 2 +- .../Sources/ListMessageNode.swift | 2 +- submodules/ListSectionHeaderNode/BUILD | 7 +- .../Sources/ListSectionHeaderNode.swift | 27 +- .../Sources/LocationActionListItem.swift | 2 +- .../Sources/LocationAttributionItem.swift | 2 +- .../Sources/LocationInfoListItem.swift | 2 +- .../Sources/LocationLiveListItem.swift | 2 +- .../Sources/LocationSectionHeaderItem.swift | 2 +- .../Sources/MediaGroupsAlbumGridItem.swift | 4 +- .../Sources/MediaGroupsAlbumItem.swift | 2 +- .../Sources/MediaGroupsHeaderItem.swift | 2 +- .../Sources/AvatarGalleryController.swift | 2 +- ...hannelDiscussionGroupSetupHeaderItem.swift | 2 +- .../PeerInfoUI/Sources/ChatSlowmodeItem.swift | 2 +- .../Sources/ChatUnrestrictBoostersItem.swift | 2 +- .../Sources/ItemListCallListItem.swift | 2 +- .../Sources/ItemListReactionItem.swift | 2 +- .../Sources/ItemListSecretChatKeyItem.swift | 2 +- .../Sources/PeerAutoremoveTimeoutItem.swift | 2 +- .../UserInfoEditingPhoneActionItem.swift | 2 +- .../Sources/UserInfoEditingPhoneItem.swift | 2 +- .../Sources/PeersNearbyHeaderItem.swift | 2 +- .../PremiumUI/Sources/GiftOptionItem.swift | 2 +- .../Sources/IncreaseLimitHeaderItem.swift | 2 +- .../Sources/SubscriptionsCountItem.swift | 2 +- .../Sources/SearchBarPlaceholderNode.swift | 4 +- .../Sources/SectionHeaderItem.swift | 2 +- .../AutodownloadDataUsagePickerItem.swift | 2 +- .../AutodownloadSizeLimitItem.swift | 2 +- .../CalculatingCacheSizeItem.swift | 2 +- .../EnergyUsageBatteryLevelItem.swift | 2 +- .../KeepMediaDurationPickerItem.swift | 2 +- .../MaximumCacheSizePickerItem.swift | 2 +- .../ProxySettingsActionItem.swift | 2 +- .../ProxySettingsServerItem.swift | 2 +- .../Data and Storage/StorageUsageItem.swift | 2 +- .../WebBrowserDomainExceptionItem.swift | 2 +- .../Data and Storage/WebBrowserItem.swift | 2 +- .../Sources/DeleteAccountPeersItem.swift | 2 +- .../Sources/DeleteAccountPhoneItem.swift | 2 +- .../NotificationsCategoryItemListItem.swift | 2 +- .../ForwardPrivacyChatPreviewItem.swift | 2 +- .../GlobalAutoremoveHeaderItem.swift | 2 +- .../ItemListRecentSessionItem.swift | 2 +- .../Recent Sessions/ItemListWebsiteItem.swift | 2 +- .../RecentSessionsHeaderItem.swift | 2 +- .../Search/SettingsSearchRecentItem.swift | 2 +- .../Search/SettingsSearchResultItem.swift | 2 +- .../Text Size/TextSizeSelectionItem.swift | 2 +- .../Sources/ThemePickerGridItem.swift | 2 +- .../Themes/ThemeSettingsAccentColorItem.swift | 6 +- .../Themes/ThemeSettingsAppIconItem.swift | 2 +- .../Themes/ThemeSettingsBrightnessItem.swift | 2 +- .../Themes/ThemeSettingsChatPreviewItem.swift | 2 +- .../Themes/ThemeSettingsFontSizeItem.swift | 2 +- .../Sources/BoostLevelHeaderItem.swift | 2 +- .../StatisticsUI/Sources/BoostsTabsItem.swift | 2 +- .../Sources/MonetizationBalanceItem.swift | 2 +- .../Sources/StarsTransactionItem.swift | 2 +- .../StatisticsUI/Sources/StatsGraphItem.swift | 2 +- .../Sources/StatsMessageItem.swift | 2 +- .../Sources/StatsOverviewItem.swift | 2 +- .../Sources/TelegramBaseController.swift | 879 +----------------- .../Sources/AccountGroupCallContextImpl.swift | 40 + .../Sources/CallStatusBarNode.swift | 16 + .../VideoChatScheduledInfoComponent.swift | 16 + .../Sources/VoiceChatActionItem.swift | 2 +- .../VoiceChatFullscreenParticipantItem.swift | 2 +- .../Sources/VoiceChatMicrophoneNode.swift | 22 +- .../Sources/VoiceChatParticipantItem.swift | 2 +- .../Sources/VoiceChatTileGridNode.swift | 2 +- .../Sources/VoiceChatTimerNode.swift | 16 + submodules/TelegramUI/BUILD | 1 + .../Sources/AnimatedTextComponent.swift | 10 +- .../Sources/AsyncListComponent.swift | 2 +- .../Sources/ChatBotInfoItem.swift | 2 +- .../Sources/ChatMessageDateHeader.swift | 4 +- .../Sources/ChatReplyCountItem.swift | 2 +- .../Sources/ChatUnreadItem.swift | 2 +- .../Sources/ChatMessageItemView.swift | 2 +- .../ChatMessageSelectionInputPanelNode.swift | 10 +- .../Sources/ChatNewThreadInfoItem.swift | 2 +- .../Sources/ChatQrCodeScreen.swift | 2 +- .../Sources/ChatRecentActionsController.swift | 2 +- .../ChatRecentActionsControllerNode.swift | 1 - .../Sources/ChatFloatingTopicsPanel.swift | 18 +- .../Sources/ChatSideTopicsPanel.swift | 12 +- .../ChatTextInputActionButtonsNode.swift | 8 +- .../Sources/ChatTextInputPanelNode.swift | 14 +- .../Sources/ChatUserInfoItem.swift | 2 +- .../Chat/EditableTokenListNode/BUILD | 3 + .../Sources/EditableTokenListNode.swift | 192 ++-- .../Sources/ChatFolderLinkPreviewScreen.swift | 5 +- .../Sources/ChatListNoticeItem.swift | 2 +- .../Sources/ChatListNavigationBar.swift | 12 +- .../Sources/ChatThemeScreen.swift | 2 +- .../Sources/ChatTitleComponent.swift | 27 +- .../ChatTitleView/Sources/ChatTitleView.swift | 32 +- .../Sources/PhoneInputItem.swift | 2 +- .../EdgeEffect/Sources/EdgeEffect.swift | 6 + .../Sources/GiftLoadingShimmerView.swift | 2 +- .../Sources/ChatGiftPreviewItem.swift | 2 +- .../Components/Gifts/GiftStoreScreen/BUILD | 1 + .../Sources/FilterSelectorComponent.swift | 114 +-- .../Sources/GiftStoreScreen.swift | 63 +- .../Sources/GlobalControlPanelsContext.swift | 201 +++- .../GroupCallHeaderPanelComponent/BUILD | 38 + .../GroupCallHeaderPanelComponent.swift | 124 +++ .../GroupCallNavigationAccessoryPanel.swift | 63 +- .../Sources/GroupStickerPackCurrentItem.swift | 2 +- .../Sources/HorizontalTabsComponent.swift | 127 ++- .../Sources/ItemListDatePickerItem.swift | 2 +- .../LiquidLens/Sources/LiquidLensView.swift | 20 +- .../Components/NavigationBarImpl/BUILD | 1 + .../Sources/NavigationBarImpl.swift | 79 +- .../Sources/NavigationButtonNode.swift | 32 +- .../Sources/MessagePriceItem.swift | 2 +- .../Sources/PeerInfoCoverComponent.swift | 12 +- .../Sources/PeerInfoHeaderNode.swift | 44 +- .../Sources/PeerInfoPaneContainerNode.swift | 4 +- .../Sources/PeerInfoScreen.swift | 18 +- .../Sources/PeerInfoStoryGridScreen.swift | 6 +- .../Sources/StorySearchGridScreen.swift | 6 +- .../Sources/PeerNameColorItem.swift | 2 +- .../Sources/EmojiPickerItem.swift | 2 +- .../PeerNameColorChatPreviewItem.swift | 2 +- .../PeerNameColorProfilePreviewItem.swift | 2 +- .../Sources/ItemListReactionItem.swift | 2 +- .../Sources/ReactionChatPreviewItem.swift | 2 +- .../Sources/ThemeCarouselItem.swift | 4 +- .../Sources/ThemeSettingsThemeItem.swift | 4 +- .../Sources/WallpaperPatternPanelNode.swift | 2 +- .../Sources/ThemeGridSearchColorsItem.swift | 2 +- .../Sources/TabBarComponent.swift | 2 +- .../Sources/EditableTokenListNode.swift | 3 - .../Sources/ChatTranslationPanelNode.swift | 25 + .../Chat/ChatControllerLoadDisplayNode.swift | 6 +- .../TelegramUI/Sources/ChatController.swift | 12 +- .../Sources/ChatControllerContentData.swift | 44 +- .../Sources/ChatControllerEditChat.swift | 5 +- .../Sources/ChatControllerNode.swift | 72 +- .../Sources/ChatHistoryListNode.swift | 2 - .../ChatInterfaceInputContextPanels.swift | 29 +- .../ChatRestrictedInputPanelNode.swift | 5 +- .../Sources/ChatTagSearchInputPanelNode.swift | 16 +- .../Sources/CommandChatInputPanelItem.swift | 2 +- .../CommandMenuChatInputPanelItem.swift | 2 +- .../ContactMultiselectionController.swift | 3 +- .../ContactMultiselectionControllerNode.swift | 12 +- .../Sources/EmojisChatInputPanelItem.swift | 2 +- .../Sources/HashtagChatInputPanelItem.swift | 2 +- ...ListContextResultsChatInputPanelItem.swift | 2 +- .../Sources/MentionChatInputPanelItem.swift | 2 +- ...ntextResultsChatInputPanelButtonItem.swift | 2 +- ...ListContextResultsChatInputPanelItem.swift | 2 +- .../Sources/UpdateInfoItem.swift | 2 +- .../Sources/LocalizationListItem.swift | 2 +- .../Sources/WallpaperBackgroundNode.swift | 3 + .../Sources/WebSearchRecentQueryItem.swift | 2 +- .../WebAppMessageChatPreviewItem.swift | 2 +- 234 files changed, 1442 insertions(+), 1764 deletions(-) create mode 100644 submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/BUILD create mode 100644 submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/Sources/GroupCallHeaderPanelComponent.swift rename submodules/{TelegramCallsUI => TelegramUI/Components/GroupCallHeaderPanelComponent}/Sources/GroupCallNavigationAccessoryPanel.swift (95%) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 574ad64059..9d6fd77bec 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -4856,12 +4856,9 @@ Sorry for the inconvenience."; "Conversation.SendMessage.SetReminder" = "Set a Reminder"; -"Conversation.SelectedMessages_1" = "%@ Selected"; -"Conversation.SelectedMessages_2" = "%@ Selected"; -"Conversation.SelectedMessages_3_10" = "%@ Selected"; -"Conversation.SelectedMessages_any" = "%@ Selected"; -"Conversation.SelectedMessages_many" = "%@ Selected"; -"Conversation.SelectedMessages_0" = "%@ Selected"; +"Conversation.SelectedMessagesFormat_1" = "{} Selected"; +"Conversation.SelectedMessagesFormat_any" = "{} Selected"; + "AccentColor.Title" = "Accent Color"; diff --git a/submodules/BotPaymentsUI/Sources/BotCheckoutHeaderItem.swift b/submodules/BotPaymentsUI/Sources/BotCheckoutHeaderItem.swift index c2c4a9c922..84ff228769 100644 --- a/submodules/BotPaymentsUI/Sources/BotCheckoutHeaderItem.swift +++ b/submodules/BotPaymentsUI/Sources/BotCheckoutHeaderItem.swift @@ -114,7 +114,7 @@ class BotCheckoutHeaderItemNode: ListViewItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.imageNode) diff --git a/submodules/BotPaymentsUI/Sources/BotCheckoutPriceItem.swift b/submodules/BotPaymentsUI/Sources/BotCheckoutPriceItem.swift index a88ecb09ed..43c32de55e 100644 --- a/submodules/BotPaymentsUI/Sources/BotCheckoutPriceItem.swift +++ b/submodules/BotPaymentsUI/Sources/BotCheckoutPriceItem.swift @@ -113,7 +113,7 @@ class BotCheckoutPriceItemNode: ListViewItemNode { self.maskNode = ASImageNode() self.maskNode.isUserInteractionEnabled = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.titleNode) diff --git a/submodules/BotPaymentsUI/Sources/BotCheckoutTipItem.swift b/submodules/BotPaymentsUI/Sources/BotCheckoutTipItem.swift index 7989f74465..7b177db972 100644 --- a/submodules/BotPaymentsUI/Sources/BotCheckoutTipItem.swift +++ b/submodules/BotPaymentsUI/Sources/BotCheckoutTipItem.swift @@ -509,7 +509,7 @@ class BotCheckoutTipItemNode: ListViewItemNode, UITextFieldDelegate { self.maskNode = ASImageNode() self.maskNode.isUserInteractionEnabled = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.backgroundNode) diff --git a/submodules/CallListUI/Sources/CallListCallItem.swift b/submodules/CallListUI/Sources/CallListCallItem.swift index 41f076af4d..798ea9b546 100644 --- a/submodules/CallListUI/Sources/CallListCallItem.swift +++ b/submodules/CallListUI/Sources/CallListCallItem.swift @@ -243,7 +243,7 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode { self.accessibilityArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.containerNode) diff --git a/submodules/CallListUI/Sources/CallListController.swift b/submodules/CallListUI/Sources/CallListController.swift index a59541a57f..17435c6665 100644 --- a/submodules/CallListUI/Sources/CallListController.swift +++ b/submodules/CallListUI/Sources/CallListController.swift @@ -103,7 +103,7 @@ public final class CallListController: TelegramBaseController { self.segmentedTitleView = ItemListControllerSegmentedTitleView(theme: self.presentationData.theme, segments: [self.presentationData.strings.Calls_All, self.presentationData.strings.Calls_Missed], selectedIndex: 0) - super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData, style: .glass), mediaAccessoryPanelVisibility: .none, locationBroadcastPanelSource: .none, groupCallPanelSource: .none) + super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData, style: .glass)) self.tabBarItemContextActionType = .always @@ -423,10 +423,15 @@ public final class CallListController: TelegramBaseController { self.displayNodeDidLoad() } + override public var navigationEdgeEffectExtension: CGFloat { + return self.controllerNode.navigationEdgeEffectExtension + } + override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { super.containerLayoutUpdated(layout, transition: transition) - self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition) + let navigationLayout = self.navigationLayout(layout: layout) + self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: navigationLayout.navigationFrame.maxY, transition: transition) } @objc func callPressed() { diff --git a/submodules/CallListUI/Sources/CallListControllerNode.swift b/submodules/CallListUI/Sources/CallListControllerNode.swift index 014cf4c92a..412302fde3 100644 --- a/submodules/CallListUI/Sources/CallListControllerNode.swift +++ b/submodules/CallListUI/Sources/CallListControllerNode.swift @@ -235,6 +235,10 @@ final class CallListControllerNode: ASDisplayNode { private let openGroupCallDisposable = MetaDisposable() + var navigationEdgeEffectExtension: CGFloat { + return max(0.0, self.listNode.edgeEffectExtension) + } + private var previousContentOffset: ListViewVisibleContentOffset? init(controller: CallListController, context: AccountContext, mode: CallListControllerMode, presentationData: PresentationData, call: @escaping (EngineMessage) -> Void, joinGroupCall: @escaping (EnginePeer.Id, EngineGroupCallDescription) -> Void, openInfo: @escaping (EnginePeer.Id, [EngineMessage]) -> Void, emptyStateUpdated: @escaping (Bool) -> Void, openNewCall: @escaping () -> Void) { @@ -682,6 +686,13 @@ final class CallListControllerNode: ASDisplayNode { } } } + + self.listNode.onEdgeEffectExtensionUpdated = { [weak self] transition in + guard let self else { + return + } + self.controller?.updateNavigationEdgeEffectExtension(transition: transition) + } } deinit { @@ -959,5 +970,7 @@ final class CallListControllerNode: ASDisplayNode { let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - edgeEffectHeight), size: CGSize(width: layout.size.width, height: edgeEffectHeight)) transition.updateFrame(view: self.edgeEffectView, frame: edgeEffectFrame) self.edgeEffectView.update(content: self.presentationData.theme.list.plainBackgroundColor, rect: edgeEffectFrame, edge: .bottom, edgeSize: edgeEffectFrame.height, transition: ComponentTransition(transition)) + + self.controller?.updateNavigationEdgeEffectExtension(transition: transition) } } diff --git a/submodules/CallListUI/Sources/CallListGroupCallItem.swift b/submodules/CallListUI/Sources/CallListGroupCallItem.swift index 5875b22936..672b47ba99 100644 --- a/submodules/CallListUI/Sources/CallListGroupCallItem.swift +++ b/submodules/CallListUI/Sources/CallListGroupCallItem.swift @@ -208,7 +208,7 @@ class CallListGroupCallItemNode: ItemListRevealOptionsItemNode { self.accessibilityArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.indicatorNode) diff --git a/submodules/CallListUI/Sources/CallListHoleItem.swift b/submodules/CallListUI/Sources/CallListHoleItem.swift index 1dd52fda6b..bf71192fcd 100644 --- a/submodules/CallListUI/Sources/CallListHoleItem.swift +++ b/submodules/CallListUI/Sources/CallListHoleItem.swift @@ -70,7 +70,7 @@ class CallListHoleItemNode: ListViewItemNode { self.labelNode = TextNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.separatorNode) self.addSubnode(self.labelNode) diff --git a/submodules/ChatListFilterSettingsHeaderItem/Sources/ChatListFilterSettingsHeaderItem.swift b/submodules/ChatListFilterSettingsHeaderItem/Sources/ChatListFilterSettingsHeaderItem.swift index ebe6c50e29..4fc9515ce8 100644 --- a/submodules/ChatListFilterSettingsHeaderItem/Sources/ChatListFilterSettingsHeaderItem.swift +++ b/submodules/ChatListFilterSettingsHeaderItem/Sources/ChatListFilterSettingsHeaderItem.swift @@ -86,7 +86,7 @@ class ChatListFilterSettingsHeaderItemNode: ListViewItemNode { self.animationNode = DefaultAnimatedStickerNodeImpl() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.animationNode) diff --git a/submodules/ChatListSearchItemHeader/BUILD b/submodules/ChatListSearchItemHeader/BUILD index 8154e629b4..288c626e88 100644 --- a/submodules/ChatListSearchItemHeader/BUILD +++ b/submodules/ChatListSearchItemHeader/BUILD @@ -10,9 +10,12 @@ swift_library( "-warnings-as-errors", ], deps = [ - "//submodules/Display:Display", - "//submodules/TelegramPresentationData:TelegramPresentationData", - "//submodules/ListSectionHeaderNode:ListSectionHeaderNode", + "//submodules/Display", + "//submodules/TelegramPresentationData", + "//submodules/ListSectionHeaderNode", + "//submodules/ComponentFlow", + "//submodules/Components/ComponentDisplayAdapters", + "//submodules/TelegramUI/Components/EdgeEffect", ], visibility = [ "//visibility:public", diff --git a/submodules/ChatListSearchItemHeader/Sources/ChatListSearchItemHeader.swift b/submodules/ChatListSearchItemHeader/Sources/ChatListSearchItemHeader.swift index 71b378f3b3..6aa19911c7 100644 --- a/submodules/ChatListSearchItemHeader/Sources/ChatListSearchItemHeader.swift +++ b/submodules/ChatListSearchItemHeader/Sources/ChatListSearchItemHeader.swift @@ -4,6 +4,9 @@ import AsyncDisplayKit import Display import TelegramPresentationData import ListSectionHeaderNode +import EdgeEffect +import ComponentFlow +import ComponentDisplayAdapters public enum ChatListSearchItemHeaderType { case localPeers @@ -250,6 +253,7 @@ public final class ChatListSearchItemHeaderNode: ListViewItemHeaderNode { private var validLayout: (size: CGSize, leftInset: CGFloat, rightInset: CGFloat)? + private var edgeEffectView: EdgeEffectView? private let sectionHeaderNode: ListSectionHeaderNode public init(type: ChatListSearchItemHeaderType, theme: PresentationTheme, strings: PresentationStrings, actionTitle: String?, action: ((ASDisplayNode) -> Void)?) { @@ -263,6 +267,8 @@ public final class ChatListSearchItemHeaderNode: ListViewItemHeaderNode { super.init() + //self.contributesToEdgeEffect = true + self.sectionHeaderNode.title = type.title(strings: strings).uppercased() self.sectionHeaderNode.action = actionTitle self.sectionHeaderNode.activateAction = action diff --git a/submodules/ChatListUI/Sources/ChatListAdditionalCategoryItem.swift b/submodules/ChatListUI/Sources/ChatListAdditionalCategoryItem.swift index a1614b2889..0dd445b2bf 100644 --- a/submodules/ChatListUI/Sources/ChatListAdditionalCategoryItem.swift +++ b/submodules/ChatListUI/Sources/ChatListAdditionalCategoryItem.swift @@ -169,7 +169,7 @@ public class ChatListAdditionalCategoryItemNode: ItemListRevealOptionsItemNode { self.titleNode = TextNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 60884e2102..f10a72fabc 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -60,6 +60,7 @@ import ChatListFilterTabContainerNode import HeaderPanelContainerComponent import HorizontalTabsComponent import GlobalControlPanelsContext +import ChatListFilterTabContainerNode private final class ContextControllerContentSourceImpl: ContextControllerContentSource { let controller: ViewController @@ -248,18 +249,17 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController self.animationCache = context.animationCache self.animationRenderer = context.animationRenderer - let groupCallPanelSource: GroupCallPanelSource + var groupCallPanelSource: EnginePeer.Id? var chatListNotices = false switch self.location { case let .chatList(groupId): - groupCallPanelSource = .all if case .root = groupId { chatListNotices = true } case let .forum(peerId): - groupCallPanelSource = .peer(peerId) + groupCallPanelSource = peerId case .savedMessagesChats: - groupCallPanelSource = .none + break } self.tabsNode = SparseNode() @@ -274,7 +274,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController chatListNotices: chatListNotices ) - super.init(context: context, navigationBarPresentationData: nil, mediaAccessoryPanelVisibility: .none, locationBroadcastPanelSource: .none, groupCallPanelSource: .none) + super.init(context: context, navigationBarPresentationData: nil) self.accessoryPanelContainer = ASDisplayNode() @@ -3660,10 +3660,35 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController return id } } + let _ = defaultFilterIds var reorderedFilterIdsValue: [Int32]? - if let reorderedFilterIds = self.tabContainerNode.reorderedFilterIds, reorderedFilterIds != defaultFilterIds { - reorderedFilterIdsValue = reorderedFilterIds + if let navigationBarView = self.chatListDisplayNode.navigationBarView.view as? ChatListNavigationBar.View, let headerPanelsView = navigationBarView.headerPanels as? HeaderPanelContainerComponent.View, let tabsView = headerPanelsView.tabs as? HorizontalTabsComponent.View, let reorderedItemIds = tabsView.reorderedItemIds { + reorderedFilterIdsValue = reorderedItemIds.compactMap { item -> Int32? in + guard let value = item.base as? Int32 else { + return nil + } + if value == Int32.min { + return 0 + } + return value + } + } + + if let reorderedFilterIdsValue, let tabContainerData = self.tabContainerData { + var entries: [ChatListFilterTabEntry] = [] + for id in reorderedFilterIdsValue { + let mappedId: ChatListFilterTabEntryId + if id == 0 { + mappedId = .all + } else { + mappedId = .filter(id) + } + if let entry = tabContainerData.0.first(where: { $0.id == mappedId }) { + entries.append(entry) + } + } + self.tabContainerData?.0 = entries } let completion = { [weak self] in @@ -7259,7 +7284,7 @@ private final class ChatListLocationContext { dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, displayBackground: false, - content: .custom(presentationData.strings.ChatList_SelectedTopics(Int32(stateAndFilterId.state.selectedThreadIds.count)), nil, false), + content: .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(presentationData.strings.ChatList_SelectedTopics(Int32(stateAndFilterId.state.selectedThreadIds.count))))], subtitle: nil, isEnabled: false), activities: nil, networkState: nil, tapped: { diff --git a/submodules/ChatListUI/Sources/ChatListControllerNode.swift b/submodules/ChatListUI/Sources/ChatListControllerNode.swift index 68d02c1178..cc49fa3346 100644 --- a/submodules/ChatListUI/Sources/ChatListControllerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListControllerNode.swift @@ -21,13 +21,13 @@ import ChatFolderLinkPreviewScreen import ChatListHeaderComponent import StoryPeerListComponent import TelegramNotices -import ChatListFilterTabContainerNode import HeaderPanelContainerComponent import HorizontalTabsComponent import PremiumUI import MediaPlaybackHeaderPanelComponent import LiveLocationHeaderPanelComponent import ChatListHeaderNoticeComponent +import ChatListFilterTabContainerNode public enum ChatListContainerNodeFilter: Equatable { case all diff --git a/submodules/ChatListUI/Sources/ChatListFilterPresetCategoryItem.swift b/submodules/ChatListUI/Sources/ChatListFilterPresetCategoryItem.swift index 24e3612de7..6b75d9a15d 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterPresetCategoryItem.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterPresetCategoryItem.swift @@ -148,7 +148,7 @@ class ChatListFilterPresetCategoryItemNode: ItemListRevealOptionsItemNode, ItemL self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/ChatListUI/Sources/ChatListFilterPresetListItem.swift b/submodules/ChatListUI/Sources/ChatListFilterPresetListItem.swift index 555404425c..84e5395075 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterPresetListItem.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterPresetListItem.swift @@ -201,7 +201,7 @@ final class ChatListFilterPresetListItemNode: ItemListRevealOptionsItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) self.containerNode.addSubnode(self.titleNode.textNode) diff --git a/submodules/ChatListUI/Sources/ChatListFilterPresetListSuggestedItem.swift b/submodules/ChatListUI/Sources/ChatListFilterPresetListSuggestedItem.swift index 34f96f727a..4cce378d6a 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterPresetListSuggestedItem.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterPresetListSuggestedItem.swift @@ -132,7 +132,7 @@ public class ChatListFilterPresetListSuggestedItemNode: ListViewItemNode, ItemLi self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.labelNode) diff --git a/submodules/ChatListUI/Sources/ChatListFilterTagSectionHeaderItem.swift b/submodules/ChatListUI/Sources/ChatListFilterTagSectionHeaderItem.swift index 93438c9af5..3c7fd1fc40 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterTagSectionHeaderItem.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterTagSectionHeaderItem.swift @@ -113,7 +113,7 @@ public class ChatListFilterTagSectionHeaderItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() self.activateArea.accessibilityTraits = [.staticText, .header] - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.accessoryTextNode) diff --git a/submodules/ChatListUI/Sources/ChatListRecentPeersListItem.swift b/submodules/ChatListUI/Sources/ChatListRecentPeersListItem.swift index 5254100773..0cac0a1bff 100644 --- a/submodules/ChatListUI/Sources/ChatListRecentPeersListItem.swift +++ b/submodules/ChatListUI/Sources/ChatListRecentPeersListItem.swift @@ -79,7 +79,7 @@ class ChatListRecentPeersListItemNode: ListViewItemNode { self.separatorNode = ASDisplayNode() self.separatorNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.separatorNode) diff --git a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift index ec0a90bdbc..272247c0bf 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift @@ -5035,7 +5035,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { transition.updateFrame(node: self.mediaAccessoryPanelContainer, frame: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: MediaNavigationAccessoryHeaderNode.minimizedHeight))) let topInset: CGFloat = topInset + topPanelHeight - let overflowInset: CGFloat = 20.0 + let overflowInset: CGFloat = 0.0 let insets = UIEdgeInsets(top: topInset + topPanelHeight, left: sideInset, bottom: bottomInset, right: sideInset) self.shimmerNode.frame = CGRect(origin: CGPoint(x: overflowInset, y: topInset), size: CGSize(width: size.width - overflowInset * 2.0, height: size.height)) diff --git a/submodules/ChatListUI/Sources/ItemListFilterTitleInputItem.swift b/submodules/ChatListUI/Sources/ItemListFilterTitleInputItem.swift index 127a4ae567..2f5e5b51d3 100644 --- a/submodules/ChatListUI/Sources/ItemListFilterTitleInputItem.swift +++ b/submodules/ChatListUI/Sources/ItemListFilterTitleInputItem.swift @@ -126,7 +126,7 @@ public class ItemListFilterTitleInputItemNode: ListViewItemNode, UITextFieldDele self.maskNode = ASImageNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) } override public func didLoad() { diff --git a/submodules/ChatListUI/Sources/Node/ChatListArchiveInfoItem.swift b/submodules/ChatListUI/Sources/Node/ChatListArchiveInfoItem.swift index 4dda5fe57c..411cd295b9 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListArchiveInfoItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListArchiveInfoItem.swift @@ -172,7 +172,7 @@ class ChatListArchiveInfoItemNode: ListViewItemNode, ASScrollViewDelegate { self.infoPageNodes = (0 ..< 3).map({ _ in InfoPageNode() }) self.pageControlNode.pagesCount = self.infoPageNodes.count - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.scrollNode) self.infoPageNodes.forEach(self.scrollNode.addSubnode) diff --git a/submodules/ChatListUI/Sources/Node/ChatListEmptyHeaderItem.swift b/submodules/ChatListUI/Sources/Node/ChatListEmptyHeaderItem.swift index 9edf523d4c..a2b5e4ee7d 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListEmptyHeaderItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListEmptyHeaderItem.swift @@ -55,7 +55,7 @@ class ChatListEmptyHeaderItemNode: ListViewItemNode { private var item: ChatListEmptyHeaderItem? required init() { - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) } override func layoutForParams(_ params: ListViewItemLayoutParams, item: ListViewItem, previousItem: ListViewItem?, nextItem: ListViewItem?) { diff --git a/submodules/ChatListUI/Sources/Node/ChatListEmptyInfoItem.swift b/submodules/ChatListUI/Sources/Node/ChatListEmptyInfoItem.swift index 21363bb4f0..06615f9875 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListEmptyInfoItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListEmptyInfoItem.swift @@ -92,7 +92,7 @@ class ChatListEmptyInfoItemNode: ListViewItemNode { self.animationNode = DefaultAnimatedStickerNodeImpl() self.textNode = TextNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.animationNode) self.addSubnode(self.textNode) @@ -207,7 +207,7 @@ class ChatListSectionHeaderNode: ListViewItemNode { private var headerNode: ListSectionHeaderNode? required init() { - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.zPosition = 1.0 } diff --git a/submodules/ChatListUI/Sources/Node/ChatListHoleItem.swift b/submodules/ChatListUI/Sources/Node/ChatListHoleItem.swift index 1716677a87..324f424570 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListHoleItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListHoleItem.swift @@ -56,7 +56,7 @@ class ChatListHoleItemNode: ListViewItemNode { var relativePosition: (first: Bool, last: Bool) = (false, false) required init() { - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) } override func layoutForParams(_ params: ListViewItemLayoutParams, item: ListViewItem, previousItem: ListViewItem?, nextItem: ListViewItem?) { @@ -153,7 +153,7 @@ class ChatListSearchEmptyFooterItemNode: ListViewItemNode { self.searchAllMessagesTitle = TextNode() self.searchAllMessagesTitle.isUserInteractionEnabled = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.contentNode) self.contentNode.addSubnode(self.titleNode) diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 7072e9109a..92d237d8f2 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -1655,7 +1655,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { self.separatorNode = ASDisplayNode() self.separatorNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/ContactListUI/Sources/ContactAddItem.swift b/submodules/ContactListUI/Sources/ContactAddItem.swift index 22d6856ccb..550001c498 100644 --- a/submodules/ContactListUI/Sources/ContactAddItem.swift +++ b/submodules/ContactListUI/Sources/ContactAddItem.swift @@ -129,7 +129,7 @@ class ContactsAddItemNode: ListViewItemNode { self.iconNode = ASImageNode() self.titleNode = TextNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.separatorNode) diff --git a/submodules/ContactListUI/Sources/ContactListActionItem.swift b/submodules/ContactListUI/Sources/ContactListActionItem.swift index b6dcf22be5..3b25b455dc 100644 --- a/submodules/ContactListUI/Sources/ContactListActionItem.swift +++ b/submodules/ContactListUI/Sources/ContactListActionItem.swift @@ -181,7 +181,7 @@ class ContactListActionItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.iconNode) self.addSubnode(self.titleNode) diff --git a/submodules/ContactListUI/Sources/ContactListNode.swift b/submodules/ContactListUI/Sources/ContactListNode.swift index 90a93477ed..ed179a8210 100644 --- a/submodules/ContactListUI/Sources/ContactListNode.swift +++ b/submodules/ContactListUI/Sources/ContactListNode.swift @@ -1234,7 +1234,6 @@ public final class ContactListNode: ASDisplayNode { self.presentationData = presentationData self.listNode = ListView() - self.listNode.dynamicBounceEnabled = false self.listNode.accessibilityPageScrolledString = { row, count in return presentationData.strings.VoiceOver_ScrollStatus(row, count).string } @@ -2098,8 +2097,6 @@ public final class ContactListNode: ASDisplayNode { strongSelf.authorizationNode.isHidden = authorizationPreviousHidden strongSelf.addSubnode(strongSelf.authorizationNode) - strongSelf.listNode.dynamicBounceEnabled = false - strongSelf.listNode.forEachAccessoryItemNode({ accessoryItemNode in if let accessoryItemNode = accessoryItemNode as? ContactsSectionHeaderAccessoryItemNode { accessoryItemNode.updateTheme(theme: presentationData.theme) diff --git a/submodules/ContactListUI/Sources/LimitedPermissionItem.swift b/submodules/ContactListUI/Sources/LimitedPermissionItem.swift index c9923da2c0..0af140e684 100644 --- a/submodules/ContactListUI/Sources/LimitedPermissionItem.swift +++ b/submodules/ContactListUI/Sources/LimitedPermissionItem.swift @@ -103,7 +103,7 @@ public class LimitedPermissionItemNode: ListViewItemNode { self.actionButtonTitleNode = TextNode() self.actionButtonTitleNode.isUserInteractionEnabled = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.textNode) self.addSubnode(self.activateArea) diff --git a/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift b/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift index 3e446f63dc..0a6b45826f 100644 --- a/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift +++ b/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift @@ -584,7 +584,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode { self.titleNode = TextNode() self.statusNode = TextNodeWithEntities() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/Display/Source/ListView.swift b/submodules/Display/Source/ListView.swift index bf3f593a34..729b32f8f2 100644 --- a/submodules/Display/Source/ListView.swift +++ b/submodules/Display/Source/ListView.swift @@ -210,7 +210,6 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel private final var displayLink: CADisplayLink! private final var needsAnimations = false - public final var dynamicBounceEnabled = true public final var rotated = false public final var experimentalSnapScrollToItem = false public final var useMainQueueTransactions = false @@ -265,6 +264,9 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel public final var addContentOffset: ((CGFloat, ListViewItemNode?) -> Void)? public final var shouldStopScrolling: ((CGFloat) -> Bool)? public final var onContentsUpdated: ((ContainedViewLayoutTransition) -> Void)? + + public private(set) final var edgeEffectExtension: CGFloat = 0.0 + public final var onEdgeEffectExtensionUpdated: ((ContainedViewLayoutTransition) -> Void)? public final var updateScrollingIndicator: ((ScrollingIndicatorState?, ContainedViewLayoutTransition) -> Void)? @@ -1044,41 +1046,10 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel self.enqueueUpdateVisibleItems(synchronous: false) } - var useScrollDynamics = false - - let anchor: CGFloat - if self.isTracking { - anchor = self.touchesPosition.y - } else if deltaY < 0.0 { - anchor = self.visibleSize.height - } else { - anchor = 0.0 - } - self.didScrollWithOffset?(deltaY, .immediate, nil, self.isTrackingOrDecelerating) for itemNode in self.itemNodes { itemNode.updateFrame(itemNode.frame.offsetBy(dx: 0.0, dy: -deltaY), within: self.visibleSize) - - if self.dynamicBounceEnabled && itemNode.wantsScrollDynamics { - useScrollDynamics = true - - var distance: CGFloat - let itemFrame = itemNode.apparentFrame - if anchor < itemFrame.origin.y { - distance = abs(itemFrame.origin.y - anchor) - } else if anchor > itemFrame.origin.y + itemFrame.size.height { - distance = abs(anchor - (itemFrame.origin.y + itemFrame.size.height)) - } else { - distance = 0.0 - } - - let factor: CGFloat = max(0.08, abs(distance) / self.visibleSize.height) - - let resistance: CGFloat = testSpringFreeResistance - - itemNode.addScrollingOffset(deltaY * factor * resistance) - } } if !self.snapToBounds(snapTopItem: false, stackFromBottom: self.stackFromBottom, insetDeltaOffsetFix: 0.0).offset.isZero { @@ -1088,38 +1059,10 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel self.updateItemHeaders(leftInset: self.insets.left, rightInset: self.insets.right, synchronousLoad: false) - for (_, headerNode) in self.itemHeaderNodes { - if self.dynamicBounceEnabled && headerNode.wantsScrollDynamics { - useScrollDynamics = true - - var distance: CGFloat - let itemFrame = headerNode.frame - if anchor < itemFrame.origin.y { - distance = abs(itemFrame.origin.y - anchor) - } else if anchor > itemFrame.origin.y + itemFrame.size.height { - distance = abs(anchor - (itemFrame.origin.y + itemFrame.size.height)) - } else { - distance = 0.0 - } - - let factor: CGFloat = max(0.08, abs(distance) / self.visibleSize.height) - - let resistance: CGFloat = testSpringFreeResistance - - headerNode.addScrollingOffset(deltaY * factor * resistance) - } - } - - if useScrollDynamics { - self.setNeedsAnimations() - } - self.updateVisibleContentOffset() self.updateVisibleItemRange() self.updateItemNodesVisibilities(onlyPositive: false) self.onContentsUpdated?(.immediate) - - //CATransaction.commit() } private func calculateAdditionalTopInverseInset() -> CGFloat { @@ -3914,6 +3857,8 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel let flashing = self.headerItemsAreFlashing() + var maxEdgeEffectExtension: CGFloat = 0.0 + func addHeader(id: VisibleHeaderNodeId, upperBound: CGFloat, upperIndex: Int, upperBoundEdge: CGFloat, lowerBound: CGFloat, lowerIndex: Int, item: ListViewItemHeader, hasValidNodes: Bool) { let itemHeaderHeight: CGFloat = item.height @@ -4096,6 +4041,11 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, distance: stickLocationDistance, transition: .immediate) } + + if headerNode.contributesToEdgeEffect && stickLocationDistance > 0.0 { + maxEdgeEffectExtension = max(maxEdgeEffectExtension, upperDisplayBound + headerFrame.height + 8.0) + } + headerNode.offsetByHeaderNodeId = offsetByHeaderNodeId headerNode.naturalOriginY = naturalY var maxIntersectionHeight: (CGFloat, Int)? @@ -4228,6 +4178,11 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } } } + + if self.edgeEffectExtension != maxEdgeEffectExtension { + self.edgeEffectExtension = maxEdgeEffectExtension + self.onEdgeEffectExtensionUpdated?(transition.0) + } } private func updateItemNodesVisibilities(onlyPositive: Bool) { diff --git a/submodules/Display/Source/ListViewItemHeader.swift b/submodules/Display/Source/ListViewItemHeader.swift index 98a43c73b0..6187c5dd0b 100644 --- a/submodules/Display/Source/ListViewItemHeader.swift +++ b/submodules/Display/Source/ListViewItemHeader.swift @@ -22,13 +22,12 @@ public protocol ListViewItemHeader: AnyObject { } open class ListViewItemHeaderNode: ASDisplayNode { - private final var spring: ListViewItemSpring? - let wantsScrollDynamics: Bool let isRotated: Bool final private(set) var internalStickLocationDistanceFactor: CGFloat = 0.0 final var internalStickLocationDistance: CGFloat = 0.0 private var isFlashingOnScrolling = false weak var attachedToItemNode: ListViewItemNode? + public var contributesToEdgeEffect: Bool = false var offsetByHeaderNodeId: ListViewItemNode.HeaderId? var naturalOriginY: CGFloat? @@ -53,12 +52,8 @@ open class ListViewItemHeaderNode: ASDisplayNode { return self.alpha } - public init(layerBacked: Bool = false, dynamicBounce: Bool = false, isRotated: Bool = false, seeThrough: Bool = false) { - self.wantsScrollDynamics = dynamicBounce + public init(layerBacked: Bool = false, isRotated: Bool = false, seeThrough: Bool = false) { self.isRotated = isRotated - if dynamicBounce { - self.spring = ListViewItemSpring(stiffness: -280.0, damping: -24.0, mass: 0.85) - } super.init() @@ -69,54 +64,10 @@ open class ListViewItemHeaderNode: ASDisplayNode { } final func addScrollingOffset(_ scrollingOffset: CGFloat) { - if self.spring != nil && internalStickLocationDistanceFactor.isZero { - let bounds = self.bounds - self.bounds = CGRect(origin: CGPoint(x: 0.0, y: bounds.origin.y + scrollingOffset), size: bounds.size) - } } public func animate(_ timestamp: Double) -> Bool { - var continueAnimations = false - - if let _ = self.spring { - let bounds = self.bounds - var offset = bounds.origin.y - let currentOffset = offset - - let frictionConstant: CGFloat = testSpringFriction - let springConstant: CGFloat = testSpringConstant - let time: CGFloat = 1.0 / 60.0 - - // friction force = velocity * friction constant - let frictionForce = self.spring!.velocity * frictionConstant - // spring force = (target point - current position) * spring constant - let springForce = -currentOffset * springConstant - // force = spring force - friction force - let force = springForce - frictionForce - - // velocity = current velocity + force * time / mass - self.spring!.velocity = self.spring!.velocity + force * time - // position = current position + velocity * time - offset = currentOffset + self.spring!.velocity * time - - offset = offset.isNaN ? 0.0 : offset - - let epsilon: CGFloat = 0.1 - if abs(offset) < epsilon && abs(self.spring!.velocity) < epsilon { - offset = 0.0 - self.spring!.velocity = 0.0 - } else { - continueAnimations = true - } - - if abs(offset) > 250.0 { - offset = offset < 0.0 ? -250.0 : 250.0 - } - - self.bounds = CGRect(origin: CGPoint(x: 0.0, y: offset), size: bounds.size) - } - - return continueAnimations + return false } open func animateRemoved(duration: Double) { diff --git a/submodules/Display/Source/ListViewItemNode.swift b/submodules/Display/Source/ListViewItemNode.swift index 42c6a99572..360e0791fe 100644 --- a/submodules/Display/Source/ListViewItemNode.swift +++ b/submodules/Display/Source/ListViewItemNode.swift @@ -129,7 +129,6 @@ open class ListViewItemNode: ASDisplayNode, AccessibilityFocusableNode { return nil } - private final var spring: ListViewItemSpring? private final var animations: [(String, ListViewAnimation)] = [] private final var pendingControlledTransitions: [ControlledTransition] = [] private final var controlledTransitions: [ControlledTransitionContext] = [] @@ -142,8 +141,6 @@ open class ListViewItemNode: ASDisplayNode, AccessibilityFocusableNode { open func attachedHeaderNodesUpdated() { } - final let wantsScrollDynamics: Bool - open var preferredAnimationCurve: (CGFloat) -> CGFloat { return listViewAnimationCurveSystem } @@ -236,12 +233,7 @@ open class ListViewItemNode: ASDisplayNode, AccessibilityFocusableNode { return .complete() } - public init(layerBacked: Bool, dynamicBounce: Bool = true, rotated: Bool = false, seeThrough: Bool = false) { - if dynamicBounce { - self.spring = ListViewItemSpring(stiffness: -280.0, damping: -24.0, mass: 0.85) - } - self.wantsScrollDynamics = dynamicBounce - + public init(layerBacked: Bool, rotated: Bool = false, seeThrough: Bool = false) { self.rotated = rotated super.init() @@ -338,56 +330,14 @@ open class ListViewItemNode: ASDisplayNode, AccessibilityFocusableNode { } final func addScrollingOffset(_ scrollingOffset: CGFloat) { - if self.spring != nil { - self.contentOffset += scrollingOffset - } } func initializeDynamicsFromSibling(_ itemView: ListViewItemNode, additionalOffset: CGFloat) { - if let itemViewSpring = itemView.spring { - self.contentOffset = itemView.contentOffset + additionalOffset - self.spring?.velocity = itemViewSpring.velocity - } } public func animate(timestamp: Double, invertOffsetDirection: inout Bool) -> Bool { var continueAnimations = false - if let _ = self.spring { - var offset = self.contentOffset - - let frictionConstant: CGFloat = testSpringFriction - let springConstant: CGFloat = testSpringConstant - let time: CGFloat = 1.0 / 60.0 - - // friction force = velocity * friction constant - let frictionForce = self.spring!.velocity * frictionConstant - // spring force = (target point - current position) * spring constant - let springForce = -self.contentOffset * springConstant - // force = spring force - friction force - let force = springForce - frictionForce - - // velocity = current velocity + force * time / mass - self.spring!.velocity = self.spring!.velocity + force * time - // position = current position + velocity * time - offset = self.contentOffset + self.spring!.velocity * time - - offset = offset.isNaN ? 0.0 : offset - - let epsilon: CGFloat = 0.1 - if abs(offset) < epsilon && abs(self.spring!.velocity) < epsilon { - offset = 0.0 - self.spring!.velocity = 0.0 - } else { - continueAnimations = true - } - - if abs(offset) > 250.0 { - offset = offset < 0.0 ? -250.0 : 250.0 - } - self.contentOffset = offset - } - var i = 0 var animationCount = self.animations.count while i < animationCount { diff --git a/submodules/Display/Source/NavigationBar.swift b/submodules/Display/Source/NavigationBar.swift index 7d1058a123..67ad9cb666 100644 --- a/submodules/Display/Source/NavigationBar.swift +++ b/submodules/Display/Source/NavigationBar.swift @@ -190,6 +190,8 @@ public protocol NavigationBar: ASDisplayNode { var requestContainerLayout: ((ContainedViewLayoutTransition) -> Void)? { get set } func updateLayout(size: CGSize, defaultHeight: CGFloat, additionalTopHeight: CGFloat, additionalContentHeight: CGFloat, additionalBackgroundHeight: CGFloat, additionalCutout: CGSize?, leftInset: CGFloat, rightInset: CGFloat, appearsHidden: Bool, isLandscape: Bool, transition: ContainedViewLayoutTransition) + + func updateEdgeEffectExtension(value: CGFloat, transition: ContainedViewLayoutTransition) } public var defaultNavigationBarImpl: ((NavigationBarPresentationData) -> NavigationBar)? diff --git a/submodules/Display/Source/ViewController.swift b/submodules/Display/Source/ViewController.swift index 32ed5000fa..a1ca25471c 100644 --- a/submodules/Display/Source/ViewController.swift +++ b/submodules/Display/Source/ViewController.swift @@ -249,6 +249,16 @@ public protocol CustomViewControllerNavigationDataSummary: AnyObject { open var interactiveNavivationGestureEdgeWidth: InteractiveTransitionGestureRecognizerEdgeWidth? { return nil } + + open var navigationEdgeEffectExtension: CGFloat { + return 0.0 + } + + public func updateNavigationEdgeEffectExtension(transition: ContainedViewLayoutTransition) { + if let navigationBar = self.navigationBar { + navigationBar.updateEdgeEffectExtension(value: max(0.0, self.navigationEdgeEffectExtension - navigationBar.frame.maxY), transition: transition) + } + } open func navigationLayout(layout: ContainerViewLayout) -> NavigationLayout { let statusBarHeight: CGFloat = layout.statusBarHeight ?? 0.0 diff --git a/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift b/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift index baca0d65aa..bc86c96b6d 100644 --- a/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift +++ b/submodules/HashtagSearchUI/Sources/HashtagSearchController.swift @@ -59,7 +59,7 @@ public final class HashtagSearchController: TelegramBaseController { } self.presentationData = presentationData - super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData, style: .glass), mediaAccessoryPanelVisibility: .specific(size: .compact), locationBroadcastPanelSource: .none, groupCallPanelSource: .none) + super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData, style: .glass)) self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style diff --git a/submodules/HashtagSearchUI/Sources/HashtagSearchRecentListNode.swift b/submodules/HashtagSearchUI/Sources/HashtagSearchRecentListNode.swift index b623808257..d2d29fda92 100644 --- a/submodules/HashtagSearchUI/Sources/HashtagSearchRecentListNode.swift +++ b/submodules/HashtagSearchUI/Sources/HashtagSearchRecentListNode.swift @@ -200,7 +200,7 @@ final class HashtagSearchRecentQueryItemNode: ItemListRevealOptionsItemNode { self.iconNode = ASImageNode() self.iconNode.displaysAsynchronously = false - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.separatorNode) diff --git a/submodules/HorizontalPeerItem/Sources/HorizontalPeerItem.swift b/submodules/HorizontalPeerItem/Sources/HorizontalPeerItem.swift index 0fb1d85b1d..d7c20dfd8e 100644 --- a/submodules/HorizontalPeerItem/Sources/HorizontalPeerItem.swift +++ b/submodules/HorizontalPeerItem/Sources/HorizontalPeerItem.swift @@ -138,7 +138,7 @@ public final class HorizontalPeerItemNode: ListViewItemNode { self.onlineNode = PeerOnlineMarkerNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.peerNode) self.addSubnode(self.badgeBackgroundNode) diff --git a/submodules/InviteLinksUI/Sources/AdditionalLinkItem.swift b/submodules/InviteLinksUI/Sources/AdditionalLinkItem.swift index c66e876ff5..474cded43e 100644 --- a/submodules/InviteLinksUI/Sources/AdditionalLinkItem.swift +++ b/submodules/InviteLinksUI/Sources/AdditionalLinkItem.swift @@ -170,7 +170,7 @@ public class AdditionalLinkItemNode: ListViewItemNode, ItemListItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/InviteLinksUI/Sources/InviteLinkHeaderItem.swift b/submodules/InviteLinksUI/Sources/InviteLinkHeaderItem.swift index d51c7950ae..6cf2608823 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkHeaderItem.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkHeaderItem.swift @@ -94,7 +94,7 @@ class InviteLinkHeaderItemNode: ListViewItemNode { self.animationNode = DefaultAnimatedStickerNodeImpl() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.textNode.textNode) diff --git a/submodules/InviteLinksUI/Sources/InviteLinkInviteHeaderItem.swift b/submodules/InviteLinksUI/Sources/InviteLinkInviteHeaderItem.swift index 22ec323310..733ee8b9cd 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkInviteHeaderItem.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkInviteHeaderItem.swift @@ -86,7 +86,7 @@ class InviteLinkInviteHeaderItemNode: ListViewItemNode { self.iconNode.displaysAsynchronously = false self.iconNode.displayWithoutProcessing = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.textNode) diff --git a/submodules/InviteLinksUI/Sources/InviteLinkInviteManageItem.swift b/submodules/InviteLinksUI/Sources/InviteLinkInviteManageItem.swift index 64b7f3b303..925c645471 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkInviteManageItem.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkInviteManageItem.swift @@ -74,7 +74,7 @@ class InviteLinkInviteManageItemNode: ListViewItemNode { self.backgroundNode = ASDisplayNode() self.buttonNode = HighlightableButtonNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.buttonNode) diff --git a/submodules/InviteLinksUI/Sources/ItemListFolderInviteLinkItem.swift b/submodules/InviteLinksUI/Sources/ItemListFolderInviteLinkItem.swift index 70cdea5871..5382dfed9c 100644 --- a/submodules/InviteLinksUI/Sources/ItemListFolderInviteLinkItem.swift +++ b/submodules/InviteLinksUI/Sources/ItemListFolderInviteLinkItem.swift @@ -203,7 +203,7 @@ public class ItemListFolderInviteLinkItemNode: ListViewItemNode, ItemListItemNod self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.fieldNode) self.addSubnode(self.addressNode) diff --git a/submodules/InviteLinksUI/Sources/ItemListFolderInviteLinkListItem.swift b/submodules/InviteLinksUI/Sources/ItemListFolderInviteLinkListItem.swift index d34dab0625..6ccdd7c2b1 100644 --- a/submodules/InviteLinksUI/Sources/ItemListFolderInviteLinkListItem.swift +++ b/submodules/InviteLinksUI/Sources/ItemListFolderInviteLinkListItem.swift @@ -210,7 +210,7 @@ public class ItemListFolderInviteLinkListItemNode: ItemListRevealOptionsItemNode self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/InviteLinksUI/Sources/ItemListInviteLinkDateLimitItem.swift b/submodules/InviteLinksUI/Sources/ItemListInviteLinkDateLimitItem.swift index f329c40be7..3555521e4e 100644 --- a/submodules/InviteLinksUI/Sources/ItemListInviteLinkDateLimitItem.swift +++ b/submodules/InviteLinksUI/Sources/ItemListInviteLinkDateLimitItem.swift @@ -170,7 +170,7 @@ private final class ItemListInviteLinkTimeLimitItemNode: ListViewItemNode { self.customTextNode.isUserInteractionEnabled = false self.customTextNode.displaysAsynchronously = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.lowTextNode) self.addSubnode(self.mediumTextNode) diff --git a/submodules/InviteLinksUI/Sources/ItemListInviteLinkItem.swift b/submodules/InviteLinksUI/Sources/ItemListInviteLinkItem.swift index d484603045..a00ee4df31 100644 --- a/submodules/InviteLinksUI/Sources/ItemListInviteLinkItem.swift +++ b/submodules/InviteLinksUI/Sources/ItemListInviteLinkItem.swift @@ -235,7 +235,7 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/InviteLinksUI/Sources/ItemListInviteLinkUsageLimitItem.swift b/submodules/InviteLinksUI/Sources/ItemListInviteLinkUsageLimitItem.swift index db379ed7ed..3bc5994529 100644 --- a/submodules/InviteLinksUI/Sources/ItemListInviteLinkUsageLimitItem.swift +++ b/submodules/InviteLinksUI/Sources/ItemListInviteLinkUsageLimitItem.swift @@ -186,7 +186,7 @@ private final class ItemListInviteLinkUsageLimitItemNode: ListViewItemNode { self.customTextNode.isUserInteractionEnabled = false self.customTextNode.displaysAsynchronously = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.lowTextNode) self.addSubnode(self.mediumTextNode) diff --git a/submodules/InviteLinksUI/Sources/ItemListInviteRequestItem.swift b/submodules/InviteLinksUI/Sources/ItemListInviteRequestItem.swift index 5a66bf6edf..a233c6cd79 100644 --- a/submodules/InviteLinksUI/Sources/ItemListInviteRequestItem.swift +++ b/submodules/InviteLinksUI/Sources/ItemListInviteRequestItem.swift @@ -223,7 +223,7 @@ public class ItemListInviteRequestItemNode: ListViewItemNode, ItemListItemNode { self.contentWrapperNode = ASDisplayNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift b/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift index 3d65cc98b5..1761e1f681 100644 --- a/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift +++ b/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift @@ -210,7 +210,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.fieldNode) self.addSubnode(self.addressNode) diff --git a/submodules/ItemListAddressItem/Sources/ItemListAddressItem.swift b/submodules/ItemListAddressItem/Sources/ItemListAddressItem.swift index 595695b61e..b4d71c200a 100644 --- a/submodules/ItemListAddressItem/Sources/ItemListAddressItem.swift +++ b/submodules/ItemListAddressItem/Sources/ItemListAddressItem.swift @@ -142,7 +142,7 @@ public class ItemListAddressItemNode: ListViewItemNode { self.iconNode = ASImageNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.labelNode) self.addSubnode(self.textNode) diff --git a/submodules/ItemListAvatarAndNameInfoItem/Sources/ItemListAvatarAndNameItem.swift b/submodules/ItemListAvatarAndNameInfoItem/Sources/ItemListAvatarAndNameItem.swift index 3e4bece6a9..b2843f1b21 100644 --- a/submodules/ItemListAvatarAndNameInfoItem/Sources/ItemListAvatarAndNameItem.swift +++ b/submodules/ItemListAvatarAndNameInfoItem/Sources/ItemListAvatarAndNameItem.swift @@ -327,7 +327,7 @@ public class ItemListAvatarAndNameInfoItemNode: ListViewItemNode, ItemListItemNo self.callButton = HighlightableButtonNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.isAccessibilityElement = true diff --git a/submodules/ItemListPeerActionItem/Sources/ItemListPeerActionItem.swift b/submodules/ItemListPeerActionItem/Sources/ItemListPeerActionItem.swift index 49b9f75a53..f7329fad2b 100644 --- a/submodules/ItemListPeerActionItem/Sources/ItemListPeerActionItem.swift +++ b/submodules/ItemListPeerActionItem/Sources/ItemListPeerActionItem.swift @@ -160,7 +160,7 @@ public final class ItemListPeerActionItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.iconNode) self.addSubnode(self.titleNode) @@ -262,7 +262,9 @@ public final class ItemListPeerActionItemNode: ListViewItemNode { case .plain: strongSelf.topStripeNode.backgroundColor = item.presentationData.theme.list.itemPlainSeparatorColor strongSelf.bottomStripeNode.backgroundColor = item.presentationData.theme.list.itemPlainSeparatorColor - strongSelf.backgroundNode.backgroundColor = item.presentationData.theme.list.plainBackgroundColor + if !item.alwaysPlain { + strongSelf.backgroundNode.backgroundColor = item.presentationData.theme.list.plainBackgroundColor + } strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor } } diff --git a/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift b/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift index d951750171..036b86ab17 100644 --- a/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift +++ b/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift @@ -855,7 +855,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift b/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift index 81f65a8c0a..149742ffdd 100644 --- a/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift +++ b/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift @@ -263,7 +263,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) diff --git a/submodules/ItemListUI/Sources/ItemListControllerSegmentedTitleView.swift b/submodules/ItemListUI/Sources/ItemListControllerSegmentedTitleView.swift index d70f2e3a47..bce3831599 100644 --- a/submodules/ItemListUI/Sources/ItemListControllerSegmentedTitleView.swift +++ b/submodules/ItemListUI/Sources/ItemListControllerSegmentedTitleView.swift @@ -104,7 +104,7 @@ public final class ItemListControllerSegmentedTitleView: UIView { layout: .fit )), environment: {}, - containerSize: CGSize(width: size.width, height: 40.0) + containerSize: CGSize(width: size.width, height: 44.0) ) let tabSelectorFrame = CGRect(origin: CGPoint(x: floor((size.width - tabSelectorSize.width) / 2.0), y: floor((size.height - tabSelectorSize.height) / 2.0)), size: tabSelectorSize) diff --git a/submodules/ItemListUI/Sources/Items/ItemListActionItem.swift b/submodules/ItemListUI/Sources/Items/ItemListActionItem.swift index a9e6d0dd34..c60eccaeb0 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListActionItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListActionItem.swift @@ -125,7 +125,7 @@ public class ItemListActionItemNode: ListViewItemNode, ItemListItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) diff --git a/submodules/ItemListUI/Sources/Items/ItemListActivityTextItem.swift b/submodules/ItemListUI/Sources/Items/ItemListActivityTextItem.swift index 434b524cf0..9a0a5effd0 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListActivityTextItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListActivityTextItem.swift @@ -85,7 +85,7 @@ public class ItemListActivityTextItemNode: ListViewItemNode { self.activityIndicator = ActivityIndicator(type: ActivityIndicatorType.custom(.black, 16.0, 2.0, false)) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.activityIndicator) diff --git a/submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift b/submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift index 667a471d9d..8743226e96 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift @@ -168,7 +168,7 @@ public class ItemListCheckboxItemNode: ItemListRevealOptionsItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.contentParentNode) self.contentParentNode.addSubnode(self.contentContainerNode) diff --git a/submodules/ItemListUI/Sources/Items/ItemListDisclosureItem.swift b/submodules/ItemListUI/Sources/Items/ItemListDisclosureItem.swift index 7b03132a31..5d518b5f14 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListDisclosureItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListDisclosureItem.swift @@ -254,7 +254,7 @@ public class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode.textNode) self.addSubnode(self.labelNode) diff --git a/submodules/ItemListUI/Sources/Items/ItemListEditableItem.swift b/submodules/ItemListUI/Sources/Items/ItemListEditableItem.swift index 3ba05e2b4c..df2372c151 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListEditableItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListEditableItem.swift @@ -83,8 +83,8 @@ open class ItemListRevealOptionsItemNode: ListViewItemNode, ASGestureRecognizerD return !self.isDisplayingRevealedOptions } - override public init(layerBacked: Bool, dynamicBounce: Bool, rotated: Bool, seeThrough: Bool) { - super.init(layerBacked: layerBacked, dynamicBounce: dynamicBounce, rotated: rotated, seeThrough: seeThrough) + override public init(layerBacked: Bool, rotated: Bool, seeThrough: Bool) { + super.init(layerBacked: layerBacked, rotated: rotated, seeThrough: seeThrough) } open var controlsContainer: ASDisplayNode { diff --git a/submodules/ItemListUI/Sources/Items/ItemListExpandableSwitchItem.swift b/submodules/ItemListUI/Sources/Items/ItemListExpandableSwitchItem.swift index a7f52e9eb4..6f95c58d2c 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListExpandableSwitchItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListExpandableSwitchItem.swift @@ -267,7 +267,7 @@ public class ItemListExpandableSwitchItemNode: ListViewItemNode, ItemListItemNod self.subItemContainer = ASDisplayNode() self.subItemContainer.clipsToBounds = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.titleValueNode) diff --git a/submodules/ItemListUI/Sources/Items/ItemListInfoItem.swift b/submodules/ItemListUI/Sources/Items/ItemListInfoItem.swift index f39f8b3f4f..bf1132496f 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListInfoItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListInfoItem.swift @@ -181,7 +181,7 @@ public class InfoItemNode: ListViewItemNode { self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0) self.closeButton.displaysAsynchronously = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.badgeNode) self.addSubnode(self.labelNode) diff --git a/submodules/ItemListUI/Sources/Items/ItemListMultilineInputItem.swift b/submodules/ItemListUI/Sources/Items/ItemListMultilineInputItem.swift index c2465dec24..e0e98a5c83 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListMultilineInputItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListMultilineInputItem.swift @@ -152,7 +152,7 @@ public class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNod self.limitTextNode = TextNode() self.limitTextNode.displaysAsynchronously = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.textClippingNode.addSubnode(self.textNode) self.addSubnode(self.textClippingNode) diff --git a/submodules/ItemListUI/Sources/Items/ItemListMultilineTextItem.swift b/submodules/ItemListUI/Sources/Items/ItemListMultilineTextItem.swift index fc92b444f0..98865359be 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListMultilineTextItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListMultilineTextItem.swift @@ -127,7 +127,7 @@ public class ItemListMultilineTextItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.textNode) self.addSubnode(self.activateArea) diff --git a/submodules/ItemListUI/Sources/Items/ItemListPlaceholderItem.swift b/submodules/ItemListUI/Sources/Items/ItemListPlaceholderItem.swift index 4a87d0113e..4bbd49de8f 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListPlaceholderItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListPlaceholderItem.swift @@ -93,7 +93,7 @@ public class ItemListPlaceholderItemNode: ListViewItemNode, ItemListItemNode { self.textNode = TextNode() self.textNode.isUserInteractionEnabled = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.textNode) } diff --git a/submodules/ItemListUI/Sources/Items/ItemListSectionHeaderItem.swift b/submodules/ItemListUI/Sources/Items/ItemListSectionHeaderItem.swift index 61c141fdd7..f19047c2ea 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListSectionHeaderItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListSectionHeaderItem.swift @@ -139,7 +139,7 @@ public class ItemListSectionHeaderItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() self.activateArea.accessibilityTraits = [.staticText, .header] - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.accessoryTextNode) diff --git a/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift b/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift index f2bdd08d55..0b012154bb 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift @@ -177,7 +177,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg self.labelNode = TextNode() self.labelNode.isUserInteractionEnabled = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode.textNode) self.addSubnode(self.textNode) diff --git a/submodules/ItemListUI/Sources/Items/ItemListSwitchItem.swift b/submodules/ItemListUI/Sources/Items/ItemListSwitchItem.swift index 18a0027cee..b9d897c106 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListSwitchItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListSwitchItem.swift @@ -207,7 +207,7 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.switchNode) diff --git a/submodules/ItemListUI/Sources/Items/ItemListTextItem.swift b/submodules/ItemListUI/Sources/Items/ItemListTextItem.swift index ad988d9773..5c5c50a27b 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListTextItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListTextItem.swift @@ -132,7 +132,7 @@ public class ItemListTextItemNode: ListViewItemNode, ItemListItemNode { self.activateArea = AccessibilityAreaNode() self.activateArea.accessibilityTraits = .staticText - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.textNode.textNode) self.addSubnode(self.activateArea) diff --git a/submodules/ItemListUI/Sources/Items/ItemListTextWithLabelItem.swift b/submodules/ItemListUI/Sources/Items/ItemListTextWithLabelItem.swift index 2b27d4078f..9e3232df86 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListTextWithLabelItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListTextWithLabelItem.swift @@ -134,7 +134,7 @@ public class ItemListTextWithLabelItemNode: ListViewItemNode { self.textNode.contentMode = .left self.textNode.contentsScale = UIScreen.main.scale - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.isAccessibilityElement = true diff --git a/submodules/ItemListVenueItem/Sources/ItemListVenueItem.swift b/submodules/ItemListVenueItem/Sources/ItemListVenueItem.swift index 0cff7f0ac5..b8492924af 100644 --- a/submodules/ItemListVenueItem/Sources/ItemListVenueItem.swift +++ b/submodules/ItemListVenueItem/Sources/ItemListVenueItem.swift @@ -171,7 +171,7 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/ListMessageItem/Sources/ListMessageHoleItem.swift b/submodules/ListMessageItem/Sources/ListMessageHoleItem.swift index d712fed09a..f4960900a3 100644 --- a/submodules/ListMessageItem/Sources/ListMessageHoleItem.swift +++ b/submodules/ListMessageItem/Sources/ListMessageHoleItem.swift @@ -66,7 +66,7 @@ final class ListMessageHoleItemNode: ListViewItemNode { private var activityIndicator: UIActivityIndicatorView? init() { - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) } override func didLoad() { diff --git a/submodules/ListMessageItem/Sources/ListMessageNode.swift b/submodules/ListMessageItem/Sources/ListMessageNode.swift index af9ba2c767..19d1b2ee17 100644 --- a/submodules/ListMessageItem/Sources/ListMessageNode.swift +++ b/submodules/ListMessageItem/Sources/ListMessageNode.swift @@ -10,7 +10,7 @@ public class ListMessageNode: ListViewItemNode { var interaction: ListMessageItemInteraction? required init() { - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) } func setupItem(_ item: ListMessageItem) { diff --git a/submodules/ListSectionHeaderNode/BUILD b/submodules/ListSectionHeaderNode/BUILD index 38262bee99..11c8ff2cd4 100644 --- a/submodules/ListSectionHeaderNode/BUILD +++ b/submodules/ListSectionHeaderNode/BUILD @@ -10,9 +10,10 @@ swift_library( "-warnings-as-errors", ], deps = [ - "//submodules/AsyncDisplayKit:AsyncDisplayKit", - "//submodules/Display:Display", - "//submodules/TelegramPresentationData:TelegramPresentationData", + "//submodules/AsyncDisplayKit", + "//submodules/Display", + "//submodules/TelegramPresentationData", + "//submodules/ImageBlur", ], visibility = [ "//visibility:public", diff --git a/submodules/ListSectionHeaderNode/Sources/ListSectionHeaderNode.swift b/submodules/ListSectionHeaderNode/Sources/ListSectionHeaderNode.swift index c781d07ffb..072e1e444d 100644 --- a/submodules/ListSectionHeaderNode/Sources/ListSectionHeaderNode.swift +++ b/submodules/ListSectionHeaderNode/Sources/ListSectionHeaderNode.swift @@ -3,6 +3,7 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import ImageBlur private let titleFont = Font.regular(13.0) private let actionFont = Font.regular(13.0) @@ -15,6 +16,7 @@ public enum ListSectionHeaderActionType { public final class ListSectionHeaderNode: ASDisplayNode { private let backgroundLayer: SimpleLayer private let label: ImmediateTextNode + private let labelBackgroundView: UIImageView private var actionButtonLabel: ImmediateTextNode? private var actionButton: HighlightableButtonNode? private var theme: PresentationTheme @@ -89,13 +91,16 @@ public final class ListSectionHeaderNode: ASDisplayNode { self.label.isAccessibilityElement = true self.label.displaysAsynchronously = false + self.labelBackgroundView = UIImageView() + super.init() self.layer.addSublayer(self.backgroundLayer) + self.view.addSubview(self.labelBackgroundView) self.addSubnode(self.label) - self.backgroundLayer.backgroundColor = theme.chatList.sectionHeaderFillColor.cgColor + //self.backgroundLayer.backgroundColor = theme.chatList.sectionHeaderFillColor.cgColor } override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { @@ -135,7 +140,7 @@ public final class ListSectionHeaderNode: ASDisplayNode { if self.theme !== theme { self.theme = theme - self.backgroundLayer.backgroundColor = theme.chatList.sectionHeaderFillColor.cgColor + //self.backgroundLayer.backgroundColor = theme.chatList.sectionHeaderFillColor.cgColor self.label.attributedText = NSAttributedString(string: self.title ?? "", font: titleFont, textColor: self.theme.chatList.sectionHeaderTextColor) @@ -150,7 +155,23 @@ public final class ListSectionHeaderNode: ASDisplayNode { public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, showBackground: Bool = true) { self.validLayout = (size, leftInset, rightInset) let labelSize = self.label.updateLayout(CGSize(width: max(0.0, size.width - leftInset - rightInset - 18.0), height: size.height)) - self.label.frame = CGRect(origin: CGPoint(x: leftInset + 16.0, y: 6.0 + UIScreenPixel), size: CGSize(width: labelSize.width, height: size.height)) + let labelFrame = CGRect(origin: CGPoint(x: leftInset + 16.0, y: 6.0 + UIScreenPixel), size: CGSize(width: labelSize.width, height: labelSize.height)) + self.label.frame = labelFrame + + let labelBackgroundSize: CGFloat = labelSize.height + let labelBackgroundInnerInset: CGFloat = 6.0 + let labelBackgroundInset: CGFloat = 10.0 + labelBackgroundInnerInset + if self.labelBackgroundView.image?.size.width != labelBackgroundSize + labelBackgroundInset * 2.0 { + self.labelBackgroundView.image = blurredImage(generateImage(CGSize(width: labelBackgroundSize + labelBackgroundInset * 2.0, height: labelBackgroundSize + labelBackgroundInset * 2.0), rotatedContext: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + context.setFillColor(UIColor.white.cgColor) + context.fillEllipse(in: CGRect(origin: CGPoint(x: labelBackgroundInset - labelBackgroundInnerInset, y: labelBackgroundInset - labelBackgroundInnerInset), size: CGSize(width: labelBackgroundSize + labelBackgroundInnerInset * 2.0, height: labelBackgroundSize + labelBackgroundInnerInset * 2.0))) + })!, radius: 19, iterations: 3)?.stretchableImage(withLeftCapWidth: Int(labelBackgroundInset + labelBackgroundSize * 0.5), topCapHeight: Int(labelBackgroundInset + labelBackgroundSize * 0.5)).withRenderingMode(.alwaysTemplate) + } + self.labelBackgroundView.tintColor = self.theme.list.plainBackgroundColor.withAlphaComponent(0.5) + //self.labelBackgroundView.tintColor = UIColor.blue.withMultipliedAlpha(0.8) + + self.labelBackgroundView.frame = labelFrame.insetBy(dx: -labelBackgroundInset - 4.0, dy: -labelBackgroundInset) if let actionButton = self.actionButton, let actionButtonLabel = self.actionButtonLabel { let buttonSize = actionButtonLabel.updateLayout(CGSize(width: size.width, height: size.height)) diff --git a/submodules/LocationUI/Sources/LocationActionListItem.swift b/submodules/LocationUI/Sources/LocationActionListItem.swift index e84192d11b..ea37651e03 100644 --- a/submodules/LocationUI/Sources/LocationActionListItem.swift +++ b/submodules/LocationUI/Sources/LocationActionListItem.swift @@ -224,7 +224,7 @@ final class LocationActionListItemNode: ListViewItemNode { self.venueIconNode = TransformImageNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.separatorNode) diff --git a/submodules/LocationUI/Sources/LocationAttributionItem.swift b/submodules/LocationUI/Sources/LocationAttributionItem.swift index d090c91b04..b38b7e900a 100644 --- a/submodules/LocationUI/Sources/LocationAttributionItem.swift +++ b/submodules/LocationUI/Sources/LocationAttributionItem.swift @@ -65,7 +65,7 @@ private class LocationAttributionItemNode: ListViewItemNode { self.imageNode.displaysAsynchronously = false self.imageNode.displayWithoutProcessing = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.imageNode) } diff --git a/submodules/LocationUI/Sources/LocationInfoListItem.swift b/submodules/LocationUI/Sources/LocationInfoListItem.swift index 4c3bca6ec8..fda4a00e51 100644 --- a/submodules/LocationUI/Sources/LocationInfoListItem.swift +++ b/submodules/LocationUI/Sources/LocationInfoListItem.swift @@ -98,7 +98,7 @@ public final class LocationInfoListItemNode: ListViewItemNode { self.venueIconNode = TransformImageNode() self.venueIconNode.isUserInteractionEnabled = false - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.buttonNode) diff --git a/submodules/LocationUI/Sources/LocationLiveListItem.swift b/submodules/LocationUI/Sources/LocationLiveListItem.swift index 7df3350349..5aaaf511fc 100644 --- a/submodules/LocationUI/Sources/LocationLiveListItem.swift +++ b/submodules/LocationUI/Sources/LocationLiveListItem.swift @@ -119,7 +119,7 @@ final class LocationLiveListItemNode: ListViewItemNode { self.avatarNode = AvatarNode(font: avatarFont) self.avatarNode.isLayerBacked = !smartInvertColorsEnabled() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.separatorNode) diff --git a/submodules/LocationUI/Sources/LocationSectionHeaderItem.swift b/submodules/LocationUI/Sources/LocationSectionHeaderItem.swift index 42f8bd296a..3aeae080a6 100644 --- a/submodules/LocationUI/Sources/LocationSectionHeaderItem.swift +++ b/submodules/LocationUI/Sources/LocationSectionHeaderItem.swift @@ -58,7 +58,7 @@ private class LocationSectionHeaderItemNode: ListViewItemNode { private var layoutParams: ListViewItemLayoutParams? required init() { - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) } override func layoutForParams(_ params: ListViewItemLayoutParams, item: ListViewItem, previousItem: ListViewItem?, nextItem: ListViewItem?) { diff --git a/submodules/MediaPickerUI/Sources/MediaGroupsAlbumGridItem.swift b/submodules/MediaPickerUI/Sources/MediaGroupsAlbumGridItem.swift index 0f9a47637b..dfeba38478 100644 --- a/submodules/MediaPickerUI/Sources/MediaGroupsAlbumGridItem.swift +++ b/submodules/MediaPickerUI/Sources/MediaGroupsAlbumGridItem.swift @@ -130,7 +130,7 @@ private final class MediaGroupsGridAlbumItemNode : ListViewItemNode { self.countNode = TextNode() self.countNode.isUserInteractionEnabled = false - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) self.containerNode.addSubnode(self.imageNode) @@ -283,7 +283,7 @@ private class MediaGroupsAlbumGridItemNode: ListViewItemNode { self.listNode = ListView() self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.listNode) } diff --git a/submodules/MediaPickerUI/Sources/MediaGroupsAlbumItem.swift b/submodules/MediaPickerUI/Sources/MediaGroupsAlbumItem.swift index 7cc617796c..d086a03832 100644 --- a/submodules/MediaPickerUI/Sources/MediaGroupsAlbumItem.swift +++ b/submodules/MediaPickerUI/Sources/MediaGroupsAlbumItem.swift @@ -172,7 +172,7 @@ class MediaGroupsAlbumItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.iconNode) self.addSubnode(self.titleNode) diff --git a/submodules/MediaPickerUI/Sources/MediaGroupsHeaderItem.swift b/submodules/MediaPickerUI/Sources/MediaGroupsHeaderItem.swift index b934d07d5a..409f895d1f 100644 --- a/submodules/MediaPickerUI/Sources/MediaGroupsHeaderItem.swift +++ b/submodules/MediaPickerUI/Sources/MediaGroupsHeaderItem.swift @@ -59,7 +59,7 @@ private class MediaGroupsHeaderItemNode: ListViewItemNode { init() { self.titleNode = TextNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.titleNode) } diff --git a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift index 9cf2bfb8b4..72931c6586 100644 --- a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift +++ b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift @@ -754,7 +754,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr self.galleryNode.setControlsHidden(true, animated: false) if let centralItemNode = self.galleryNode.pager.centralItemNode(), let itemSize = centralItemNode.contentSize() { self.preferredContentSize = itemSize.aspectFitted(self.view.bounds.size) - self.containerLayoutUpdated(ContainerViewLayout(size: self.preferredContentSize, metrics: LayoutMetrics(), deviceMetrics: layout.deviceMetrics, intrinsicInsets: UIEdgeInsets(), safeInsets: UIEdgeInsets(), additionalInsets: UIEdgeInsets(), statusBarHeight: nil, inputHeight: nil, inputHeightIsInteractivellyChanging: false, inVoiceOver: false), transition: .immediate) + self.containerLayoutUpdated(ContainerViewLayout(size: self.preferredContentSize, metrics: LayoutMetrics(), deviceMetrics: layout.deviceMetrics, intrinsicInsets: UIEdgeInsets(), safeInsets: UIEdgeInsets(), additionalInsets: UIEdgeInsets(), statusBarHeight: nil, inputHeight: nil, inputHeightIsInteractivellyChanging: false, inVoiceOver: false), transition: .immediate) centralItemNode.activateAsInitial() } } diff --git a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupHeaderItem.swift b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupHeaderItem.swift index 9a87b6001f..e98240c8f6 100644 --- a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupHeaderItem.swift +++ b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupHeaderItem.swift @@ -90,7 +90,7 @@ class ChannelDiscussionGroupSetupHeaderItemNode: ListViewItemNode { self.labelNode.contentMode = .left self.labelNode.contentsScale = UIScreen.main.scale - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.imageNode) self.addSubnode(self.titleNode) diff --git a/submodules/PeerInfoUI/Sources/ChatSlowmodeItem.swift b/submodules/PeerInfoUI/Sources/ChatSlowmodeItem.swift index 781c3eec41..f87a8316e2 100644 --- a/submodules/PeerInfoUI/Sources/ChatSlowmodeItem.swift +++ b/submodules/PeerInfoUI/Sources/ChatSlowmodeItem.swift @@ -95,7 +95,7 @@ class ChatSlowmodeItemNode: ListViewItemNode { return textNode } - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.textNodes.forEach(self.addSubnode) } diff --git a/submodules/PeerInfoUI/Sources/ChatUnrestrictBoostersItem.swift b/submodules/PeerInfoUI/Sources/ChatUnrestrictBoostersItem.swift index baa545c79c..4817be5eac 100644 --- a/submodules/PeerInfoUI/Sources/ChatUnrestrictBoostersItem.swift +++ b/submodules/PeerInfoUI/Sources/ChatUnrestrictBoostersItem.swift @@ -103,7 +103,7 @@ class ChatUnrestrictBoostersItemNode: ListViewItemNode { return textNode } - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.iconNodes.forEach(self.addSubnode) self.textNodes.forEach(self.addSubnode) diff --git a/submodules/PeerInfoUI/Sources/ItemListCallListItem.swift b/submodules/PeerInfoUI/Sources/ItemListCallListItem.swift index 23bb4f30d1..cfd32b4a21 100644 --- a/submodules/PeerInfoUI/Sources/ItemListCallListItem.swift +++ b/submodules/PeerInfoUI/Sources/ItemListCallListItem.swift @@ -174,7 +174,7 @@ public class ItemListCallListItemNode: ListViewItemNode { self.accessibilityArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.accessibilityArea) diff --git a/submodules/PeerInfoUI/Sources/ItemListReactionItem.swift b/submodules/PeerInfoUI/Sources/ItemListReactionItem.swift index e1e2d04c61..64133463f7 100644 --- a/submodules/PeerInfoUI/Sources/ItemListReactionItem.swift +++ b/submodules/PeerInfoUI/Sources/ItemListReactionItem.swift @@ -168,7 +168,7 @@ public class ItemListReactionItemNode: ListViewItemNode, ItemListItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.switchNode) diff --git a/submodules/PeerInfoUI/Sources/ItemListSecretChatKeyItem.swift b/submodules/PeerInfoUI/Sources/ItemListSecretChatKeyItem.swift index a9824f78fd..4d3b36341d 100644 --- a/submodules/PeerInfoUI/Sources/ItemListSecretChatKeyItem.swift +++ b/submodules/PeerInfoUI/Sources/ItemListSecretChatKeyItem.swift @@ -123,7 +123,7 @@ class ItemListSecretChatKeyItemNode: ListViewItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.keyNode) diff --git a/submodules/PeerInfoUI/Sources/PeerAutoremoveTimeoutItem.swift b/submodules/PeerInfoUI/Sources/PeerAutoremoveTimeoutItem.swift index f45479be7b..b0a2827bab 100644 --- a/submodules/PeerInfoUI/Sources/PeerAutoremoveTimeoutItem.swift +++ b/submodules/PeerInfoUI/Sources/PeerAutoremoveTimeoutItem.swift @@ -125,7 +125,7 @@ class PeerRemoveTimeoutItemNode: ListViewItemNode, ItemListItemNode { return TextNode() } - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.titleNodes.forEach(self.addSubnode) diff --git a/submodules/PeerInfoUI/Sources/UserInfoEditingPhoneActionItem.swift b/submodules/PeerInfoUI/Sources/UserInfoEditingPhoneActionItem.swift index 4fe64adbab..ba29224332 100644 --- a/submodules/PeerInfoUI/Sources/UserInfoEditingPhoneActionItem.swift +++ b/submodules/PeerInfoUI/Sources/UserInfoEditingPhoneActionItem.swift @@ -100,7 +100,7 @@ class UserInfoEditingPhoneActionItemNode: ListViewItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.iconNode) self.addSubnode(self.titleNode) diff --git a/submodules/PeerInfoUI/Sources/UserInfoEditingPhoneItem.swift b/submodules/PeerInfoUI/Sources/UserInfoEditingPhoneItem.swift index 409db1eb16..c3ff6f4c80 100644 --- a/submodules/PeerInfoUI/Sources/UserInfoEditingPhoneItem.swift +++ b/submodules/PeerInfoUI/Sources/UserInfoEditingPhoneItem.swift @@ -131,7 +131,7 @@ class UserInfoEditingPhoneItemNode: ItemListRevealOptionsItemNode, ItemListItemN self.clearButton.displaysAsynchronously = false self.clearButton.isHidden = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.editableControlNode) self.addSubnode(self.labelNode) diff --git a/submodules/PeersNearbyUI/Sources/PeersNearbyHeaderItem.swift b/submodules/PeersNearbyUI/Sources/PeersNearbyHeaderItem.swift index 57f756bf39..e1b70cb30c 100644 --- a/submodules/PeersNearbyUI/Sources/PeersNearbyHeaderItem.swift +++ b/submodules/PeersNearbyUI/Sources/PeersNearbyHeaderItem.swift @@ -76,7 +76,7 @@ class PeersNearbyHeaderItemNode: ListViewItemNode { self.animationNode = DefaultAnimatedStickerNodeImpl() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.animationNode) diff --git a/submodules/PremiumUI/Sources/GiftOptionItem.swift b/submodules/PremiumUI/Sources/GiftOptionItem.swift index 12166ff4b9..eac888a1f6 100644 --- a/submodules/PremiumUI/Sources/GiftOptionItem.swift +++ b/submodules/PremiumUI/Sources/GiftOptionItem.swift @@ -212,7 +212,7 @@ class GiftOptionItemNode: ItemListRevealOptionsItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) diff --git a/submodules/PremiumUI/Sources/IncreaseLimitHeaderItem.swift b/submodules/PremiumUI/Sources/IncreaseLimitHeaderItem.swift index f203973b74..14600adfa2 100644 --- a/submodules/PremiumUI/Sources/IncreaseLimitHeaderItem.swift +++ b/submodules/PremiumUI/Sources/IncreaseLimitHeaderItem.swift @@ -99,7 +99,7 @@ class IncreaseLimitHeaderItemNode: ListViewItemNode { self.textNode.contentMode = .left self.textNode.contentsScale = UIScreen.main.scale - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.textNode) diff --git a/submodules/PremiumUI/Sources/SubscriptionsCountItem.swift b/submodules/PremiumUI/Sources/SubscriptionsCountItem.swift index 6fecfbfbe1..861c43d7e7 100644 --- a/submodules/PremiumUI/Sources/SubscriptionsCountItem.swift +++ b/submodules/PremiumUI/Sources/SubscriptionsCountItem.swift @@ -91,7 +91,7 @@ private final class SubscriptionsCountItemNode: ListViewItemNode { return textNode } - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.textNodes.forEach(self.addSubnode) } diff --git a/submodules/SearchBarNode/Sources/SearchBarPlaceholderNode.swift b/submodules/SearchBarNode/Sources/SearchBarPlaceholderNode.swift index fdf652338b..59f12feab3 100644 --- a/submodules/SearchBarNode/Sources/SearchBarPlaceholderNode.swift +++ b/submodules/SearchBarNode/Sources/SearchBarPlaceholderNode.swift @@ -304,7 +304,9 @@ public final class SearchBarPlaceholderContentView: UIView { } ComponentTransition(transition).setAlpha(view: glassBackgroundView, alpha: backgroundAlpha) let isDark = params.backgroundColor.hsb.b < 0.5 - glassBackgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.height * 0.5, isDark: isDark, tintColor: .init(kind: .panel, color: UIColor(white: isDark ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, transition: ComponentTransition(transition)) + if params.isActive { + glassBackgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.height * 0.5, isDark: isDark, tintColor: .init(kind: .panel, color: UIColor(white: isDark ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, transition: ComponentTransition(transition)) + } if params.isActive { let transition = ComponentTransition(transition) diff --git a/submodules/SectionHeaderItem/Sources/SectionHeaderItem.swift b/submodules/SectionHeaderItem/Sources/SectionHeaderItem.swift index 37a1f4f925..2a5f15e603 100644 --- a/submodules/SectionHeaderItem/Sources/SectionHeaderItem.swift +++ b/submodules/SectionHeaderItem/Sources/SectionHeaderItem.swift @@ -73,7 +73,7 @@ private class SectionHeaderItemNode: ListViewItemNode { private var layoutParams: ListViewItemLayoutParams? required init() { - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) } override func layoutForParams(_ params: ListViewItemLayoutParams, item: ListViewItem, previousItem: ListViewItem?, nextItem: ListViewItem?) { diff --git a/submodules/SettingsUI/Sources/Data and Storage/AutodownloadDataUsagePickerItem.swift b/submodules/SettingsUI/Sources/Data and Storage/AutodownloadDataUsagePickerItem.swift index 735565cf31..acb2d8f720 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/AutodownloadDataUsagePickerItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/AutodownloadDataUsagePickerItem.swift @@ -133,7 +133,7 @@ private final class AutodownloadDataUsagePickerItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.lowTextNode) self.addSubnode(self.mediumTextNode) diff --git a/submodules/SettingsUI/Sources/Data and Storage/AutodownloadSizeLimitItem.swift b/submodules/SettingsUI/Sources/Data and Storage/AutodownloadSizeLimitItem.swift index affc44c9a6..280d73655c 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/AutodownloadSizeLimitItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/AutodownloadSizeLimitItem.swift @@ -143,7 +143,7 @@ private final class AutodownloadSizeLimitItemNode: ListViewItemNode { self.maxTextNode.isUserInteractionEnabled = false self.maxTextNode.displaysAsynchronously = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.textNode) self.addSubnode(self.minTextNode) diff --git a/submodules/SettingsUI/Sources/Data and Storage/CalculatingCacheSizeItem.swift b/submodules/SettingsUI/Sources/Data and Storage/CalculatingCacheSizeItem.swift index 2d6531d397..2f86442bfa 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/CalculatingCacheSizeItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/CalculatingCacheSizeItem.swift @@ -90,7 +90,7 @@ private final class CalculatingCacheSizeItemNode: ListViewItemNode { self.titleNode.contentMode = .left self.titleNode.contentsScale = UIScreen.main.scale - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) } diff --git a/submodules/SettingsUI/Sources/Data and Storage/EnergyUsageBatteryLevelItem.swift b/submodules/SettingsUI/Sources/Data and Storage/EnergyUsageBatteryLevelItem.swift index 84ce6fb2ae..831492c293 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/EnergyUsageBatteryLevelItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/EnergyUsageBatteryLevelItem.swift @@ -112,7 +112,7 @@ class EnergyUsageBatteryLevelItemNode: ListViewItemNode { self.batteryBackgroundNode = ASImageNode() self.batteryForegroundNode = ASImageNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.leftTextNode) self.addSubnode(self.rightTextNode) diff --git a/submodules/SettingsUI/Sources/Data and Storage/KeepMediaDurationPickerItem.swift b/submodules/SettingsUI/Sources/Data and Storage/KeepMediaDurationPickerItem.swift index 69cf788465..a62039c1db 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/KeepMediaDurationPickerItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/KeepMediaDurationPickerItem.swift @@ -107,7 +107,7 @@ private final class KeepMediaDurationPickerItemNode: ListViewItemNode { } self.textNodes = textNodes - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) for textNode in textNodes { self.addSubnode(textNode) diff --git a/submodules/SettingsUI/Sources/Data and Storage/MaximumCacheSizePickerItem.swift b/submodules/SettingsUI/Sources/Data and Storage/MaximumCacheSizePickerItem.swift index 6d6d7257d9..25c1db6d9a 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/MaximumCacheSizePickerItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/MaximumCacheSizePickerItem.swift @@ -122,7 +122,7 @@ private final class MaximumCacheSizePickerItemNode: ListViewItemNode { } self.textNodes = textNodes - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) for textNode in textNodes { self.addSubnode(textNode) diff --git a/submodules/SettingsUI/Sources/Data and Storage/ProxySettingsActionItem.swift b/submodules/SettingsUI/Sources/Data and Storage/ProxySettingsActionItem.swift index 6b3e78494f..e1f086abab 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/ProxySettingsActionItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/ProxySettingsActionItem.swift @@ -114,7 +114,7 @@ private final class ProxySettingsActionItemNode: ListViewItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.isAccessibilityElement = true diff --git a/submodules/SettingsUI/Sources/Data and Storage/ProxySettingsServerItem.swift b/submodules/SettingsUI/Sources/Data and Storage/ProxySettingsServerItem.swift index da7512ddab..3108d64985 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/ProxySettingsServerItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/ProxySettingsServerItem.swift @@ -174,7 +174,7 @@ private final class ProxySettingsServerItemNode: ItemListRevealOptionsItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.titleNode) self.addSubnode(self.statusNode) diff --git a/submodules/SettingsUI/Sources/Data and Storage/StorageUsageItem.swift b/submodules/SettingsUI/Sources/Data and Storage/StorageUsageItem.swift index e50a2c31c3..7a085e607f 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/StorageUsageItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/StorageUsageItem.swift @@ -119,7 +119,7 @@ private final class StorageUsageItemNode: ListViewItemNode { self.lineNodes = [] self.descriptionNodes = [] - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.lineMaskNode) } diff --git a/submodules/SettingsUI/Sources/Data and Storage/WebBrowserDomainExceptionItem.swift b/submodules/SettingsUI/Sources/Data and Storage/WebBrowserDomainExceptionItem.swift index 2ba7108446..29197201c1 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/WebBrowserDomainExceptionItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/WebBrowserDomainExceptionItem.swift @@ -132,7 +132,7 @@ final class WebBrowserDomainExceptionItemNode: ItemListRevealOptionsItemNode, It self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.iconNode) self.addSubnode(self.titleNode) diff --git a/submodules/SettingsUI/Sources/Data and Storage/WebBrowserItem.swift b/submodules/SettingsUI/Sources/Data and Storage/WebBrowserItem.swift index 410254c412..ecaa103547 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/WebBrowserItem.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/WebBrowserItem.swift @@ -117,7 +117,7 @@ private final class WebBrowserItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.iconNode) self.addSubnode(self.checkIconNode) diff --git a/submodules/SettingsUI/Sources/DeleteAccountPeersItem.swift b/submodules/SettingsUI/Sources/DeleteAccountPeersItem.swift index 0e7581bdbf..1ce362fcd1 100644 --- a/submodules/SettingsUI/Sources/DeleteAccountPeersItem.swift +++ b/submodules/SettingsUI/Sources/DeleteAccountPeersItem.swift @@ -169,7 +169,7 @@ class DeleteAccountPeersItemNode: ListViewItemNode, ItemListItemNode { self.listView = ListView() self.listView.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.listView) diff --git a/submodules/SettingsUI/Sources/DeleteAccountPhoneItem.swift b/submodules/SettingsUI/Sources/DeleteAccountPhoneItem.swift index 11c8ad4905..396d658358 100644 --- a/submodules/SettingsUI/Sources/DeleteAccountPhoneItem.swift +++ b/submodules/SettingsUI/Sources/DeleteAccountPhoneItem.swift @@ -167,7 +167,7 @@ final class DeleteAccountPhoneItemNode: ListViewItemNode, ItemListItemNode { self.phoneInputNode = PhoneInputNode(fontSize: 17.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.phoneBackground) self.addSubnode(self.countryButton) diff --git a/submodules/SettingsUI/Sources/Notifications/NotificationsCategoryItemListItem.swift b/submodules/SettingsUI/Sources/Notifications/NotificationsCategoryItemListItem.swift index 9e0f727d66..a63e4174c8 100644 --- a/submodules/SettingsUI/Sources/Notifications/NotificationsCategoryItemListItem.swift +++ b/submodules/SettingsUI/Sources/Notifications/NotificationsCategoryItemListItem.swift @@ -148,7 +148,7 @@ public class NotificationsCategoryItemListItemNode: ListViewItemNode, ItemListIt self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.subtitleNode) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift b/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift index f522f3826f..d7bb50ba39 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift @@ -115,7 +115,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode { self.measureTextNode = TextNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.clipsToBounds = true diff --git a/submodules/SettingsUI/Sources/Privacy and Security/GlobalAutoremoveHeaderItem.swift b/submodules/SettingsUI/Sources/Privacy and Security/GlobalAutoremoveHeaderItem.swift index 585f1d766d..5eda7838cd 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/GlobalAutoremoveHeaderItem.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/GlobalAutoremoveHeaderItem.swift @@ -68,7 +68,7 @@ class GlobalAutoremoveHeaderItemNode: ListViewItemNode { init() { self.animationNode = DefaultAnimatedStickerNodeImpl() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.animationNode) } diff --git a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/ItemListRecentSessionItem.swift b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/ItemListRecentSessionItem.swift index 77684f5bc9..a872ae6a19 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/ItemListRecentSessionItem.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/ItemListRecentSessionItem.swift @@ -241,7 +241,7 @@ class ItemListRecentSessionItemNode: ItemListRevealOptionsItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) self.containerNode.addSubnode(self.iconNode) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/ItemListWebsiteItem.swift b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/ItemListWebsiteItem.swift index cd902c96f8..1dc5be3814 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/ItemListWebsiteItem.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/ItemListWebsiteItem.swift @@ -190,7 +190,7 @@ class ItemListWebsiteItemNode: ItemListRevealOptionsItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) self.containerNode.addSubnode(self.avatarNode) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsHeaderItem.swift b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsHeaderItem.swift index 2bd1a4d163..0b9dab7e70 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsHeaderItem.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsHeaderItem.swift @@ -92,7 +92,7 @@ class RecentSessionsHeaderItemNode: ListViewItemNode { self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), fontSize: 16.0, height: 50.0, cornerRadius: 11.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.addSubnode(self.animationNode) diff --git a/submodules/SettingsUI/Sources/Search/SettingsSearchRecentItem.swift b/submodules/SettingsUI/Sources/Search/SettingsSearchRecentItem.swift index 10f315d55b..f2863b3b75 100644 --- a/submodules/SettingsUI/Sources/Search/SettingsSearchRecentItem.swift +++ b/submodules/SettingsUI/Sources/Search/SettingsSearchRecentItem.swift @@ -127,7 +127,7 @@ class SettingsSearchRecentItemNode: ItemListRevealOptionsItemNode { self.subtitleNode.contentMode = .left self.subtitleNode.contentsScale = UIScreenScale - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.separatorNode) diff --git a/submodules/SettingsUI/Sources/Search/SettingsSearchResultItem.swift b/submodules/SettingsUI/Sources/Search/SettingsSearchResultItem.swift index 7e73002311..c04b38af70 100644 --- a/submodules/SettingsUI/Sources/Search/SettingsSearchResultItem.swift +++ b/submodules/SettingsUI/Sources/Search/SettingsSearchResultItem.swift @@ -117,7 +117,7 @@ class SettingsSearchResultItemNode: ListViewItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.iconNode) self.addSubnode(self.titleNode) diff --git a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionItem.swift b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionItem.swift index f19fe421d9..125e115198 100644 --- a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionItem.swift +++ b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionItem.swift @@ -110,7 +110,7 @@ class BubbleSettingsRadiusItemNode: ListViewItemNode, ItemListItemNode { self.disabledOverlayNode = ASDisplayNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.leftIconNode) self.addSubnode(self.rightIconNode) diff --git a/submodules/SettingsUI/Sources/ThemePickerGridItem.swift b/submodules/SettingsUI/Sources/ThemePickerGridItem.swift index 5504d02664..aae20daead 100644 --- a/submodules/SettingsUI/Sources/ThemePickerGridItem.swift +++ b/submodules/SettingsUI/Sources/ThemePickerGridItem.swift @@ -406,7 +406,7 @@ class ThemeGridThemeItemNode: ListViewItemNode, ItemListItemNode { self.scrollNode = ASScrollNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.containerNode) self.addSubnode(self.scrollNode) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift index 2e5218a857..7d673f3531 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAccentColorItem.swift @@ -298,7 +298,7 @@ private final class ThemeSettingsAccentColorIconItemNode : ListViewItemNode { self.dotsNode.displayWithoutProcessing = true self.dotsNode.image = generateDotsImage() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) self.containerNode.addSubnode(self.fillNode) @@ -537,7 +537,7 @@ private final class ThemeSettingsAccentColorPickerItemNode : ListViewItemNode { self.imageNode.displayWithoutProcessing = true self.imageNode.image = generateCustomSwatchImage() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.imageNode) } @@ -734,7 +734,7 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode { self.listNode = ListView() self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.containerNode) self.addSubnode(self.listNode) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift index 421d3d4179..4ba2046088 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift @@ -229,7 +229,7 @@ class ThemeSettingsAppIconItemNode: ListViewItemNode, ItemListItemNode { self.containerNode = ASDisplayNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.containerNode) } diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsBrightnessItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsBrightnessItem.swift index c4fa77d58b..81aee3ec5c 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsBrightnessItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsBrightnessItem.swift @@ -90,7 +90,7 @@ class ThemeSettingsBrightnessItemNode: ListViewItemNode { self.rightIconNode.displaysAsynchronously = false self.rightIconNode.displayWithoutProcessing = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.leftIconNode) self.addSubnode(self.rightIconNode) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift index ac07ff62b2..b475dce6d4 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift @@ -130,7 +130,7 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { self.containerNode = ASDisplayNode() self.containerNode.subnodeTransform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.clipsToBounds = true diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsFontSizeItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsFontSizeItem.swift index aff462c9ae..08d11cee06 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsFontSizeItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsFontSizeItem.swift @@ -110,7 +110,7 @@ class ThemeSettingsFontSizeItemNode: ListViewItemNode, ItemListItemNode { self.disabledOverlayNode = ASDisplayNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.leftIconNode) self.addSubnode(self.rightIconNode) diff --git a/submodules/StatisticsUI/Sources/BoostLevelHeaderItem.swift b/submodules/StatisticsUI/Sources/BoostLevelHeaderItem.swift index 9270713394..5bb6750c49 100644 --- a/submodules/StatisticsUI/Sources/BoostLevelHeaderItem.swift +++ b/submodules/StatisticsUI/Sources/BoostLevelHeaderItem.swift @@ -76,7 +76,7 @@ class IncreaseLimitHeaderItemNode: ListViewItemNode { private var item: BoostLevelHeaderItem? init() { - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) } override func didLoad() { diff --git a/submodules/StatisticsUI/Sources/BoostsTabsItem.swift b/submodules/StatisticsUI/Sources/BoostsTabsItem.swift index 538b32351c..334ede4237 100644 --- a/submodules/StatisticsUI/Sources/BoostsTabsItem.swift +++ b/submodules/StatisticsUI/Sources/BoostsTabsItem.swift @@ -111,7 +111,7 @@ private final class BoostsTabsItemNode: ListViewItemNode { self.selectionNode = ASImageNode() self.selectionNode.displaysAsynchronously = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.boostsTextNode) self.addSubnode(self.giftsTextNode) diff --git a/submodules/StatisticsUI/Sources/MonetizationBalanceItem.swift b/submodules/StatisticsUI/Sources/MonetizationBalanceItem.swift index 98441dc464..687d2a4236 100644 --- a/submodules/StatisticsUI/Sources/MonetizationBalanceItem.swift +++ b/submodules/StatisticsUI/Sources/MonetizationBalanceItem.swift @@ -140,7 +140,7 @@ final class MonetizationBalanceItemNode: ListViewItemNode, ItemListItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.iconNode) self.addSubnode(self.balanceTextNode) diff --git a/submodules/StatisticsUI/Sources/StarsTransactionItem.swift b/submodules/StatisticsUI/Sources/StarsTransactionItem.swift index 1ab05b983f..f0fa87968a 100644 --- a/submodules/StatisticsUI/Sources/StarsTransactionItem.swift +++ b/submodules/StatisticsUI/Sources/StarsTransactionItem.swift @@ -113,7 +113,7 @@ final class StarsTransactionItemNode: ListViewItemNode, ItemListItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) } func asyncLayout() -> (_ item: StarsTransactionItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { diff --git a/submodules/StatisticsUI/Sources/StatsGraphItem.swift b/submodules/StatisticsUI/Sources/StatsGraphItem.swift index 7f8d1c8517..0ab64e4546 100644 --- a/submodules/StatisticsUI/Sources/StatsGraphItem.swift +++ b/submodules/StatisticsUI/Sources/StatsGraphItem.swift @@ -133,7 +133,7 @@ public final class StatsGraphItemNode: ListViewItemNode { self.activityIndicator = ActivityIndicator(type: ActivityIndicatorType.custom(.black, 16.0, 2.0, false)) self.activityIndicator.isHidden = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.chartContainerNode.addSubnode(self.chartNode) self.chartContainerNode.addSubnode(self.activityIndicator) diff --git a/submodules/StatisticsUI/Sources/StatsMessageItem.swift b/submodules/StatisticsUI/Sources/StatsMessageItem.swift index 1a2bf60b6a..641da989c6 100644 --- a/submodules/StatisticsUI/Sources/StatsMessageItem.swift +++ b/submodules/StatisticsUI/Sources/StatsMessageItem.swift @@ -184,7 +184,7 @@ final class StatsMessageItemNode: ListViewItemNode, ItemListItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.containerNode.addSubnode(self.contextSourceNode) self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode diff --git a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift index a5b9d6d2d2..789526910c 100644 --- a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift +++ b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift @@ -327,7 +327,7 @@ class StatsOverviewItemNode: ListViewItemNode { self.bottomLeftItem = ValueItemNode() self.bottomRightItem = ValueItemNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.clipsToBounds = true diff --git a/submodules/TelegramBaseController/Sources/TelegramBaseController.swift b/submodules/TelegramBaseController/Sources/TelegramBaseController.swift index 74588d00eb..87cad945ee 100644 --- a/submodules/TelegramBaseController/Sources/TelegramBaseController.swift +++ b/submodules/TelegramBaseController/Sources/TelegramBaseController.swift @@ -14,18 +14,6 @@ import PresentationDataUtils import TelegramCallsUI import UndoUI -public enum MediaAccessoryPanelVisibility { - case none - case specific(size: ContainerViewLayoutSizeClass) - case always -} - -public enum LocationBroadcastPanelSource { - case none - case summary - case peer(PeerId) -} - private func presentLiveLocationController(context: AccountContext, peerId: PeerId, controller: ViewController) { let presentImpl: (EngineMessage?) -> Void = { [weak controller] message in if let message = message, let strongController = controller { @@ -65,332 +53,31 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder { public var accessoryPanelContainer: ASDisplayNode? public private(set) var accessoryPanelContainerHeight: CGFloat = 0.0 - public let mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility public var tempHideAccessoryPanels: Bool = false - public let locationBroadcastPanelSource: LocationBroadcastPanelSource - public let groupCallPanelSource: GroupCallPanelSource - - private var mediaStatusDisposable: Disposable? - private var locationBroadcastDisposable: Disposable? - private var currentGroupCallDisposable: Disposable? - - public private(set) var playlistStateAndType: (SharedMediaPlaylistItem, SharedMediaPlaylistItem?, SharedMediaPlaylistItem?, MusicPlaybackSettingsOrder, MediaManagerPlayerType, Account)? - private var playlistLocation: SharedMediaPlaylistLocation? - - public var tempVoicePlaylistEnded: (() -> Void)? - public var tempVoicePlaylistItemChanged: ((SharedMediaPlaylistItem?, SharedMediaPlaylistItem?) -> Void)? - public var tempVoicePlaylistCurrentItem: SharedMediaPlaylistItem? - - public private(set) var mediaAccessoryPanel: (MediaNavigationAccessoryPanel, MediaManagerPlayerType)? - - private var locationBroadcastMode: LocationBroadcastNavigationAccessoryPanelMode? - private var locationBroadcastPeers: [EnginePeer]? - private var locationBroadcastMessages: [EngineMessage.Id: EngineMessage]? - private var locationBroadcastAccessoryPanel: LocationBroadcastNavigationAccessoryPanel? - private var giftAuctionAccessoryPanel: GiftAuctionAccessoryPanel? private var giftAuctionStates: [GiftAuctionContext.State] = [] private var giftAuctionDisposable: Disposable? - private var groupCallPanelData: GroupCallPanelData? - public private(set) var groupCallAccessoryPanel: GroupCallNavigationAccessoryPanel? - private var dismissingPanel: ASDisplayNode? - private weak var audioRateTooltipController: UndoOverlayController? - private var presentationData: PresentationData private var presentationDataDisposable: Disposable? - private var playlistPreloadDisposable: Disposable? override open var additionalNavigationBarHeight: CGFloat { - var height: CGFloat = 0.0 - if self.accessoryPanelContainer == nil { - if let _ = self.groupCallAccessoryPanel { - height += 50.0 - } - if let _ = self.mediaAccessoryPanel { - height += MediaNavigationAccessoryHeaderNode.minimizedHeight - } - if let _ = self.locationBroadcastAccessoryPanel { - height += MediaNavigationAccessoryHeaderNode.minimizedHeight - } - } - return height + return 0.0 } - public init(context: AccountContext, navigationBarPresentationData: NavigationBarPresentationData?, mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility, locationBroadcastPanelSource: LocationBroadcastPanelSource, groupCallPanelSource: GroupCallPanelSource) { + public init(context: AccountContext, navigationBarPresentationData: NavigationBarPresentationData?) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } - self.mediaAccessoryPanelVisibility = mediaAccessoryPanelVisibility - self.locationBroadcastPanelSource = locationBroadcastPanelSource - self.groupCallPanelSource = groupCallPanelSource super.init(navigationBarPresentationData: navigationBarPresentationData) - if case .none = mediaAccessoryPanelVisibility { - } else { - self.mediaStatusDisposable = (context.sharedContext.mediaManager.globalMediaPlayerState - |> mapToSignal { playlistStateAndType -> Signal<(Account, SharedMediaPlayerItemPlaybackState, MediaManagerPlayerType)?, NoError> in - if let (account, state, type) = playlistStateAndType { - switch state { - case let .state(state): - return .single((account, state, type)) - case .loading: - return .single(nil) |> delay(0.2, queue: .mainQueue()) - } - } else { - return .single(nil) - } - } - |> deliverOnMainQueue).start(next: { [weak self] playlistStateAndType in - guard let strongSelf = self else { - return - } - if !arePlaylistItemsEqual(strongSelf.playlistStateAndType?.0, playlistStateAndType?.1.item) || - !arePlaylistItemsEqual(strongSelf.playlistStateAndType?.1, playlistStateAndType?.1.previousItem) || - !arePlaylistItemsEqual(strongSelf.playlistStateAndType?.2, playlistStateAndType?.1.nextItem) || - strongSelf.playlistStateAndType?.3 != playlistStateAndType?.1.order || strongSelf.playlistStateAndType?.4 != playlistStateAndType?.2 { - var previousVoiceItem: SharedMediaPlaylistItem? - if let playlistStateAndType = strongSelf.playlistStateAndType, playlistStateAndType.4 == .voice { - previousVoiceItem = playlistStateAndType.0 - } - - var updatedVoiceItem: SharedMediaPlaylistItem? - if let playlistStateAndType = playlistStateAndType, playlistStateAndType.2 == .voice { - updatedVoiceItem = playlistStateAndType.1.item - } - - strongSelf.tempVoicePlaylistCurrentItem = updatedVoiceItem - strongSelf.tempVoicePlaylistItemChanged?(previousVoiceItem, updatedVoiceItem) - if let playlistStateAndType = playlistStateAndType { - strongSelf.playlistStateAndType = (playlistStateAndType.1.item, playlistStateAndType.1.previousItem, playlistStateAndType.1.nextItem, playlistStateAndType.1.order, playlistStateAndType.2, playlistStateAndType.0) - } else { - var voiceEnded = false - if strongSelf.playlistStateAndType?.4 == .voice { - voiceEnded = true - } - strongSelf.playlistStateAndType = nil - if voiceEnded { - strongSelf.tempVoicePlaylistEnded?() - } - } - strongSelf.requestLayout(transition: .animated(duration: 0.4, curve: .spring)) - } - strongSelf.playlistLocation = playlistStateAndType?.1.playlistLocation - }) - } - - if let liveLocationManager = context.liveLocationManager { - switch locationBroadcastPanelSource { - case .none: - self.locationBroadcastMode = nil - case .summary, .peer: - let signal: Signal<([EnginePeer]?, [EngineMessage.Id: EngineMessage]?), NoError> - switch locationBroadcastPanelSource { - case let .peer(peerId): - self.locationBroadcastMode = .peer - signal = combineLatest(liveLocationManager.summaryManager.peersBroadcastingTo(peerId: peerId), liveLocationManager.summaryManager.broadcastingToMessages()) - |> map { peersAndMessages, outgoingMessages in - var peers = peersAndMessages?.map { $0.0 } - for message in outgoingMessages.values { - if message.id.peerId == peerId, let author = message.author { - if peers == nil { - peers = [] - } - peers?.append(author) - } - } - return (peers, outgoingMessages) - } - default: - self.locationBroadcastMode = .summary - signal = liveLocationManager.summaryManager.broadcastingToMessages() - |> map { messages -> ([EnginePeer]?, [EngineMessage.Id: EngineMessage]?) in - if messages.isEmpty { - return (nil, nil) - } else { - var peers: [EnginePeer] = [] - for message in messages.values.sorted(by: { $0.index < $1.index }) { - if let peer = message.peers[message.id.peerId] { - peers.append(EnginePeer(peer)) - } - } - return (peers, messages) - } - } - - } - - self.locationBroadcastDisposable = (signal - |> deliverOnMainQueue).start(next: { [weak self] peers, messages in - if let strongSelf = self { - var updated = false - if let current = strongSelf.locationBroadcastPeers, let peers = peers { - updated = current != peers - } else if (strongSelf.locationBroadcastPeers != nil) != (peers != nil) { - updated = true - } - - strongSelf.locationBroadcastMessages = messages - - if updated { - let wasEmpty = strongSelf.locationBroadcastPeers == nil - strongSelf.locationBroadcastPeers = peers - if wasEmpty != (peers == nil) { - strongSelf.requestLayout(transition: .animated(duration: 0.4, curve: .spring)) - } else if let peers = peers, let locationBroadcastMode = strongSelf.locationBroadcastMode { - var canClose = true - if case let .peer(peerId) = strongSelf.locationBroadcastPanelSource, let messages = messages { - canClose = false - for messageId in messages.keys { - if messageId.peerId == peerId { - canClose = true - } - } - } - strongSelf.locationBroadcastAccessoryPanel?.update(peers: peers, mode: locationBroadcastMode, canClose: canClose) - } - } - } - }) - } - } - - if let callManager = context.sharedContext.callManager { - switch groupCallPanelSource { - case .none, .all: - break - case let .peer(peerId): - let currentGroupCall: Signal = callManager.currentGroupCallSignal - |> distinctUntilChanged(isEqual: { lhs, rhs in - return lhs == rhs - }) - |> map { call -> PresentationGroupCall? in - guard case let .group(call) = call else { - return nil - } - guard call.peerId == peerId && call.account.peerId == context.account.peerId else { - return nil - } - return call - } - - let availableGroupCall: Signal - if case let .peer(peerId) = groupCallPanelSource { - availableGroupCall = context.account.viewTracker.peerView(peerId) - |> map { peerView -> (CachedChannelData.ActiveCall?, EnginePeer?) in - let peer = peerView.peers[peerId].flatMap(EnginePeer.init) - if let cachedData = peerView.cachedData as? CachedChannelData { - return (cachedData.activeCall, peer) - } else if let cachedData = peerView.cachedData as? CachedGroupData { - return (cachedData.activeCall, peer) - } else { - return (nil, peer) - } - } - |> distinctUntilChanged(isEqual: { lhs, rhs in - return lhs.0 == rhs.0 - }) - |> mapToSignal { activeCall, peer -> Signal in - guard let activeCall = activeCall else { - return .single(nil) - } - - var isChannel = false - if let peer = peer, case let .channel(channel) = peer, case .broadcast = channel.info { - isChannel = true - } - - return Signal { [weak context] subscriber in - guard let context = context, let callContextCache = context.cachedGroupCallContexts as? AccountGroupCallContextCacheImpl else { - return EmptyDisposable - } - - let disposable = MetaDisposable() - - callContextCache.impl.syncWith { impl in - let callContext = impl.get(account: context.account, engine: context.engine, peerId: peerId, isChannel: isChannel, call: EngineGroupCallDescription(activeCall)) - disposable.set((callContext.context.panelData - |> deliverOnMainQueue).start(next: { panelData in - callContext.keep() - var updatedPanelData = panelData - if let panelData { - var updatedInfo = panelData.info - updatedInfo.subscribedToScheduled = activeCall.subscribedToScheduled - updatedPanelData = panelData.withInfo(updatedInfo) - } - subscriber.putNext(updatedPanelData) - })) - } - - return ActionDisposable { - disposable.dispose() - } - } - |> runOn(.mainQueue()) - } - } else { - availableGroupCall = .single(nil) - } - - let previousCurrentGroupCall = Atomic(value: nil) - self.currentGroupCallDisposable = combineLatest(queue: .mainQueue(), availableGroupCall, currentGroupCall).start(next: { [weak self] availableState, currentGroupCall in - guard let strongSelf = self else { - return - } - - let previousCurrentGroupCall = previousCurrentGroupCall.swap(currentGroupCall) - - let panelData: GroupCallPanelData? - if previousCurrentGroupCall != nil && currentGroupCall == nil && availableState?.participantCount == 1 { - panelData = nil - } else { - panelData = currentGroupCall != nil || (availableState?.participantCount == 0 && availableState?.info.scheduleTimestamp == nil && availableState?.info.isStream == false) ? nil : availableState - } - - let wasEmpty = strongSelf.groupCallPanelData == nil - strongSelf.groupCallPanelData = panelData - let isEmpty = strongSelf.groupCallPanelData == nil - if wasEmpty != isEmpty { - strongSelf.requestLayout(transition: .animated(duration: 0.4, curve: .spring)) - } else if let groupCallPanelData = strongSelf.groupCallPanelData { - strongSelf.groupCallAccessoryPanel?.update(data: groupCallPanelData) - } - }) - } - } - - if let giftAuctionsManager = context.giftAuctionsManager, case .summary = locationBroadcastPanelSource { - self.giftAuctionDisposable = (giftAuctionsManager.state - |> deliverOnMainQueue).start(next: { [weak self] states in - guard let self else { - return - } - self.giftAuctionStates = states.filter { state in - if case .ongoing = state.auctionState { - return true - } else { - return false - } - } - }) - } - self.presentationDataDisposable = (self.updatedPresentationData.1 |> deliverOnMainQueue).start(next: { [weak self] presentationData in if let strongSelf = self { - let previousTheme = strongSelf.presentationData.theme - let previousStrings = strongSelf.presentationData.strings - strongSelf.presentationData = presentationData - - if previousTheme !== presentationData.theme || previousStrings !== presentationData.strings { - strongSelf.mediaAccessoryPanel?.0.containerNode.updatePresentationData(presentationData) - strongSelf.locationBroadcastAccessoryPanel?.updatePresentationData(presentationData) - strongSelf.groupCallAccessoryPanel?.updatePresentationData(presentationData) - } } }) } @@ -400,11 +87,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder { } deinit { - self.mediaStatusDisposable?.dispose() - self.locationBroadcastDisposable?.dispose() - self.currentGroupCallDisposable?.dispose() self.presentationDataDisposable?.dispose() - self.playlistPreloadDisposable?.dispose() } required public init(coder aDecoder: NSCoder) { @@ -429,118 +112,8 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder { super.containerLayoutUpdated(layout, transition: transition) - let navigationHeight = super.navigationLayout(layout: layout).navigationFrame.height - self.additionalNavigationBarHeight - - let mediaAccessoryPanelHidden: Bool - if self.tempHideAccessoryPanels { - mediaAccessoryPanelHidden = true - } else { - switch self.mediaAccessoryPanelVisibility { - case .always: - mediaAccessoryPanelHidden = false - case .none: - mediaAccessoryPanelHidden = true - case let .specific(size): - mediaAccessoryPanelHidden = size != layout.metrics.widthClass - } - } - var additionalHeight: CGFloat = 0.0 var panelStartY: CGFloat = 0.0 - if self.accessoryPanelContainer == nil { - var negativeHeight: CGFloat = 0.0 - if let _ = self.groupCallPanelData { - negativeHeight += 50.0 - } - if let _ = self.locationBroadcastPeers, let _ = self.locationBroadcastMode { - negativeHeight += MediaNavigationAccessoryHeaderNode.minimizedHeight - } - if let _ = self.playlistStateAndType, !mediaAccessoryPanelHidden { - negativeHeight += MediaNavigationAccessoryHeaderNode.minimizedHeight - } - panelStartY = navigationHeight.isZero ? (-negativeHeight) : (navigationHeight + additionalHeight + UIScreenPixel) - } - - if let groupCallPanelData = self.groupCallPanelData { - let panelHeight: CGFloat = 50.0 - let panelFrame = CGRect(origin: CGPoint(x: 0.0, y: panelStartY), size: CGSize(width: layout.size.width, height: panelHeight)) - additionalHeight += panelHeight - panelStartY += panelHeight - - let groupCallAccessoryPanel: GroupCallNavigationAccessoryPanel - if let current = self.groupCallAccessoryPanel { - groupCallAccessoryPanel = current - transition.updateFrame(node: groupCallAccessoryPanel, frame: panelFrame) - groupCallAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, isHidden: !self.displayNavigationBar, transition: transition) - } else { - let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } - groupCallAccessoryPanel = GroupCallNavigationAccessoryPanel(context: self.context, presentationData: presentationData, tapAction: { [weak self] in - guard let strongSelf = self, let groupCallPanelData = strongSelf.groupCallPanelData else { - return - } - strongSelf.joinGroupCall( - peerId: groupCallPanelData.peerId, - invite: nil, - activeCall: EngineGroupCallDescription(id: groupCallPanelData.info.id, accessHash: groupCallPanelData.info.accessHash, title: groupCallPanelData.info.title, scheduleTimestamp: groupCallPanelData.info.scheduleTimestamp, subscribedToScheduled: groupCallPanelData.info.subscribedToScheduled, isStream: groupCallPanelData.info.isStream) - ) - }, notifyScheduledTapAction: { [weak self] in - guard let self, let groupCallPanelData = self.groupCallPanelData else { - return - } - if groupCallPanelData.info.scheduleTimestamp != nil && !groupCallPanelData.info.subscribedToScheduled { - let _ = self.context.engine.calls.toggleScheduledGroupCallSubscription(peerId: groupCallPanelData.peerId, reference: .id(id: groupCallPanelData.info.id, accessHash: groupCallPanelData.info.accessHash), subscribe: true).startStandalone() - - let controller = UndoOverlayController( - presentationData: presentationData, - content: .universal( - animation: "anim_set_notification", - scale: 0.06, - colors: [ - "Middle.Group 1.Fill 1": UIColor.white, - "Top.Group 1.Fill 1": UIColor.white, - "Bottom.Group 1.Fill 1": UIColor.white, - "EXAMPLE.Group 1.Fill 1": UIColor.white, - "Line.Group 1.Stroke 1": UIColor.white - ], - title: nil, - text: presentationData.strings.Chat_ToastSubscribedToScheduledLiveStream_Text, - customUndoText: nil, - timeout: nil - ), - elevatedLayout: false, - animateInAsReplacement: false, - action: { _ in - return true - } - ) - self.audioRateTooltipController = controller - self.present(controller, in: .current) - } - }) - if let accessoryPanelContainer = self.accessoryPanelContainer { - accessoryPanelContainer.addSubnode(groupCallAccessoryPanel) - } else { - self.navigationBar?.additionalContentNode.addSubnode(groupCallAccessoryPanel) - } - self.groupCallAccessoryPanel = groupCallAccessoryPanel - groupCallAccessoryPanel.frame = panelFrame - - groupCallAccessoryPanel.update(data: groupCallPanelData) - groupCallAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, isHidden: !self.displayNavigationBar, transition: .immediate) - if transition.isAnimated { - groupCallAccessoryPanel.animateIn(transition) - } - } - } else if let groupCallAccessoryPanel = self.groupCallAccessoryPanel { - self.groupCallAccessoryPanel = nil - if transition.isAnimated { - groupCallAccessoryPanel.animateOut(transition, completion: { [weak groupCallAccessoryPanel] in - groupCallAccessoryPanel?.removeFromSupernode() - }) - } else { - groupCallAccessoryPanel.removeFromSupernode() - } - } if !self.giftAuctionStates.isEmpty { let panelHeight: CGFloat = 56.0 @@ -598,454 +171,6 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder { giftAuctionAccessoryPanel.removeFromSupernode() } } - - if let locationBroadcastPeers = self.locationBroadcastPeers, let locationBroadcastMode = self.locationBroadcastMode { - let panelHeight = MediaNavigationAccessoryHeaderNode.minimizedHeight - let panelFrame = CGRect(origin: CGPoint(x: 0.0, y: panelStartY), size: CGSize(width: layout.size.width, height: panelHeight)) - additionalHeight += panelHeight - panelStartY += panelHeight - - let locationBroadcastAccessoryPanel: LocationBroadcastNavigationAccessoryPanel - if let current = self.locationBroadcastAccessoryPanel { - locationBroadcastAccessoryPanel = current - transition.updateFrame(node: locationBroadcastAccessoryPanel, frame: panelFrame) - locationBroadcastAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, isHidden: !self.displayNavigationBar, transition: transition) - } else { - let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } - locationBroadcastAccessoryPanel = LocationBroadcastNavigationAccessoryPanel(accountPeerId: self.context.account.peerId, theme: presentationData.theme, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder, tapAction: { [weak self] in - if let strongSelf = self { - switch strongSelf.locationBroadcastPanelSource { - case .none: - break - case .summary: - if let locationBroadcastMessages = strongSelf.locationBroadcastMessages { - let messages = locationBroadcastMessages.values.sorted(by: { $0.index > $1.index }) - - if messages.count == 1 { - presentLiveLocationController(context: strongSelf.context, peerId: messages[0].id.peerId, controller: strongSelf) - } else { - let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } - let controller = ActionSheetController(presentationData: presentationData) - let dismissAction: () -> Void = { [weak controller] in - controller?.dismissAnimated() - } - var items: [ActionSheetItem] = [] - if !messages.isEmpty { - items.append(ActionSheetTextItem(title: presentationData.strings.LiveLocation_MenuChatsCount(Int32(messages.count)))) - for message in messages { - if let peer = message.peers[message.id.peerId] { - var beginTimeAndTimeout: (Double, Double)? - for media in message.media { - if let media = media as? TelegramMediaMap, let timeout = media.liveBroadcastingTimeout { - beginTimeAndTimeout = (Double(message.timestamp), Double(timeout)) - } - } - - if let beginTimeAndTimeout = beginTimeAndTimeout { - items.append(LocationBroadcastActionSheetItem(context: strongSelf.context, peer: peer, title: EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), beginTimestamp: beginTimeAndTimeout.0, timeout: beginTimeAndTimeout.1, strings: presentationData.strings, action: { - dismissAction() - if let strongSelf = self { - presentLiveLocationController(context: strongSelf.context, peerId: peer.id, controller: strongSelf) - } - })) - } - } - } - items.append(ActionSheetButtonItem(title: presentationData.strings.LiveLocation_MenuStopAll, color: .destructive, action: { - dismissAction() - if let locationBroadcastPeers = strongSelf.locationBroadcastPeers { - for peer in locationBroadcastPeers { - self?.context.liveLocationManager?.cancelLiveLocation(peerId: peer.id) - } - } - })) - } - controller.setItemGroups([ - ActionSheetItemGroup(items: items), - ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })]) - ]) - strongSelf.view.endEditing(true) - strongSelf.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) - } - } - case let .peer(peerId): - presentLiveLocationController(context: strongSelf.context, peerId: peerId, controller: strongSelf) - } - } - }, close: { [weak self] in - if let strongSelf = self { - var closePeers: [EnginePeer]? - var closePeerId: EnginePeer.Id? - switch strongSelf.locationBroadcastPanelSource { - case .none: - break - case .summary: - if let locationBroadcastPeers = strongSelf.locationBroadcastPeers { - if locationBroadcastPeers.count > 1 { - closePeers = locationBroadcastPeers - } else { - closePeerId = locationBroadcastPeers.first?.id - } - } - case let .peer(peerId): - closePeerId = peerId - } - let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } - let controller = ActionSheetController(presentationData: presentationData) - let dismissAction: () -> Void = { [weak controller] in - controller?.dismissAnimated() - } - var items: [ActionSheetItem] = [] - if let closePeers = closePeers, !closePeers.isEmpty { - items.append(ActionSheetTextItem(title: presentationData.strings.LiveLocation_MenuChatsCount(Int32(closePeers.count)))) - for peer in closePeers { - items.append(ActionSheetButtonItem(title: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), action: { - dismissAction() - if let strongSelf = self { - presentLiveLocationController(context: strongSelf.context, peerId: peer.id, controller: strongSelf) - } - })) - } - items.append(ActionSheetButtonItem(title: presentationData.strings.LiveLocation_MenuStopAll, color: .destructive, action: { - dismissAction() - for peer in closePeers { - self?.context.liveLocationManager?.cancelLiveLocation(peerId: peer.id) - } - })) - } else if let closePeerId = closePeerId { - items.append(ActionSheetButtonItem(title: presentationData.strings.Map_StopLiveLocation, color: .destructive, action: { - dismissAction() - self?.context.liveLocationManager?.cancelLiveLocation(peerId: closePeerId) - })) - } - controller.setItemGroups([ - ActionSheetItemGroup(items: items), - ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })]) - ]) - strongSelf.view.endEditing(true) - strongSelf.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) - } - }) - if let accessoryPanelContainer = self.accessoryPanelContainer { - accessoryPanelContainer.addSubnode(locationBroadcastAccessoryPanel) - } else { - self.navigationBar?.additionalContentNode.addSubnode(locationBroadcastAccessoryPanel) - } - self.locationBroadcastAccessoryPanel = locationBroadcastAccessoryPanel - locationBroadcastAccessoryPanel.frame = panelFrame - - var canClose = true - if case let .peer(peerId) = self.locationBroadcastPanelSource, let messages = self.locationBroadcastMessages { - canClose = false - for messageId in messages.keys { - if messageId.peerId == peerId { - canClose = true - } - } - } - - locationBroadcastAccessoryPanel.update(peers: locationBroadcastPeers, mode: locationBroadcastMode, canClose: canClose) - locationBroadcastAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, isHidden: !self.displayNavigationBar, transition: .immediate) - if transition.isAnimated { - locationBroadcastAccessoryPanel.animateIn(transition) - } - } - } else if let locationBroadcastAccessoryPanel = self.locationBroadcastAccessoryPanel { - self.locationBroadcastAccessoryPanel = nil - if transition.isAnimated { - locationBroadcastAccessoryPanel.animateOut(transition, completion: { [weak locationBroadcastAccessoryPanel] in - locationBroadcastAccessoryPanel?.removeFromSupernode() - }) - } else { - locationBroadcastAccessoryPanel.removeFromSupernode() - } - } - - var isViewOnceMessage = false - if let (item, _, _, _, _, _) = self.playlistStateAndType, let source = item.playbackData?.source, case let .telegramFile(_, _, isViewOnce) = source, isViewOnce { - isViewOnceMessage = true - } - - if let (item, previousItem, nextItem, order, type, _) = self.playlistStateAndType, !mediaAccessoryPanelHidden && !isViewOnceMessage { - let panelHeight = MediaNavigationAccessoryHeaderNode.minimizedHeight - let panelFrame = CGRect(origin: CGPoint(x: 0.0, y: panelStartY), size: CGSize(width: layout.size.width, height: panelHeight)) - additionalHeight += panelHeight - panelStartY += panelHeight - - if let (mediaAccessoryPanel, mediaType) = self.mediaAccessoryPanel, mediaType == type { - transition.updateFrame(layer: mediaAccessoryPanel.layer, frame: panelFrame) - mediaAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, isHidden: !self.displayNavigationBar, transition: transition) - switch order { - case .regular: - mediaAccessoryPanel.containerNode.headerNode.playbackItems = (item, previousItem, nextItem) - case .reversed: - mediaAccessoryPanel.containerNode.headerNode.playbackItems = (item, nextItem, previousItem) - case .random: - mediaAccessoryPanel.containerNode.headerNode.playbackItems = (item, nil, nil) - } - let delayedStatus = self.context.sharedContext.mediaManager.globalMediaPlayerState - |> mapToSignal { value -> Signal<(Account, SharedMediaPlayerItemPlaybackStateOrLoading, MediaManagerPlayerType)?, NoError> in - guard let value = value else { - return .single(nil) - } - switch value.1 { - case .state: - return .single(value) - case .loading: - return .single(value) |> delay(0.1, queue: .mainQueue()) - } - } - - mediaAccessoryPanel.containerNode.headerNode.playbackStatus = delayedStatus - |> map { state -> MediaPlayerStatus in - if let stateOrLoading = state?.1, case let .state(state) = stateOrLoading { - return state.status - } else { - return MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .paused, soundEnabled: true) - } - } - } else { - if let (mediaAccessoryPanel, _) = self.mediaAccessoryPanel { - self.mediaAccessoryPanel = nil - self.dismissingPanel = mediaAccessoryPanel - self.audioRateTooltipController?.dismissWithCommitAction() - mediaAccessoryPanel.animateOut(transition: transition, completion: { [weak self, weak mediaAccessoryPanel] in - mediaAccessoryPanel?.removeFromSupernode() - if let strongSelf = self, strongSelf.dismissingPanel === mediaAccessoryPanel { - strongSelf.dismissingPanel = nil - } - }) - } - - let mediaAccessoryPanel = MediaNavigationAccessoryPanel(context: self.context, presentationData: self.updatedPresentationData.0) - mediaAccessoryPanel.containerNode.headerNode.displayScrubber = item.playbackData?.type != .instantVideo - mediaAccessoryPanel.getController = { [weak self] in - return self - } - mediaAccessoryPanel.presentInGlobalOverlay = { [weak self] c in - self?.presentInGlobalOverlay(c) - } - mediaAccessoryPanel.close = { [weak self] in - if let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType { - strongSelf.context.sharedContext.mediaManager.setPlaylist(nil, type: type, control: SharedMediaPlayerControlAction.playback(.pause)) - } - } - mediaAccessoryPanel.setRate = { [weak self] rate, changeType in - guard let strongSelf = self else { - return - } - let _ = (strongSelf.context.sharedContext.accountManager.transaction { transaction -> AudioPlaybackRate in - let settings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.musicPlaybackSettings)?.get(MusicPlaybackSettings.self) ?? MusicPlaybackSettings.defaultSettings - - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.musicPlaybackSettings, { _ in - return PreferencesEntry(settings.withUpdatedVoicePlaybackRate(rate)) - }) - return rate - } - |> deliverOnMainQueue).start(next: { baseRate in - guard let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType else { - return - } - strongSelf.context.sharedContext.mediaManager.playlistControl(.setBaseRate(baseRate), type: type) - - var hasTooltip = false - strongSelf.forEachController({ controller in - if let controller = controller as? UndoOverlayController { - hasTooltip = true - controller.dismissWithCommitAction() - } - return true - }) - - let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } - let text: String? - let rate: CGFloat? - if case let .sliderCommit(previousValue, newValue) = changeType { - let value = String(format: "%0.1f", baseRate.doubleValue) - if baseRate == .x1 { - text = presentationData.strings.Conversation_AudioRateTooltipNormal - } else { - text = presentationData.strings.Conversation_AudioRateTooltipCustom(value).string - } - if newValue > previousValue { - rate = .infinity - } else if newValue < previousValue { - rate = -.infinity - } else { - rate = nil - } - } else if baseRate == .x1 { - text = presentationData.strings.Conversation_AudioRateTooltipNormal - rate = 1.0 - } else if baseRate == .x1_5 { - text = presentationData.strings.Conversation_AudioRateTooltip15X - rate = 1.5 - } else if baseRate == .x2 { - text = presentationData.strings.Conversation_AudioRateTooltipSpeedUp - rate = 2.0 - } else { - text = nil - rate = nil - } - var showTooltip = true - if case .sliderChange = changeType { - showTooltip = false - } - if let rate, let text, showTooltip { - let controller = UndoOverlayController( - presentationData: presentationData, - content: .audioRate( - rate: rate, - text: text - ), - elevatedLayout: false, - animateInAsReplacement: hasTooltip, - action: { action in - return true - } - ) - strongSelf.audioRateTooltipController = controller - strongSelf.present(controller, in: .current) - } - }) - } - mediaAccessoryPanel.togglePlayPause = { [weak self] in - if let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType { - strongSelf.context.sharedContext.mediaManager.playlistControl(.playback(.togglePlayPause), type: type) - } - } - mediaAccessoryPanel.playPrevious = { [weak self] in - if let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType { - strongSelf.context.sharedContext.mediaManager.playlistControl(.next, type: type) - } - } - mediaAccessoryPanel.playNext = { [weak self] in - if let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType { - strongSelf.context.sharedContext.mediaManager.playlistControl(.previous, type: type) - } - } - mediaAccessoryPanel.tapAction = { [weak self] in - guard let strongSelf = self, let _ = strongSelf.navigationController as? NavigationController, let (state, _, _, order, type, account) = strongSelf.playlistStateAndType else { - return - } - if let id = state.id as? PeerMessagesMediaPlaylistItemId, let playlistLocation = strongSelf.playlistLocation as? PeerMessagesPlaylistLocation { - if type == .music { - switch playlistLocation { - case .custom, .savedMusic: - let controllerContext: AccountContext - if account.id == strongSelf.context.account.id { - controllerContext = strongSelf.context - } else { - controllerContext = strongSelf.context.sharedContext.makeTempAccountContext(account: account) - } - let controller = strongSelf.context.sharedContext.makeOverlayAudioPlayerController(context: controllerContext, chatLocation: .peer(id: id.messageId.peerId), type: type, initialMessageId: id.messageId, initialOrder: order, playlistLocation: playlistLocation, parentNavigationController: strongSelf.navigationController as? NavigationController) - strongSelf.displayNode.view.window?.endEditing(true) - strongSelf.present(controller, in: .window(.root)) - case let .messages(chatLocation, _, _): - let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(id.messageId)), count: 60, highlight: true, setupReply: false), id: 0), context: strongSelf.context, chatLocation: chatLocation, subject: nil, chatLocationContextHolder: Atomic(value: nil), tag: .tag(MessageTags.music)) - - var cancelImpl: (() -> Void)? - let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } - let progressSignal = Signal { subscriber in - let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: { - cancelImpl?() - })) - self?.present(controller, in: .window(.root)) - return ActionDisposable { [weak controller] in - Queue.mainQueue().async() { - controller?.dismiss() - } - } - } - |> runOn(Queue.mainQueue()) - |> delay(0.15, queue: Queue.mainQueue()) - let progressDisposable = MetaDisposable() - var progressStarted = false - strongSelf.playlistPreloadDisposable?.dispose() - strongSelf.playlistPreloadDisposable = (signal - |> afterDisposed { - Queue.mainQueue().async { - progressDisposable.dispose() - } - } - |> deliverOnMainQueue).start(next: { index in - guard let strongSelf = self else { - return - } - if let _ = index.0 { - let controllerContext: AccountContext - if account.id == strongSelf.context.account.id { - controllerContext = strongSelf.context - } else { - controllerContext = strongSelf.context.sharedContext.makeTempAccountContext(account: account) - } - let controller = strongSelf.context.sharedContext.makeOverlayAudioPlayerController(context: controllerContext, chatLocation: chatLocation, type: type, initialMessageId: id.messageId, initialOrder: order, playlistLocation: nil, parentNavigationController: strongSelf.navigationController as? NavigationController) - strongSelf.displayNode.view.window?.endEditing(true) - strongSelf.present(controller, in: .window(.root)) - } else if index.1 { - if !progressStarted { - progressStarted = true - progressDisposable.set(progressSignal.start()) - } - } - }, completed: { - }) - cancelImpl = { - self?.playlistPreloadDisposable?.dispose() - } - default: - break - } - } else { - strongSelf.context.sharedContext.navigateToChat(accountId: strongSelf.context.account.id, peerId: id.messageId.peerId, messageId: id.messageId) - } - } - } - mediaAccessoryPanel.frame = panelFrame - if let dismissingPanel = self.dismissingPanel { - if let accessoryPanelContainer = self.accessoryPanelContainer { - accessoryPanelContainer.insertSubnode(mediaAccessoryPanel, aboveSubnode: dismissingPanel) - } else { - self.navigationBar?.additionalContentNode.insertSubnode(mediaAccessoryPanel, aboveSubnode: dismissingPanel) - } - } else { - if let accessoryPanelContainer = self.accessoryPanelContainer { - accessoryPanelContainer.addSubnode(mediaAccessoryPanel) - } else { - self.navigationBar?.additionalContentNode.addSubnode(mediaAccessoryPanel) - } - } - self.mediaAccessoryPanel = (mediaAccessoryPanel, type) - mediaAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, isHidden: !self.displayNavigationBar, transition: .immediate) - switch order { - case .regular: - mediaAccessoryPanel.containerNode.headerNode.playbackItems = (item, previousItem, nextItem) - case .reversed: - mediaAccessoryPanel.containerNode.headerNode.playbackItems = (item, nextItem, previousItem) - case .random: - mediaAccessoryPanel.containerNode.headerNode.playbackItems = (item, nil, nil) - } - mediaAccessoryPanel.containerNode.headerNode.playbackStatus = self.context.sharedContext.mediaManager.globalMediaPlayerState - |> map { state -> MediaPlayerStatus in - if let stateOrLoading = state?.1, case let .state(state) = stateOrLoading { - return state.status - } else { - return MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .paused, soundEnabled: true) - } - } - mediaAccessoryPanel.animateIn(transition: transition) - } - } else if let (mediaAccessoryPanel, _) = self.mediaAccessoryPanel { - self.mediaAccessoryPanel = nil - self.dismissingPanel = mediaAccessoryPanel - self.audioRateTooltipController?.dismissWithCommitAction() - mediaAccessoryPanel.animateOut(transition: transition, completion: { [weak self, weak mediaAccessoryPanel] in - mediaAccessoryPanel?.removeFromSupernode() - if let strongSelf = self, strongSelf.dismissingPanel === mediaAccessoryPanel { - strongSelf.dismissingPanel = nil - } - }) - } self.suspendNavigationBarLayout = false if let suspendedNavigationBarLayout = self.suspendedNavigationBarLayout { diff --git a/submodules/TelegramCallsUI/Sources/AccountGroupCallContextImpl.swift b/submodules/TelegramCallsUI/Sources/AccountGroupCallContextImpl.swift index 5b348c93da..44f7f27b22 100644 --- a/submodules/TelegramCallsUI/Sources/AccountGroupCallContextImpl.swift +++ b/submodules/TelegramCallsUI/Sources/AccountGroupCallContextImpl.swift @@ -24,6 +24,46 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext { var disposable: Disposable? public var participantsContext: GroupCallParticipantsContext? + public final class GroupCallPanelData { + public let peerId: EnginePeer.Id + public let isChannel: Bool + public let info: GroupCallInfo + public let topParticipants: [GroupCallParticipantsContext.Participant] + public let participantCount: Int + public let activeSpeakers: Set + public let groupCall: PresentationGroupCall? + + public init( + peerId: EnginePeer.Id, + isChannel: Bool, + info: GroupCallInfo, + topParticipants: [GroupCallParticipantsContext.Participant], + participantCount: Int, + activeSpeakers: Set, + groupCall: PresentationGroupCall? + ) { + self.peerId = peerId + self.isChannel = isChannel + self.info = info + self.topParticipants = topParticipants + self.participantCount = participantCount + self.activeSpeakers = activeSpeakers + self.groupCall = groupCall + } + + public func withInfo(_ info: GroupCallInfo) -> GroupCallPanelData { + return GroupCallPanelData( + peerId: self.peerId, + isChannel: self.isChannel, + info: info, + topParticipants: self.topParticipants, + participantCount: self.participantCount, + activeSpeakers: self.activeSpeakers, + groupCall: self.groupCall + ) + } + } + private let panelDataPromise = Promise() public var panelData: Signal { return self.panelDataPromise.get() diff --git a/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift b/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift index e40dafcf8a..04529dbea6 100644 --- a/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift +++ b/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift @@ -22,6 +22,22 @@ private let pink = UIColor(rgb: 0xef436c) private let latePurple = UIColor(rgb: 0xaa56a6) private let latePink = UIColor(rgb: 0xef476f) +private func textForTimeout(value: Int32) -> String { + if value < 3600 { + let minutes = value / 60 + let seconds = value % 60 + let secondsPadding = seconds < 10 ? "0" : "" + return "\(minutes):\(secondsPadding)\(seconds)" + } else { + let hours = value / 3600 + let minutes = (value % 3600) / 60 + let minutesPadding = minutes < 10 ? "0" : "" + let seconds = value % 60 + let secondsPadding = seconds < 10 ? "0" : "" + return "\(hours):\(minutesPadding)\(minutes):\(secondsPadding)\(seconds)" + } +} + private class CallStatusBarBackgroundNode: ASDisplayNode { enum State { case connecting diff --git a/submodules/TelegramCallsUI/Sources/VideoChatScheduledInfoComponent.swift b/submodules/TelegramCallsUI/Sources/VideoChatScheduledInfoComponent.swift index c9ae7d1dea..1143f2eae4 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatScheduledInfoComponent.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatScheduledInfoComponent.swift @@ -13,6 +13,22 @@ private let pink = UIColor(rgb: 0xef436c) private let latePurple = UIColor(rgb: 0x974aa9) private let latePink = UIColor(rgb: 0xf0436c) +private func textForTimeout(value: Int32) -> String { + if value < 3600 { + let minutes = value / 60 + let seconds = value % 60 + let secondsPadding = seconds < 10 ? "0" : "" + return "\(minutes):\(secondsPadding)\(seconds)" + } else { + let hours = value / 3600 + let minutes = (value % 3600) / 60 + let minutesPadding = minutes < 10 ? "0" : "" + let seconds = value % 60 + let secondsPadding = seconds < 10 ? "0" : "" + return "\(hours):\(minutesPadding)\(minutes):\(secondsPadding)\(seconds)" + } +} + final class VideoChatScheduledInfoComponent: Component { let timestamp: Int32 let strings: PresentationStrings diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatActionItem.swift b/submodules/TelegramCallsUI/Sources/VoiceChatActionItem.swift index 320041dea4..c2822f5f04 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatActionItem.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatActionItem.swift @@ -129,7 +129,7 @@ class VoiceChatActionItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.highlightContainerNode.addSubnode(self.highlightedBackgroundNode) diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatFullscreenParticipantItem.swift b/submodules/TelegramCallsUI/Sources/VoiceChatFullscreenParticipantItem.swift index 583671503a..fc62365030 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatFullscreenParticipantItem.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatFullscreenParticipantItem.swift @@ -259,7 +259,7 @@ class VoiceChatFullscreenParticipantItemNode: ItemListRevealOptionsItemNode { self.actionContainerNode = ASDisplayNode() self.actionButtonNode = HighlightableButtonNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatMicrophoneNode.swift b/submodules/TelegramCallsUI/Sources/VoiceChatMicrophoneNode.swift index c644942dc0..b296906eda 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatMicrophoneNode.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatMicrophoneNode.swift @@ -23,15 +23,15 @@ private final class VoiceChatMicrophoneNodeDrawingState: NSObject { } } -final class VoiceChatMicrophoneNode: ASDisplayNode { - class State: Equatable { - let muted: Bool - let color: UIColor - let filled: Bool - let shadowColor: UIColor? - let shadowBlur: CGFloat +public final class VoiceChatMicrophoneNode: ASDisplayNode { + public class State: Equatable { + public let muted: Bool + public let color: UIColor + public let filled: Bool + public let shadowColor: UIColor? + public let shadowBlur: CGFloat - init(muted: Bool, filled: Bool, color: UIColor, shadowColor: UIColor? = nil, shadowBlur: CGFloat = 0.0) { + public init(muted: Bool, filled: Bool, color: UIColor, shadowColor: UIColor? = nil, shadowBlur: CGFloat = 0.0) { self.muted = muted self.filled = filled self.color = color @@ -39,7 +39,7 @@ final class VoiceChatMicrophoneNode: ASDisplayNode { self.shadowBlur = shadowBlur } - static func ==(lhs: State, rhs: State) -> Bool { + public static func ==(lhs: State, rhs: State) -> Bool { if lhs.muted != rhs.muted { return false } @@ -77,13 +77,13 @@ final class VoiceChatMicrophoneNode: ASDisplayNode { private var state: State = State(muted: false, filled: false, color: .black) private var transitionContext: TransitionContext? - override init() { + override public init() { super.init() self.isOpaque = false } - func update(state: State, animated: Bool) { + public func update(state: State, animated: Bool) { var animated = animated if !self.hasState { self.hasState = true diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatParticipantItem.swift b/submodules/TelegramCallsUI/Sources/VoiceChatParticipantItem.swift index 81722b4d4f..820b98cd76 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatParticipantItem.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatParticipantItem.swift @@ -344,7 +344,7 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode { self.highlightedBackgroundNode = ASDisplayNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.isAccessibilityElement = true diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatTileGridNode.swift b/submodules/TelegramCallsUI/Sources/VoiceChatTileGridNode.swift index 1b8b43df66..037905bdeb 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatTileGridNode.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatTileGridNode.swift @@ -257,7 +257,7 @@ final class VoiceChatTilesGridItemNode: ListViewItemNode { self.limitLabel = TextNode() self.limitLabel.alpha = 0.0 - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.cornersNode) diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift b/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift index 3fb3b29b7d..6f4abcd3e6 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift @@ -12,6 +12,22 @@ private let pink = UIColor(rgb: 0xef436c) private let latePurple = UIColor(rgb: 0x974aa9) private let latePink = UIColor(rgb: 0xf0436c) +private func textForTimeout(value: Int32) -> String { + if value < 3600 { + let minutes = value / 60 + let seconds = value % 60 + let secondsPadding = seconds < 10 ? "0" : "" + return "\(minutes):\(secondsPadding)\(seconds)" + } else { + let hours = value / 3600 + let minutes = (value % 3600) / 60 + let minutesPadding = minutes < 10 ? "0" : "" + let seconds = value % 60 + let secondsPadding = seconds < 10 ? "0" : "" + return "\(hours):\(minutesPadding)\(minutes):\(secondsPadding)\(seconds)" + } +} + final class VoiceChatTimerNode: ASDisplayNode { private let strings: PresentationStrings private let dateTimeFormat: PresentationDateTimeFormat diff --git a/submodules/TelegramUI/BUILD b/submodules/TelegramUI/BUILD index 3ea6a6b64d..ce5d42a396 100644 --- a/submodules/TelegramUI/BUILD +++ b/submodules/TelegramUI/BUILD @@ -505,6 +505,7 @@ swift_library( "//submodules/TelegramUI/Components/AdPanelHeaderPanelComponent", "//submodules/TelegramUI/Components/MessageFeeHeaderPanelComponent", "//submodules/TelegramUI/Components/LegacyChatHeaderPanelComponent", + "//submodules/TelegramUI/Components/GroupCallHeaderPanelComponent", "//submodules/TelegramUI/Components/Chat/ChatSearchNavigationContentNode", "//submodules/TelegramUI/Components/Settings/PasskeysScreen", "//submodules/TelegramUI/Components/Gifts/GiftDemoScreen", diff --git a/submodules/TelegramUI/Components/AnimatedTextComponent/Sources/AnimatedTextComponent.swift b/submodules/TelegramUI/Components/AnimatedTextComponent/Sources/AnimatedTextComponent.swift index 42ab7770f9..0d6438d422 100644 --- a/submodules/TelegramUI/Components/AnimatedTextComponent/Sources/AnimatedTextComponent.swift +++ b/submodules/TelegramUI/Components/AnimatedTextComponent/Sources/AnimatedTextComponent.swift @@ -263,10 +263,6 @@ public final class AnimatedTextComponent: Component { continue characterLoop } else { - if text.hasPrefix(" ") { - size.height = max(size.height, ceil(spaceSize.height)) - size.width += max(0.0, ceil(spaceSize.width)) - } if text.hasSuffix(" ") { addTrailingSpace = true } @@ -295,6 +291,7 @@ public final class AnimatedTextComponent: Component { if characterComponentView.superview == nil { characterComponentView.layer.rasterizationScale = UIScreenScale self.addSubview(characterComponentView) + characterComponentView.layer.anchorPoint = CGPoint() animateIn = true } @@ -314,8 +311,9 @@ public final class AnimatedTextComponent: Component { } characterComponentView.bounds = CGRect(origin: CGPoint(), size: characterFrame.size) - let deltaPosition = CGPoint(x: characterFrame.midX - characterComponentView.frame.midX, y: characterFrame.midY - characterComponentView.frame.midY) - characterComponentView.center = characterFrame.center + + let deltaPosition = CGPoint(x: characterFrame.minX - characterComponentView.frame.minX, y: characterFrame.minY - characterComponentView.frame.minY) + characterComponentView.center = characterFrame.origin characterComponentView.layer.animatePosition(from: CGPoint(x: -deltaPosition.x, y: -deltaPosition.y), to: CGPoint(), duration: 0.4, delay: delayNorm * delayWidth, timingFunction: kCAMediaTimingFunctionSpring, additive: true) } } diff --git a/submodules/TelegramUI/Components/AsyncListComponent/Sources/AsyncListComponent.swift b/submodules/TelegramUI/Components/AsyncListComponent/Sources/AsyncListComponent.swift index 4b7fac1b88..5d798af850 100644 --- a/submodules/TelegramUI/Components/AsyncListComponent/Sources/AsyncListComponent.swift +++ b/submodules/TelegramUI/Components/AsyncListComponent/Sources/AsyncListComponent.swift @@ -363,7 +363,7 @@ public final class AsyncListComponent: Component { init() { self.contentContainer = UIView() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.view.addSubview(self.contentContainer) diff --git a/submodules/TelegramUI/Components/Chat/ChatBotInfoItem/Sources/ChatBotInfoItem.swift b/submodules/TelegramUI/Components/Chat/ChatBotInfoItem/Sources/ChatBotInfoItem.swift index 19a4ebbc66..ed37649c86 100644 --- a/submodules/TelegramUI/Components/Chat/ChatBotInfoItem/Sources/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatBotInfoItem/Sources/ChatBotInfoItem.swift @@ -118,7 +118,7 @@ public final class ChatBotInfoItemNode: ListViewItemNode { self.textNode = TextNode() self.titleNode = TextNode() - super.init(layerBacked: false, dynamicBounce: true, rotated: true) + super.init(layerBacked: false, rotated: true) self.transform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift index 99026ce1a2..e706cb2c4b 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift @@ -645,7 +645,7 @@ public final class ChatMessageDateHeaderNodeImpl: ListViewItemHeaderNode, ChatMe let isRotated = controllerInteraction?.chatIsRotated ?? true - super.init(layerBacked: false, dynamicBounce: true, isRotated: isRotated, seeThrough: false) + super.init(layerBacked: false, isRotated: isRotated, seeThrough: false) if isRotated { self.transform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) @@ -1012,7 +1012,7 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat let isRotated = controllerInteraction?.chatIsRotated ?? true - super.init(layerBacked: false, dynamicBounce: true, isRotated: isRotated, seeThrough: false) + super.init(layerBacked: false, isRotated: isRotated, seeThrough: false) if isRotated { self.transform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatReplyCountItem.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatReplyCountItem.swift index 70311fed90..4c393049f5 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatReplyCountItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatReplyCountItem.swift @@ -81,7 +81,7 @@ public class ChatReplyCountItemNode: ListViewItemNode { self.backgroundColorNode = ASDisplayNode() - super.init(layerBacked: false, dynamicBounce: true, rotated: true) + super.init(layerBacked: false, rotated: true) self.addSubnode(self.labelNode) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatUnreadItem.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatUnreadItem.swift index 65c004db87..63c5f26b05 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatUnreadItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatUnreadItem.swift @@ -94,7 +94,7 @@ public class ChatUnreadItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() self.activateArea.accessibilityTraits = .staticText - super.init(layerBacked: false, dynamicBounce: true, rotated: true) + super.init(layerBacked: false, rotated: true) self.addSubnode(self.backgroundNode) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift index 2a3b973f25..161e9c0fec 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift @@ -664,7 +664,7 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { public var effectAnimationNodes: [ChatMessageTransitionNode.DecorationItemNode] = [] public required init(rotated: Bool) { - super.init(layerBacked: false, dynamicBounce: true, rotated: rotated) + super.init(layerBacked: false, rotated: rotated) if rotated { self.transform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift index 61fa256f8d..57779e8ee9 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift @@ -460,11 +460,13 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { override public func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat { self.validLayout = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) - var leftInset = leftInset - leftInset += 16.0 + var leftInset = leftInset + 8.0 + var rightInset = rightInset + 8.0 - var rightInset = rightInset - rightInset += 16.0 + if bottomInset <= 32.0 { + leftInset += 18.0 + rightInset += 18.0 + } let panelHeight = defaultHeight(metrics: metrics) diff --git a/submodules/TelegramUI/Components/Chat/ChatNewThreadInfoItem/Sources/ChatNewThreadInfoItem.swift b/submodules/TelegramUI/Components/Chat/ChatNewThreadInfoItem/Sources/ChatNewThreadInfoItem.swift index 0cdd733cb3..9870951c4e 100644 --- a/submodules/TelegramUI/Components/Chat/ChatNewThreadInfoItem/Sources/ChatNewThreadInfoItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatNewThreadInfoItem/Sources/ChatNewThreadInfoItem.swift @@ -108,7 +108,7 @@ public final class ChatNewThreadInfoItemNode: ListViewItemNode, ASGestureRecogni self.arrowView = UIImageView() - super.init(layerBacked: false, dynamicBounce: true, rotated: true) + super.init(layerBacked: false, rotated: true) self.transform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) diff --git a/submodules/TelegramUI/Components/Chat/ChatQrCodeScreen/Sources/ChatQrCodeScreen.swift b/submodules/TelegramUI/Components/Chat/ChatQrCodeScreen/Sources/ChatQrCodeScreen.swift index fd7cd24e75..88f49088f4 100644 --- a/submodules/TelegramUI/Components/Chat/ChatQrCodeScreen/Sources/ChatQrCodeScreen.swift +++ b/submodules/TelegramUI/Components/Chat/ChatQrCodeScreen/Sources/ChatQrCodeScreen.swift @@ -333,7 +333,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode { self.placeholderNode = StickerShimmerEffectNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) self.containerNode.addSubnode(self.imageNode) diff --git a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsController.swift b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsController.swift index ff8c1cd0ba..6c94d41404 100644 --- a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsController.swift +++ b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsController.swift @@ -49,7 +49,7 @@ public final class ChatRecentActionsController: TelegramBaseController { self.titleView = CounterControllerTitleView(theme: self.presentationData.theme) - super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData), mediaAccessoryPanelVisibility: .specific(size: .compact), locationBroadcastPanelSource: .none, groupCallPanelSource: .none) + super.init(context: context, navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData)) self.automaticallyControlPresentationContextLayout = false diff --git a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift index b3e9e0fc54..3a6597782c 100644 --- a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift @@ -130,7 +130,6 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { self.panelInfoButtonNode = HighlightableButtonNode() self.listNode = ListView() - self.listNode.dynamicBounceEnabled = false self.listNode.transform = CATransform3DMakeRotation(CGFloat(Double.pi), 0.0, 0.0, 1.0) self.listNode.accessibilityPageScrolledString = { row, count in return presentationData.strings.VoiceOver_ScrollStatus(row, count).string diff --git a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatFloatingTopicsPanel.swift b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatFloatingTopicsPanel.swift index 46b7f46431..e54789b9f7 100644 --- a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatFloatingTopicsPanel.swift +++ b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatFloatingTopicsPanel.swift @@ -151,8 +151,8 @@ public final class ChatFloatingTopicsPanel: Component { }, containerSize: CGSize(width: 72.0 + 8.0, height: availableSize.height) ) - let sidePanelFrame = CGRect(origin: CGPoint(), size: CGSize(width: 8.0 + 80.0, height: availableSize.height - 8.0 - environment.insets.bottom)) - let sidePanelBackgroundFrame = CGRect(origin: CGPoint(x: 8.0, y: 8.0), size: CGSize(width: 80.0, height: availableSize.height - 8.0 - 8.0 - environment.insets.bottom)) + let sidePanelFrame = CGRect(origin: CGPoint(x: 8.0, y: 0.0), size: CGSize(width: 16.0 + 80.0, height: availableSize.height - 8.0 - environment.insets.bottom)) + let sidePanelBackgroundFrame = CGRect(origin: CGPoint(x: 16.0, y: 8.0), size: CGSize(width: 80.0, height: availableSize.height - 8.0 - 8.0 - environment.insets.bottom)) currentPanelBackgroundFrame = sidePanelBackgroundFrame if let sidePanelView = sidePanel.view as? ChatSideTopicsPanel.View { if sidePanelView.superview == nil { @@ -160,7 +160,7 @@ public final class ChatFloatingTopicsPanel: Component { sidePanelView.clipsToBounds = true self.addSubview(sidePanelView) - sidePanelView.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: sidePanelSize.height, height: 8.0 + 40.0)) + sidePanelView.frame = CGRect(origin: CGPoint(x: 8.0, y: 0.0), size: CGSize(width: sidePanelSize.height, height: 8.0 + 40.0)) } transition.setFrame(view: sidePanelView, frame: sidePanelFrame) } @@ -168,7 +168,7 @@ public final class ChatFloatingTopicsPanel: Component { self.sidePanel = nil if let sidePanelView = sidePanel.view as? ChatSideTopicsPanel.View { sidePanelView.clipsToBounds = true - transition.setFrame(view: sidePanelView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: sidePanelView.bounds.width, height: 8.0 + 40.0)), completion: { [weak sidePanelView] _ in + transition.setFrame(view: sidePanelView, frame: CGRect(origin: CGPoint(x: 8.0, y: 0.0), size: CGSize(width: sidePanelView.bounds.width, height: 8.0 + 40.0)), completion: { [weak sidePanelView] _ in sidePanelView?.removeFromSuperview() }) } @@ -212,17 +212,17 @@ public final class ChatFloatingTopicsPanel: Component { right: 0.0 )) }, - containerSize: CGSize(width: availableSize.width, height: 8.0 + 40.0) + containerSize: CGSize(width: availableSize.width - 16.0, height: 8.0 + 40.0) ) - let topPanelFrame = CGRect(origin: CGPoint(), size: CGSize(width: availableSize.width - 8.0, height: 8.0 + 40.0)) - let topPanelBackgroundFrame = CGRect(origin: CGPoint(x: 8.0, y: 8.0), size: CGSize(width: availableSize.width - 8.0 - 8.0, height: 40.0)) + let topPanelFrame = CGRect(origin: CGPoint(x: 8.0, y: 0.0), size: CGSize(width: availableSize.width - 16.0, height: 8.0 + 40.0)) + let topPanelBackgroundFrame = CGRect(origin: CGPoint(x: 16.0, y: 8.0), size: CGSize(width: availableSize.width - 16.0 - 16.0, height: 40.0)) currentPanelBackgroundFrame = topPanelBackgroundFrame if let topPanelView = topPanel.view as? ChatSideTopicsPanel.View { if topPanelView.superview == nil { topPanelView.clipsToBounds = true topPanelView.layer.cornerRadius = 20.0 self.addSubview(topPanelView) - topPanelView.frame = CGRect(origin: CGPoint(), size: CGSize(width: 80.0 + 8.0, height: topPanelFrame.height)) + topPanelView.frame = CGRect(origin: CGPoint(x: 8.0, y: 0.0), size: CGSize(width: 80.0 + 16.0, height: topPanelFrame.height)) } transition.setFrame(view: topPanelView, frame: topPanelFrame) } @@ -230,7 +230,7 @@ public final class ChatFloatingTopicsPanel: Component { self.topPanel = nil if let topPanelView = topPanel.view as? ChatSideTopicsPanel.View { topPanelView.clipsToBounds = true - transition.setFrame(view: topPanelView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 8.0 + 72.0, height: topPanelView.bounds.height)), completion: { [weak topPanelView] _ in + transition.setFrame(view: topPanelView, frame: CGRect(origin: CGPoint(x: 8.0, y: 0.0), size: CGSize(width: 16.0 + 72.0, height: topPanelView.bounds.height)), completion: { [weak topPanelView] _ in topPanelView?.removeFromSuperview() }) } diff --git a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift index d703291312..872c9df914 100644 --- a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift +++ b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift @@ -464,7 +464,7 @@ public final class ChatSideTopicsPanel: Component { let titleSize = self.title.update( transition: .immediate, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: titleText, font: Font.regular(10.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.rootController.navigationBar.secondaryTextColor)), + text: .plain(NSAttributedString(string: titleText, font: Font.regular(10.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.chat.inputPanel.panelControlColor)), horizontalAlignment: .center, maximumNumberOfLines: 2 )), @@ -897,7 +897,7 @@ public final class ChatSideTopicsPanel: Component { let titleSize = self.title.update( transition: .immediate, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: titleText, font: Font.medium(14.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.rootController.navigationBar.secondaryTextColor)), + text: .plain(NSAttributedString(string: titleText, font: Font.medium(14.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.chat.inputPanel.panelControlColor)), horizontalAlignment: .center, maximumNumberOfLines: 2 )), @@ -1109,7 +1109,7 @@ public final class ChatSideTopicsPanel: Component { transition: .immediate, component: AnyComponent(BundleIconComponent( name: isReordering ? "Media Editor/Done" : "Chat/Title Panels/SidebarIcon", - tintColor: location == .side ? theme.rootController.navigationBar.accentTextColor : theme.rootController.navigationBar.secondaryTextColor, + tintColor: location == .side ? theme.rootController.navigationBar.accentTextColor : theme.chat.inputPanel.panelControlColor, maxSize: CGSize(width: 24.0, height: 24.0), scaleFactor: 1.0 )), @@ -1242,7 +1242,7 @@ public final class ChatSideTopicsPanel: Component { transition: .immediate, component: AnyComponent(BundleIconComponent( name: "Chat List/Tabs/IconChats", - tintColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.rootController.navigationBar.secondaryTextColor + tintColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.chat.inputPanel.panelControlColor )), environment: {}, containerSize: CGSize(width: 100.0, height: 100.0) @@ -1257,7 +1257,7 @@ public final class ChatSideTopicsPanel: Component { let titleSize = self.title.update( transition: .immediate, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: titleText, font: Font.regular(10.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.rootController.navigationBar.secondaryTextColor)), + text: .plain(NSAttributedString(string: titleText, font: Font.regular(10.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.chat.inputPanel.panelControlColor)), maximumNumberOfLines: 2 )), environment: {}, @@ -1394,7 +1394,7 @@ public final class ChatSideTopicsPanel: Component { let titleSize = self.title.update( transition: .immediate, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: titleText, font: Font.medium(14.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.rootController.navigationBar.secondaryTextColor)), + text: .plain(NSAttributedString(string: titleText, font: Font.medium(14.0), textColor: component.isSelected ? component.theme.rootController.navigationBar.accentTextColor : component.theme.chat.inputPanel.panelControlColor)), maximumNumberOfLines: 2 )), environment: {}, diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputActionButtonsNode/Sources/ChatTextInputActionButtonsNode.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputActionButtonsNode/Sources/ChatTextInputActionButtonsNode.swift index a4e00c92e0..9550c56159 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputActionButtonsNode/Sources/ChatTextInputActionButtonsNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputActionButtonsNode/Sources/ChatTextInputActionButtonsNode.swift @@ -149,7 +149,7 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag public let textNode: ImmediateAnimatedCountLabelNode public let expandMediaInputButton: HighlightTrackingButton - private let expandMediaInputButtonBackgroundView: GlassBackgroundView + public let expandMediaInputButtonBackgroundView: GlassBackgroundView private let expandMediaInputButtonIcon: GlassBackgroundView.ContentImageView private var effectBadgeView: EffectBadgeView? @@ -202,9 +202,9 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag self.expandMediaInputButton = HighlightTrackingButton() self.expandMediaInputButtonBackgroundView = GlassBackgroundView() self.expandMediaInputButtonBackgroundView.isUserInteractionEnabled = false - self.expandMediaInputButton.addSubview(self.expandMediaInputButtonBackgroundView) self.expandMediaInputButtonIcon = GlassBackgroundView.ContentImageView() self.expandMediaInputButtonBackgroundView.contentView.addSubview(self.expandMediaInputButtonIcon) + self.expandMediaInputButtonBackgroundView.contentView.addSubview(self.expandMediaInputButton) self.expandMediaInputButtonIcon.image = PresentationResourcesChat.chatInputPanelExpandButtonImage(presentationInterfaceState.theme) self.expandMediaInputButtonIcon.tintColor = theme.chat.inputPanel.panelControlColor self.expandMediaInputButtonIcon.setMonochromaticEffect(tintColor: theme.chat.inputPanel.panelControlColor) @@ -242,7 +242,7 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag self.sendContainerNode.view.addSubview(self.sendButtonBackgroundView) self.sendContainerNode.addSubnode(self.sendButton) self.sendContainerNode.addSubnode(self.textNode) - self.view.addSubview(self.expandMediaInputButton) + self.view.addSubview(self.expandMediaInputButtonBackgroundView) self.expandMediaInputButton.highligthedChanged = { [weak self] highlighted in guard let self else { @@ -402,7 +402,7 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag transition.updateFrame(view: self.expandMediaInputButton, frame: CGRect(origin: CGPoint(), size: size)) transition.updateFrame(view: self.expandMediaInputButtonBackgroundView, frame: CGRect(origin: CGPoint(), size: size)) - self.expandMediaInputButtonBackgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: ComponentTransition(transition)) + self.expandMediaInputButtonBackgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), isInteractive: true, transition: ComponentTransition(transition)) if let image = self.expandMediaInputButtonIcon.image { let expandIconFrame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) * 0.5), y: floor((size.height - image.size.height) * 0.5)), size: image.size) self.expandMediaInputButtonIcon.center = expandIconFrame.center diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift index 99ef8a56b5..913235e864 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift @@ -703,7 +703,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg self.sendActionButtons.micButtonBackgroundView.alpha = 0.0 self.sendActionButtons.micButton.alpha = 0.0 self.sendActionButtons.micButtonTintMaskView.alpha = 0.0 - self.sendActionButtons.expandMediaInputButton.alpha = 0.0 + self.sendActionButtons.expandMediaInputButtonBackgroundView.alpha = 0.0 self.mediaActionButtons = ChatTextInputActionButtonsNode(context: context, presentationInterfaceState: presentationInterfaceState, presentationContext: presentationContext, presentController: presentController) self.mediaActionButtons.sendContainerNode.alpha = 0.0 @@ -901,7 +901,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg self.mediaActionButtons.updateAccessibility() self.mediaActionButtons.expandMediaInputButton.addTarget(self, action: #selector(self.expandButtonPressed), for: .touchUpInside) - self.mediaActionButtons.expandMediaInputButton.alpha = 0.0 + self.mediaActionButtons.expandMediaInputButtonBackgroundView.alpha = 0.0 self.searchLayoutClearButton.highligthedChanged = { [weak self] highlighted in guard let self else { @@ -4466,15 +4466,15 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg } if mediaInputIsActive && !hideExpandMediaInput { - if self.mediaActionButtons.expandMediaInputButton.alpha.isZero { - self.mediaActionButtons.expandMediaInputButton.alpha = 1.0 + if self.mediaActionButtons.expandMediaInputButtonBackgroundView.alpha.isZero { + self.mediaActionButtons.expandMediaInputButtonBackgroundView.alpha = 1.0 if alphaTransition.isAnimated { - self.mediaActionButtons.expandMediaInputButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + self.mediaActionButtons.expandMediaInputButtonBackgroundView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) } } } else { - if !self.mediaActionButtons.expandMediaInputButton.alpha.isZero { - alphaTransition.updateAlpha(layer: self.mediaActionButtons.expandMediaInputButton.layer, alpha: 0.0) + if !self.mediaActionButtons.expandMediaInputButtonBackgroundView.alpha.isZero { + alphaTransition.updateAlpha(layer: self.mediaActionButtons.expandMediaInputButtonBackgroundView.layer, alpha: 0.0) } } diff --git a/submodules/TelegramUI/Components/Chat/ChatUserInfoItem/Sources/ChatUserInfoItem.swift b/submodules/TelegramUI/Components/Chat/ChatUserInfoItem/Sources/ChatUserInfoItem.swift index c9bab92dc5..3b80c51c1f 100644 --- a/submodules/TelegramUI/Components/Chat/ChatUserInfoItem/Sources/ChatUserInfoItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatUserInfoItem/Sources/ChatUserInfoItem.swift @@ -170,7 +170,7 @@ public final class ChatUserInfoItemNode: ListViewItemNode, ASGestureRecognizerDe self.disclaimerTextNode.textNode.isUserInteractionEnabled = false self.disclaimerTextNode.textNode.displaysAsynchronously = false - super.init(layerBacked: false, dynamicBounce: true, rotated: true) + super.init(layerBacked: false, rotated: true) self.transform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) diff --git a/submodules/TelegramUI/Components/Chat/EditableTokenListNode/BUILD b/submodules/TelegramUI/Components/Chat/EditableTokenListNode/BUILD index cb19c19e8e..4b23fb1231 100644 --- a/submodules/TelegramUI/Components/Chat/EditableTokenListNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/EditableTokenListNode/BUILD @@ -16,6 +16,9 @@ swift_library( "//submodules/TelegramPresentationData", "//submodules/AvatarNode", "//submodules/AccountContext", + "//submodules/TelegramUI/Components/GlassBackgroundComponent", + "//submodules/ComponentFlow", + "//submodules/Components/ComponentDisplayAdapters", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Chat/EditableTokenListNode/Sources/EditableTokenListNode.swift b/submodules/TelegramUI/Components/Chat/EditableTokenListNode/Sources/EditableTokenListNode.swift index a2ec801bab..2078237391 100644 --- a/submodules/TelegramUI/Components/Chat/EditableTokenListNode/Sources/EditableTokenListNode.swift +++ b/submodules/TelegramUI/Components/Chat/EditableTokenListNode/Sources/EditableTokenListNode.swift @@ -6,6 +6,9 @@ import TelegramCore import TelegramPresentationData import AvatarNode import AccountContext +import GlassBackgroundComponent +import ComponentFlow +import ComponentDisplayAdapters public struct EditableTokenListToken { public enum Subject { @@ -26,23 +29,6 @@ public struct EditableTokenListToken { } } -private let caretIndicatorImage = generateVerticallyStretchableFilledCircleImage(radius: 1.0, color: UIColor(rgb: 0x3350ee)) - -private func caretAnimation() -> CAAnimation { - let animation = CAKeyframeAnimation(keyPath: "opacity") - animation.values = [1.0 as NSNumber, 0.0 as NSNumber, 1.0 as NSNumber, 1.0 as NSNumber] - let firstDuration = 0.3 - let secondDuration = 0.25 - let restDuration = 0.35 - let duration = firstDuration + secondDuration + restDuration - let keyTimes: [NSNumber] = [0.0 as NSNumber, (firstDuration / duration) as NSNumber, ((firstDuration + secondDuration) / duration) as NSNumber, ((firstDuration + secondDuration + restDuration) / duration) as NSNumber] - - animation.keyTimes = keyTimes - animation.duration = duration - animation.repeatCount = Float.greatestFiniteMagnitude - return animation -} - private func generateRemoveIcon(_ color: UIColor) -> UIImage? { return generateImage(CGSize(width: 22.0, height: 22.0), rotatedContext: { size, context in context.clear(CGRect(origin: .zero, size: size)) @@ -61,35 +47,10 @@ private func generateRemoveIcon(_ color: UIColor) -> UIImage? { }) } -public final class EditableTokenListNodeTheme { - public let backgroundColor: UIColor - public let separatorColor: UIColor - public let placeholderTextColor: UIColor - public let primaryTextColor: UIColor - public let tokenBackgroundColor: UIColor - public let selectedTextColor: UIColor - public let selectedBackgroundColor: UIColor - public let accentColor: UIColor - public let keyboardColor: PresentationThemeKeyboardColor - - public init(backgroundColor: UIColor, separatorColor: UIColor, placeholderTextColor: UIColor, primaryTextColor: UIColor, tokenBackgroundColor: UIColor, selectedTextColor: UIColor, selectedBackgroundColor: UIColor, accentColor: UIColor, keyboardColor: PresentationThemeKeyboardColor) { - self.backgroundColor = backgroundColor - self.separatorColor = separatorColor - self.placeholderTextColor = placeholderTextColor - self.primaryTextColor = primaryTextColor - self.tokenBackgroundColor = tokenBackgroundColor - self.selectedTextColor = selectedTextColor - self.selectedBackgroundColor = selectedBackgroundColor - self.accentColor = accentColor - self.keyboardColor = keyboardColor - } -} - private final class TokenNode: ASDisplayNode { private let context: AccountContext - private let presentationTheme: PresentationTheme + private let theme: PresentationTheme - let theme: EditableTokenListNodeTheme let token: EditableTokenListToken let avatarNode: AvatarNode let categoryAvatarNode: ASImageNode @@ -98,23 +59,9 @@ private final class TokenNode: ASDisplayNode { let backgroundNode: ASImageNode let selectedBackgroundNode: ASImageNode var isSelected: Bool = false - // didSet { - // if self.isSelected != oldValue { - // self.titleNode.attributedText = NSAttributedString(string: token.title, font: Font.regular(14.0), textColor: self.isSelected ? self.theme.selectedTextColor : self.theme.primaryTextColor) - // self.titleNode.redrawIfPossible() - // self.backgroundNode.isHidden = self.isSelected - // self.selectedBackgroundNode.isHidden = !self.isSelected - // - // self.avatarNode.isHidden = self.isSelected - // self.categoryAvatarNode.isHidden = self.isSelected - // self.removeIconNode.isHidden = !self.isSelected - // } - // } - // } - init(context: AccountContext, presentationTheme: PresentationTheme, theme: EditableTokenListNodeTheme, token: EditableTokenListToken, isSelected: Bool) { + init(context: AccountContext, theme: PresentationTheme, token: EditableTokenListToken, isSelected: Bool) { self.context = context - self.presentationTheme = presentationTheme self.theme = theme self.token = token self.titleNode = ASTextNode() @@ -131,39 +78,39 @@ private final class TokenNode: ASDisplayNode { self.removeIconNode.alpha = 0.0 self.removeIconNode.displaysAsynchronously = false self.removeIconNode.displayWithoutProcessing = true - self.removeIconNode.image = generateRemoveIcon(theme.selectedTextColor) + self.removeIconNode.image = generateRemoveIcon(theme.list.itemCheckColors.foregroundColor) - let cornerRadius: CGFloat + let cornerDiameter: CGFloat switch token.subject { case .peer: - cornerRadius = 24.0 + cornerDiameter = 28.0 case .category: - cornerRadius = 14.0 + cornerDiameter = 14.0 } self.backgroundNode = ASImageNode() self.backgroundNode.displaysAsynchronously = false self.backgroundNode.displayWithoutProcessing = true - self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: cornerRadius, color: theme.tokenBackgroundColor) + self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: cornerDiameter, color: theme.list.itemCheckColors.strokeColor.withAlphaComponent(0.25)) self.selectedBackgroundNode = ASImageNode() self.selectedBackgroundNode.alpha = 0.0 self.selectedBackgroundNode.displaysAsynchronously = false self.selectedBackgroundNode.displayWithoutProcessing = true - self.selectedBackgroundNode.image = generateStretchableFilledCircleImage(diameter: cornerRadius, color: theme.selectedBackgroundColor) + self.selectedBackgroundNode.image = generateStretchableFilledCircleImage(diameter: cornerDiameter, color: theme.list.itemCheckColors.fillColor) super.init() self.addSubnode(self.backgroundNode) self.addSubnode(self.selectedBackgroundNode) - self.titleNode.attributedText = NSAttributedString(string: token.title, font: Font.regular(14.0), textColor: self.isSelected ? self.theme.selectedTextColor : self.theme.primaryTextColor) + self.titleNode.attributedText = NSAttributedString(string: token.title, font: Font.regular(15.0), textColor: self.isSelected ? self.theme.list.itemCheckColors.foregroundColor : self.theme.list.itemPrimaryTextColor) self.addSubnode(self.titleNode) self.addSubnode(self.removeIconNode) switch token.subject { case let .peer(peer): self.addSubnode(self.avatarNode) - self.avatarNode.setPeer(context: context, theme: presentationTheme, peer: peer) + self.avatarNode.setPeer(context: context, theme: theme, peer: peer) case let .category(image): self.addSubnode(self.categoryAvatarNode) self.categoryAvatarNode.image = image @@ -182,9 +129,9 @@ private final class TokenNode: ASDisplayNode { if titleSize.width.isZero { return } - self.backgroundNode.frame = self.bounds.insetBy(dx: 2.0, dy: 2.0) - self.selectedBackgroundNode.frame = self.bounds.insetBy(dx: 2.0, dy: 2.0) - self.avatarNode.frame = CGRect(origin: CGPoint(x: 3.0, y: 3.0), size: CGSize(width: 22.0, height: 22.0)) + self.backgroundNode.frame = self.bounds + self.selectedBackgroundNode.frame = self.bounds + self.avatarNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: self.bounds.height, height: self.bounds.height)) self.categoryAvatarNode.frame = self.avatarNode.frame self.removeIconNode.frame = self.avatarNode.frame @@ -243,91 +190,70 @@ private final class TokenNode: ASDisplayNode { } } - self.titleNode.attributedText = NSAttributedString(string: token.title, font: Font.regular(14.0), textColor: self.isSelected ? self.theme.selectedTextColor : self.theme.primaryTextColor) + self.titleNode.attributedText = NSAttributedString(string: token.title, font: Font.regular(15.0), textColor: self.isSelected ? self.theme.list.itemCheckColors.foregroundColor : self.theme.list.itemPrimaryTextColor) self.titleNode.redrawIfPossible() } } -private final class CaretIndicatorNode: ASImageNode { - override func willEnterHierarchy() { - super.willEnterHierarchy() - - if self.layer.animation(forKey: "blink") == nil { - self.layer.add(caretAnimation(), forKey: "blink") - } - } -} - public final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { private let context: AccountContext - private let presentationTheme: PresentationTheme + private let theme: PresentationTheme private let placeholder: String private let shortPlaceholder: String? - private let theme: EditableTokenListNodeTheme - private let backgroundNode: NavigationBackgroundNode + private let backgroundContainer: GlassBackgroundContainerView + private let backgroundView: GlassBackgroundView private let scrollNode: ASScrollNode private let placeholderNode: ASTextNode private var tokenNodes: [TokenNode] = [] - private let separatorNode: ASDisplayNode private let textFieldScrollNode: ASScrollNode private let textFieldNode: TextFieldNode - private let caretIndicatorNode: CaretIndicatorNode private var selectedTokenId: AnyHashable? public var textUpdated: ((String) -> Void)? public var deleteToken: ((AnyHashable) -> Void)? public var textReturned: (() -> Void)? - public init(context: AccountContext, presentationTheme: PresentationTheme, theme: EditableTokenListNodeTheme, placeholder: String, shortPlaceholder: String? = nil) { + public init(context: AccountContext, theme: PresentationTheme, placeholder: String, shortPlaceholder: String? = nil) { self.context = context - self.presentationTheme = presentationTheme self.theme = theme self.placeholder = placeholder self.shortPlaceholder = shortPlaceholder - self.backgroundNode = NavigationBackgroundNode(color: theme.backgroundColor) + self.backgroundContainer = GlassBackgroundContainerView() + self.backgroundView = GlassBackgroundView() + self.backgroundContainer.contentView.addSubview(self.backgroundView) self.scrollNode = ASScrollNode() - self.scrollNode.view.alwaysBounceVertical = true + self.scrollNode.view.alwaysBounceVertical = false + self.scrollNode.clipsToBounds = true self.placeholderNode = ASTextNode() self.placeholderNode.isUserInteractionEnabled = false self.placeholderNode.maximumNumberOfLines = 1 - self.placeholderNode.attributedText = NSAttributedString(string: placeholder, font: Font.regular(15.0), textColor: theme.placeholderTextColor) + self.placeholderNode.attributedText = NSAttributedString(string: placeholder, font: Font.regular(15.0), textColor: theme.list.itemPlaceholderTextColor) self.textFieldScrollNode = ASScrollNode() self.textFieldNode = TextFieldNode() self.textFieldNode.textField.font = Font.regular(15.0) - self.textFieldNode.textField.textColor = theme.primaryTextColor + self.textFieldNode.textField.textColor = theme.list.itemPrimaryTextColor self.textFieldNode.textField.autocorrectionType = .no self.textFieldNode.textField.returnKeyType = .done - self.textFieldNode.textField.keyboardAppearance = theme.keyboardColor.keyboardAppearance - self.textFieldNode.textField.tintColor = theme.accentColor - - self.caretIndicatorNode = CaretIndicatorNode() - self.caretIndicatorNode.isLayerBacked = true - self.caretIndicatorNode.displayWithoutProcessing = true - self.caretIndicatorNode.displaysAsynchronously = false - self.caretIndicatorNode.image = caretIndicatorImage - - self.separatorNode = ASDisplayNode() - self.separatorNode.isLayerBacked = true - self.separatorNode.backgroundColor = theme.separatorColor + self.textFieldNode.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance + self.textFieldNode.textField.tintColor = theme.list.itemAccentColor super.init() - self.addSubnode(self.backgroundNode) + + self.view.addSubview(self.backgroundContainer) + self.addSubnode(self.scrollNode) - self.addSubnode(self.separatorNode) self.scrollNode.addSubnode(self.placeholderNode) self.scrollNode.addSubnode(self.textFieldScrollNode) self.textFieldScrollNode.addSubnode(self.textFieldNode) - //self.scrollNode.addSubnode(self.caretIndicatorNode) - self.clipsToBounds = true self.textFieldNode.textField.delegate = self self.textFieldNode.textField.addTarget(self, action: #selector(self.textFieldChanged(_:)), for: .editingChanged) @@ -357,7 +283,7 @@ public final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { placeholderSnapshot = self.placeholderNode.layer.snapshotContentTreeAsView() placeholderSnapshot?.frame = self.placeholderNode.frame } - self.placeholderNode.attributedText = NSAttributedString(string: placeholder, font: Font.regular(15.0), textColor: self.theme.placeholderTextColor) + self.placeholderNode.attributedText = NSAttributedString(string: placeholder, font: Font.regular(15.0), textColor: self.theme.list.itemPlaceholderTextColor) } for i in (0 ..< self.tokenNodes.count).reversed() { @@ -380,8 +306,7 @@ public final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { } let sideInset: CGFloat = 12.0 + leftInset - let verticalInset: CGFloat = 6.0 - + let verticalInset: CGFloat = 8.0 var animationDelay = 0.0 var currentOffset = CGPoint(x: sideInset, y: verticalInset) @@ -398,7 +323,7 @@ public final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { if let currentNode = currentNode { tokenNode = currentNode } else { - tokenNode = TokenNode(context: self.context, presentationTheme: self.presentationTheme, theme: self.theme, token: token, isSelected: self.selectedTokenId != nil && token.id == self.selectedTokenId!) + tokenNode = TokenNode(context: self.context, theme: self.theme, token: token, isSelected: self.selectedTokenId != nil && token.id == self.selectedTokenId!) self.tokenNodes.append(tokenNode) self.scrollNode.addSubnode(tokenNode) animateIn = true @@ -407,10 +332,10 @@ public final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { let tokenSize = tokenNode.measure(CGSize(width: max(1.0, width - sideInset - sideInset), height: CGFloat.greatestFiniteMagnitude)) if tokenSize.width + currentOffset.x >= width - sideInset && !currentOffset.x.isEqual(to: sideInset) { currentOffset.x = sideInset - currentOffset.y += tokenSize.height + currentOffset.y += tokenSize.height + 6.0 } let tokenFrame = CGRect(origin: CGPoint(x: currentOffset.x, y: currentOffset.y), size: tokenSize) - currentOffset.x += ceil(tokenSize.width) + currentOffset.x += ceil(tokenSize.width) + 6.0 if animateIn { tokenNode.frame = tokenFrame @@ -451,7 +376,7 @@ public final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { let placeholderSize = self.placeholderNode.measure(CGSize(width: max(1.0, width - sideInset - sideInset), height: CGFloat.greatestFiniteMagnitude)) if width - currentOffset.x < placeholderSize.width { - currentOffset.y += 28.0 + currentOffset.y += 28.0 + 6.0 currentOffset.x = sideInset } @@ -472,42 +397,45 @@ public final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { } let textNodeFrame = CGRect(origin: CGPoint(x: currentOffset.x + 4.0, y: currentOffset.y + UIScreenPixel), size: CGSize(width: width - currentOffset.x - sideInset - 8.0, height: 28.0)) - let caretNodeFrame = CGRect(origin: CGPoint(x: textNodeFrame.minX, y: textNodeFrame.minY + 4.0 - UIScreenPixel), size: CGSize(width: 2.0, height: 19.0 + UIScreenPixel)) if case .immediate = transition { transition.updateFrame(node: self.textFieldScrollNode, frame: textNodeFrame) transition.updateFrame(node: self.textFieldNode, frame: CGRect(origin: CGPoint(), size: textNodeFrame.size)) - transition.updateFrame(node: self.caretIndicatorNode, frame: caretNodeFrame) } else { let previousFrame = self.textFieldScrollNode.frame self.textFieldScrollNode.frame = textNodeFrame self.textFieldScrollNode.layer.animateFrame(from: previousFrame, to: textNodeFrame, duration: 0.2 + animationDelay, timingFunction: kCAMediaTimingFunctionSpring) transition.updateFrame(node: self.textFieldNode, frame: CGRect(origin: CGPoint(), size: textNodeFrame.size)) - - let previousCaretFrame = self.caretIndicatorNode.frame - self.caretIndicatorNode.frame = caretNodeFrame - self.caretIndicatorNode.layer.animateFrame(from: previousCaretFrame, to: caretNodeFrame, duration: 0.2 + animationDelay, timingFunction: kCAMediaTimingFunctionSpring) } let previousContentHeight = self.scrollNode.view.contentSize.height - let contentHeight = currentOffset.y + 29.0 + verticalInset + let contentHeight = currentOffset.y + 28.0 + verticalInset let nodeHeight = min(contentHeight, 110.0) - transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: UIScreenPixel))) transition.updateFrame(node: self.scrollNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: nodeHeight))) + transition.updateCornerRadius(node: self.scrollNode, cornerRadius: min(44.0, nodeHeight) * 0.5) + self.scrollNode.view.scrollIndicatorInsets = UIEdgeInsets(top: 16.0, left: 0.0, bottom: 16.0, right: 0.0) if !abs(previousContentHeight - contentHeight).isLess(than: CGFloat.ulpOfOne) { let contentOffset = CGPoint(x: 0.0, y: max(0.0, contentHeight - nodeHeight)) - if case .immediate = transition { - self.scrollNode.view.contentOffset = contentOffset - } else { - transition.updateBounds(node: self.scrollNode, bounds: CGRect(origin: CGPoint(x: 0.0, y: contentOffset.y), size: self.scrollNode.bounds.size)) + if self.scrollNode.view.contentOffset != contentOffset { + if case .immediate = transition { + self.scrollNode.view.contentOffset = contentOffset + } else { + //transition.animateOffsetAdditive(node: self.scrollNode, offset: self.scrollNode.view.contentOffset.y - contentOffset.y) + } } } - self.scrollNode.view.contentSize = CGSize(width: width, height: contentHeight) + if self.scrollNode.view.contentSize != CGSize(width: width, height: contentHeight) { + self.scrollNode.view.contentSize = CGSize(width: width, height: contentHeight) + } - transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: nodeHeight))) - self.backgroundNode.update(size: self.backgroundNode.bounds.size, transition: transition) + let backgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: width, height: nodeHeight)) + self.backgroundContainer.update(size: backgroundFrame.size, isDark: self.theme.overallDarkAppearance, transition: ComponentTransition(transition)) + transition.updateFrame(view: self.backgroundContainer, frame: backgroundFrame) + + self.backgroundView.update(size: backgroundFrame.size, cornerRadius: min(44.0, backgroundFrame.height) * 0.5, isDark: self.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: UIColor(white: self.theme.overallDarkAppearance ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, transition: ComponentTransition(transition)) + transition.updateFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(), size: backgroundFrame.size)) return nodeHeight } @@ -528,15 +456,9 @@ public final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { } public func textFieldDidBeginEditing(_ textField: UITextField) { - /*if self.caretIndicatorNode.supernode == self { - self.caretIndicatorNode.removeFromSupernode() - }*/ } public func textFieldDidEndEditing(_ textField: UITextField) { - /*if self.caretIndicatorNode.supernode != self.scrollNode { - self.scrollNode.addSubnode(self.caretIndicatorNode) - }*/ } public func setText(_ text: String) { diff --git a/submodules/TelegramUI/Components/ChatFolderLinkPreviewScreen/Sources/ChatFolderLinkPreviewScreen.swift b/submodules/TelegramUI/Components/ChatFolderLinkPreviewScreen/Sources/ChatFolderLinkPreviewScreen.swift index 7b623f3485..8aefc908a3 100644 --- a/submodules/TelegramUI/Components/ChatFolderLinkPreviewScreen/Sources/ChatFolderLinkPreviewScreen.swift +++ b/submodules/TelegramUI/Components/ChatFolderLinkPreviewScreen/Sources/ChatFolderLinkPreviewScreen.swift @@ -1269,7 +1269,10 @@ private final class ChatFolderLinkPreviewScreenComponent: Component { if let controller = environment.controller() { let subLayout = ContainerViewLayout( - size: availableSize, metrics: environment.metrics, deviceMetrics: environment.deviceMetrics, intrinsicInsets: UIEdgeInsets(top: 0.0, left: sideInset - 12.0, bottom: bottomPanelHeight, right: sideInset), + size: availableSize, + metrics: environment.metrics, + deviceMetrics: environment.deviceMetrics, + intrinsicInsets: UIEdgeInsets(top: 0.0, left: sideInset - 12.0, bottom: bottomPanelHeight, right: sideInset), safeInsets: UIEdgeInsets(), additionalInsets: UIEdgeInsets(), statusBarHeight: nil, diff --git a/submodules/TelegramUI/Components/ChatList/ChatListHeaderNoticeComponent/Sources/ChatListNoticeItem.swift b/submodules/TelegramUI/Components/ChatList/ChatListHeaderNoticeComponent/Sources/ChatListNoticeItem.swift index 420975850f..7c7cb283e4 100644 --- a/submodules/TelegramUI/Components/ChatList/ChatListHeaderNoticeComponent/Sources/ChatListNoticeItem.swift +++ b/submodules/TelegramUI/Components/ChatList/ChatListHeaderNoticeComponent/Sources/ChatListNoticeItem.swift @@ -130,7 +130,7 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode { self.arrowNode = ASImageNode() self.separatorNode = ASDisplayNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.contentContainer.clipsToBounds = true self.clipsToBounds = true diff --git a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift index 3a54ef3fa0..f8842a4cc3 100644 --- a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift +++ b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift @@ -10,6 +10,7 @@ import AccountContext import TelegramCore import StoryPeerListComponent import EdgeEffect +import GlassBackgroundComponent private func searchScrollHeightValue() -> CGFloat { return 54.0 @@ -186,6 +187,7 @@ public final class ChatListNavigationBar: Component { public final class View: UIView { private let edgeEffectView: EdgeEffectView + private let headerBackgroundContainer: GlassBackgroundContainerView public let headerContent = ComponentView() public private(set) var searchContentNode: NavigationBarSearchContentNode? @@ -226,6 +228,9 @@ public final class ChatListNavigationBar: Component { override public init(frame: CGRect) { self.edgeEffectView = EdgeEffectView() + self.headerBackgroundContainer = GlassBackgroundContainerView() + self.headerBackgroundContainer.layer.anchorPoint = CGPoint() + self.bottomContentsContainer = UIView() self.bottomContentsContainer.layer.anchorPoint = CGPoint() @@ -495,9 +500,12 @@ public final class ChatListNavigationBar: Component { if let headerContentView = self.headerContent.view { if headerContentView.superview == nil { headerContentView.layer.anchorPoint = CGPoint() - self.addSubview(headerContentView) + self.addSubview(self.headerBackgroundContainer) + self.headerBackgroundContainer.contentView.addSubview(headerContentView) } - transition.setFrameWithAdditivePosition(view: headerContentView, frame: headerContentFrame) + transition.setFrameWithAdditivePosition(view: self.headerBackgroundContainer, frame: headerContentFrame) + self.headerBackgroundContainer.update(size: headerContentFrame.size, isDark: component.theme.overallDarkAppearance, transition: transition) + transition.setFrameWithAdditivePosition(view: headerContentView, frame: CGRect(origin: CGPoint(), size: headerContentFrame.size)) if (component.activeSearch != nil) != (headerContentView.alpha == 0.0) { headerContentView.alpha = component.activeSearch != nil ? 0.0 : 1.0 diff --git a/submodules/TelegramUI/Components/ChatThemeScreen/Sources/ChatThemeScreen.swift b/submodules/TelegramUI/Components/ChatThemeScreen/Sources/ChatThemeScreen.swift index 589c5c5582..b9fd6b0f2a 100644 --- a/submodules/TelegramUI/Components/ChatThemeScreen/Sources/ChatThemeScreen.swift +++ b/submodules/TelegramUI/Components/ChatThemeScreen/Sources/ChatThemeScreen.swift @@ -308,7 +308,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode { self.placeholderNode = StickerShimmerEffectNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) self.containerNode.addSubnode(self.imageNode) diff --git a/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleComponent.swift b/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleComponent.swift index 75403455c5..ac424cf01b 100644 --- a/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleComponent.swift +++ b/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleComponent.swift @@ -522,12 +522,21 @@ public final class ChatTitleComponent: Component { } isEnabled = false - case let .custom(text, _, enabled): - titleSegments = [AnimatedTextComponent.Item( - id: AnyHashable(0), - isUnbreakable: true, - content: .text(text) - )] + case let .custom(textItems, _, enabled): + titleSegments = textItems.map { item -> AnimatedTextComponent.Item in + let mappedContent: AnimatedTextComponent.Item.Content + switch item.content { + case let .number(value, minDigits): + mappedContent = .number(value, minDigits: minDigits) + case let .text(text): + mappedContent = .text(text) + } + return AnimatedTextComponent.Item( + id: item.id, + isUnbreakable: item.isUnbreakable, + content: mappedContent + ) + } isEnabled = enabled } @@ -982,9 +991,9 @@ public final class ChatTitleComponent: Component { font: Font.semibold(17.0), color: component.theme.chat.inputPanel.panelControlColor, items: titleSegments, - noDelay: true, - animateScale: false, - animateSlide: false, + noDelay: false, + animateScale: true, + animateSlide: true, blur: true )), environment: {}, diff --git a/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleView.swift b/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleView.swift index 243d62dec7..1b2e41fd6c 100644 --- a/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleView.swift +++ b/submodules/TelegramUI/Components/ChatTitleView/Sources/ChatTitleView.swift @@ -93,9 +93,26 @@ public enum ChatTitleContent: Equatable { case replies } + public struct TitleTextItem: Equatable { + public enum Content: Equatable { + case text(String) + case number(Int, minDigits: Int) + } + + public var id: AnyHashable + public var isUnbreakable: Bool + public var content: Content + + public init(id: AnyHashable, isUnbreakable: Bool = true, content: Content) { + self.id = id + self.isUnbreakable = isUnbreakable + self.content = content + } + } + case peer(peerView: PeerData, customTitle: String?, customSubtitle: String?, onlineMemberCount: (total: Int32?, recent: Int32?), isScheduledMessages: Bool, isMuted: Bool?, customMessageCount: Int?, isEnabled: Bool) case replyThread(type: ReplyThreadType, count: Int) - case custom(String, String?, Bool) + case custom(title: [TitleTextItem], subtitle: String?, isEnabled: Bool) public static func ==(lhs: ChatTitleContent, rhs: ChatTitleContent) -> Bool { switch lhs { @@ -397,8 +414,17 @@ public final class ChatTitleView: UIView, NavigationBarTitleView { } isEnabled = false - case let .custom(text, _, enabled): - segments = [.text(0, NSAttributedString(string: text, font: titleFont, textColor: titleTheme.rootController.navigationBar.primaryTextColor))] + case let .custom(textItems, _, enabled): + var nextId = -1 + segments = textItems.map { item -> AnimatedCountLabelNode.Segment in + nextId += 1 + switch item.content { + case let .number(value, _): + return .number(nextId, NSAttributedString(string: "\(value)", font: titleFont, textColor: titleTheme.rootController.navigationBar.primaryTextColor)) + case let .text(text): + return .text(nextId, NSAttributedString(string: text, font: titleFont, textColor: titleTheme.rootController.navigationBar.primaryTextColor)) + } + } isEnabled = enabled } diff --git a/submodules/TelegramUI/Components/Contacts/NewContactScreen/Sources/PhoneInputItem.swift b/submodules/TelegramUI/Components/Contacts/NewContactScreen/Sources/PhoneInputItem.swift index bfb74ff6a2..b87ce20240 100644 --- a/submodules/TelegramUI/Components/Contacts/NewContactScreen/Sources/PhoneInputItem.swift +++ b/submodules/TelegramUI/Components/Contacts/NewContactScreen/Sources/PhoneInputItem.swift @@ -175,7 +175,7 @@ final class PhoneInputItemNode: ListViewItemNode, ItemListItemNode { self.checkNode.displaysAsynchronously = false self.checkNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.phoneBackground) self.addSubnode(self.countryButton) diff --git a/submodules/TelegramUI/Components/EdgeEffect/Sources/EdgeEffect.swift b/submodules/TelegramUI/Components/EdgeEffect/Sources/EdgeEffect.swift index 793dd39372..ecd4bc66e6 100644 --- a/submodules/TelegramUI/Components/EdgeEffect/Sources/EdgeEffect.swift +++ b/submodules/TelegramUI/Components/EdgeEffect/Sources/EdgeEffect.swift @@ -29,6 +29,12 @@ public class EdgeEffectView: UIView { } public func update(content: UIColor, blur: Bool = false, alpha: CGFloat = 0.75, rect: CGRect, edge: Edge, edgeSize: CGFloat, transition: ComponentTransition) { + #if DEBUG && false + let content: UIColor = .blue + let blur: Bool = !"".isEmpty + self.backgroundColor = .blue + #endif + transition.setBackgroundColor(view: self.contentView, color: content) switch edge { diff --git a/submodules/TelegramUI/Components/Gifts/GiftLoadingShimmerView/Sources/GiftLoadingShimmerView.swift b/submodules/TelegramUI/Components/Gifts/GiftLoadingShimmerView/Sources/GiftLoadingShimmerView.swift index 5596735825..07ecd244b9 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftLoadingShimmerView/Sources/GiftLoadingShimmerView.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftLoadingShimmerView/Sources/GiftLoadingShimmerView.swift @@ -164,7 +164,7 @@ public final class GiftLoadingShimmerView: UIView { } } - var currentY: CGFloat = 39.0 + 7.0 + var currentY: CGFloat = 52.0 + 7.0 var rowIndex: Int = 0 let optionSpacing: CGFloat = 10.0 diff --git a/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/ChatGiftPreviewItem.swift b/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/ChatGiftPreviewItem.swift index 0175318100..f6c7f11a90 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/ChatGiftPreviewItem.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/ChatGiftPreviewItem.swift @@ -193,7 +193,7 @@ final class ChatGiftPreviewItemNode: ListViewItemNode { self.containerNode = ASDisplayNode() self.containerNode.subnodeTransform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.clipsToBounds = true self.isUserInteractionEnabled = false diff --git a/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/BUILD b/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/BUILD index 09e5fc712c..16f3589b91 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/BUILD +++ b/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/BUILD @@ -47,6 +47,7 @@ swift_library( "//submodules/TelegramUI/Components/TextFieldComponent", "//submodules/TelegramUI/Components/Gifts/GiftLoadingShimmerView", "//submodules/TelegramUI/Components/EdgeEffect", + "//submodules/TelegramUI/Components/GlassBackgroundComponent", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/FilterSelectorComponent.swift b/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/FilterSelectorComponent.swift index f282b15046..14f0697c32 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/FilterSelectorComponent.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/FilterSelectorComponent.swift @@ -9,21 +9,10 @@ import BundleIconComponent import TextFormat import AccountContext import LottieComponent +import TelegramPresentationData +import GlassBackgroundComponent public final class FilterSelectorComponent: Component { - public struct Colors: Equatable { - public var foreground: UIColor - public var background: UIColor - - public init( - foreground: UIColor, - background: UIColor - ) { - self.foreground = foreground - self.background = background - } - } - public struct Item: Equatable { public var id: AnyHashable public var index: Int @@ -51,18 +40,18 @@ public final class FilterSelectorComponent: Component { } public let context: AccountContext? - public let colors: Colors + public let theme: PresentationTheme public let items: [Item] public let selectedItemId: AnyHashable? public init( context: AccountContext? = nil, - colors: Colors, + theme: PresentationTheme, items: [Item], selectedItemId: AnyHashable? ) { self.context = context - self.colors = colors + self.theme = theme self.items = items self.selectedItemId = selectedItemId } @@ -71,7 +60,7 @@ public final class FilterSelectorComponent: Component { if lhs.context !== rhs.context { return false } - if lhs.colors != rhs.colors { + if lhs.theme !== rhs.theme { return false } if lhs.items != rhs.items { @@ -133,11 +122,11 @@ public final class FilterSelectorComponent: Component { self.component = component self.state = state - let baseHeight: CGFloat = 28.0 + let baseHeight: CGFloat = 36.0 var spacing: CGFloat = 6.0 - let itemFont = Font.semibold(14.0) + let itemFont = Font.medium(14.0) let allowScroll = true var innerContentWidth: CGFloat = 0.0 @@ -162,25 +151,19 @@ public final class FilterSelectorComponent: Component { let itemSize = itemView.title.update( transition: transition, - component: AnyComponent(PlainButtonComponent( - content: AnyComponent(ItemComponent( - context: component.context, - index: item.index, - iconName: item.iconName, - text: item.title, - font: itemFont, - color: component.colors.foreground, - backgroundColor: component.colors.background, - isSelected: itemId == component.selectedItemId - )), - effectAlignment: .center, - minSize: nil, + component: AnyComponent(ItemComponent( + context: component.context, + index: item.index, + iconName: item.iconName, + text: item.title, + font: itemFont, + theme: component.theme, + isSelected: itemId == component.selectedItemId, action: { [weak itemView] in if let view = itemView?.title.view { item.action(view) } - }, - animateScale: false + } )), environment: {}, containerSize: CGSize(width: 200.0, height: 100.0) @@ -261,9 +244,9 @@ private final class ItemComponent: Component { let iconName: String? let text: String let font: UIFont - let color: UIColor - let backgroundColor: UIColor + let theme: PresentationTheme let isSelected: Bool + let action: () -> Void init( context: AccountContext?, @@ -271,18 +254,18 @@ private final class ItemComponent: Component { iconName: String?, text: String, font: UIFont, - color: UIColor, - backgroundColor: UIColor, - isSelected: Bool + theme: PresentationTheme, + isSelected: Bool, + action: @escaping () -> Void ) { self.context = context self.index = index self.iconName = iconName self.text = text self.font = font - self.color = color - self.backgroundColor = backgroundColor + self.theme = theme self.isSelected = isSelected + self.action = action } static func ==(lhs: ItemComponent, rhs: ItemComponent) -> Bool { @@ -301,10 +284,7 @@ private final class ItemComponent: Component { if lhs.font != rhs.font { return false } - if lhs.color != rhs.color { - return false - } - if lhs.backgroundColor != rhs.backgroundColor { + if lhs.theme !== rhs.theme { return false } if lhs.isSelected != rhs.isSelected { @@ -317,7 +297,7 @@ private final class ItemComponent: Component { private var component: ItemComponent? private weak var state: EmptyComponentState? - private let background = ComponentView() + private let backgroundView: GlassBackgroundView private let title = ComponentView() private let icon = ComponentView() @@ -327,13 +307,24 @@ private final class ItemComponent: Component { private let playOnce = ActionSlot() override init(frame: CGRect) { + self.backgroundView = GlassBackgroundView() + super.init(frame: frame) + + self.addSubview(self.backgroundView) + self.backgroundView.contentView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.onTapGesture(_:)))) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + @objc private func onTapGesture(_ recognizer: UITapGestureRecognizer) { + if case .ended = recognizer.state { + self.component?.action() + } + } + func update(component: ItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { let previousComponent = self.component self.component = component @@ -342,7 +333,7 @@ private final class ItemComponent: Component { var animateTitleInDirection: CGFloat? if let previousComponent, previousComponent.text != component.text, !transition.animation.isImmediate, let titleView = self.title.view, let snapshotView = titleView.snapshotView(afterScreenUpdates: false) { snapshotView.frame = titleView.frame - self.addSubview(snapshotView) + self.backgroundView.contentView.addSubview(snapshotView) var direction: CGFloat = 1.0 if previousComponent.index < component.index { @@ -357,7 +348,7 @@ private final class ItemComponent: Component { animateTitleInDirection = direction } - let attributedTitle = NSAttributedString(string: component.text, font: component.font, textColor: component.color) + let attributedTitle = NSAttributedString(string: component.text, font: component.font, textColor: component.theme.chat.inputPanel.panelControlColor) let titleSize = self.title.update( transition: .immediate, component: AnyComponent(MultilineTextComponent( @@ -374,7 +365,7 @@ private final class ItemComponent: Component { transition: transition, component: AnyComponent(LottieComponent( content: LottieComponent.AppBundleContent(name: animationName), - color: component.color, + color: component.theme.chat.inputPanel.panelControlColor, playOnce: self.playOnce )), environment: {}, @@ -406,29 +397,14 @@ private final class ItemComponent: Component { } let spacing: CGFloat = 4.0 let totalWidth = titleSize.width + animationSize.width + spacing - let size = CGSize(width: totalWidth + leftPadding + padding, height: 28.0) + let size = CGSize(width: totalWidth + leftPadding + padding, height:36.0) - let backgroundSize = self.background.update( - transition: transition, - component: AnyComponent(RoundedRectangle( - color: component.backgroundColor, - cornerRadius: 14.0 - )), - environment: {}, - containerSize: size - ) - - if let backgroundView = self.background.view { - if backgroundView.superview == nil { - self.addSubview(backgroundView) - } - transition.setPosition(view: backgroundView, position: CGPoint(x: size.width / 2.0, y: size.height / 2.0)) - transition.setBounds(view: backgroundView, bounds: CGRect(origin: CGPoint(), size: backgroundSize)) - } + self.backgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: component.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: UIColor(white: component.theme.overallDarkAppearance ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, transition: transition) + transition.setFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(), size: size)) if let titleView = self.title.view { if titleView.superview == nil { - self.addSubview(titleView) + self.backgroundView.contentView.addSubview(titleView) } let titlePosition: CGPoint if let _ = component.iconName { @@ -446,7 +422,7 @@ private final class ItemComponent: Component { if let iconView = self.icon.view { if iconView.superview == nil { - self.addSubview(iconView) + self.backgroundView.contentView.addSubview(iconView) } let iconPosition: CGPoint if let _ = component.iconName { diff --git a/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/GiftStoreScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/GiftStoreScreen.swift index 676bb7aecc..34860682e3 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/GiftStoreScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftStoreScreen/Sources/GiftStoreScreen.swift @@ -28,6 +28,7 @@ import ContextUI import LottieComponent import GiftLoadingShimmerView import EdgeEffect +import GlassBackgroundComponent private let minimumCountToDisplayFilters = 18 @@ -84,7 +85,8 @@ final class GiftStoreScreenComponent: Component { private let edgeEffectView: EdgeEffectView private let cancelButton = ComponentView() private let sortButton = ComponentView() - + + private let balanceBackgroundView: GlassBackgroundView private let balanceTitle = ComponentView() private let balanceValue = ComponentView() private let balanceIcon = ComponentView() @@ -109,6 +111,8 @@ final class GiftStoreScreenComponent: Component { private var environment: EnvironmentType? override init(frame: CGRect) { + self.balanceBackgroundView = GlassBackgroundView() + self.scrollView = ScrollView() self.scrollView.showsVerticalScrollIndicator = true self.scrollView.showsHorizontalScrollIndicator = false @@ -177,7 +181,7 @@ final class GiftStoreScreenComponent: Component { let availableWidth = self.scrollView.bounds.width let availableHeight = self.scrollView.bounds.height - var topInset = environment.navigationHeight + 39.0 + var topInset = environment.navigationHeight + 53.0 if let initialCount = self.initialCount, initialCount < minimumCountToDisplayFilters { topInset = environment.navigationHeight } @@ -889,13 +893,12 @@ final class GiftStoreScreenComponent: Component { var contentHeight: CGFloat = 0.0 contentHeight += environment.navigationHeight - var topPanelHeight = environment.navigationHeight + 39.0 + var topPanelHeight = environment.navigationHeight + 53.0 if let initialCount = self.initialCount, initialCount < minimumCountToDisplayFilters { topPanelHeight = environment.navigationHeight } - - let edgeEffectHeight: CGFloat = environment.navigationHeight + 56.0 + let edgeEffectHeight: CGFloat = topPanelHeight + 8.0 let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: availableSize.width, height: edgeEffectHeight)) transition.setFrame(view: self.edgeEffectView, frame: edgeEffectFrame) self.edgeEffectView.update(content: environment.theme.list.blocksBackgroundColor, blur: true, rect: edgeEffectFrame, edge: .top, edgeSize: min(30, edgeEffectFrame.height), transition: transition) @@ -935,26 +938,41 @@ final class GiftStoreScreenComponent: Component { containerSize: availableSize ) - if let balanceTitleView = self.balanceTitle.view, let balanceValueView = self.balanceValue.view, let balanceIconView = self.balanceIcon.view { - if balanceTitleView.superview == nil { - component.overNavigationContainer.addSubview(balanceTitleView) - component.overNavigationContainer.addSubview(balanceValueView) - component.overNavigationContainer.addSubview(balanceIconView) - } - let navigationHeight = environment.navigationHeight - environment.statusBarHeight - let topBalanceOriginY = environment.statusBarHeight + (navigationHeight - balanceTitleSize.height - balanceValueSize.height) / 2.0 + 3.0 - balanceTitleView.center = CGPoint(x: availableSize.width - 16.0 - environment.safeInsets.right - balanceTitleSize.width / 2.0, y: topBalanceOriginY + balanceTitleSize.height / 2.0) - balanceTitleView.bounds = CGRect(origin: .zero, size: balanceTitleSize) - balanceValueView.center = CGPoint(x: availableSize.width - 16.0 - environment.safeInsets.right - balanceValueSize.width / 2.0, y: topBalanceOriginY + balanceTitleSize.height + balanceValueSize.height / 2.0) - balanceValueView.bounds = CGRect(origin: .zero, size: balanceValueSize) - balanceIconView.center = CGPoint(x: availableSize.width - 16.0 - environment.safeInsets.right - balanceValueSize.width - balanceIconSize.width / 2.0 - 2.0, y: topBalanceOriginY + balanceTitleSize.height + balanceValueSize.height / 2.0 - UIScreenPixel) - balanceIconView.bounds = CGRect(origin: .zero, size: balanceIconSize) + if self.balanceBackgroundView.superview == nil { + component.overNavigationContainer.addSubview(self.balanceBackgroundView) } var topInset: CGFloat = 0.0 if environment.statusBarHeight > 0.0 { topInset = environment.statusBarHeight - 6.0 } + + if let balanceTitleView = self.balanceTitle.view, let balanceValueView = self.balanceValue.view, let balanceIconView = self.balanceIcon.view { + if balanceTitleView.superview == nil { + self.balanceBackgroundView.contentView.addSubview(balanceTitleView) + self.balanceBackgroundView.contentView.addSubview(balanceValueView) + self.balanceBackgroundView.contentView.addSubview(balanceIconView) + } + + let topBalanceOriginY = (44.0 - balanceTitleSize.height - balanceValueSize.height) / 2.0 + + let balanceSideInset: CGFloat = 12.0 + var balanceBackgroundSize = CGSize(width: balanceTitleSize.width + balanceSideInset * 2.0, height: 44.0) + balanceBackgroundSize.width = max(balanceBackgroundSize.width, balanceValueSize.width + balanceIconSize.width + 2.0 + 6.0 * 2.0) + + let balanceBackgroundFrame = CGRect(origin: CGPoint(x: availableSize.width - environment.safeInsets.right - 16.0 - balanceBackgroundSize.width, y: environment.navigationHeight - 60.0 + 2.0 + floor((60.0 - 44.0) * 0.5)), size: balanceBackgroundSize) + + transition.setFrame(view: self.balanceBackgroundView, frame: balanceBackgroundFrame) + self.balanceBackgroundView.update(size: balanceBackgroundFrame.size, cornerRadius: balanceBackgroundFrame.height * 0.5, isDark: environment.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: UIColor(white: environment.theme.overallDarkAppearance ? 0.0 : 1.0, alpha: 0.6)), transition: transition) + + balanceTitleView.center = CGPoint(x: balanceBackgroundFrame.width - balanceSideInset - balanceTitleSize.width / 2.0, y: topBalanceOriginY + balanceTitleSize.height / 2.0) + balanceTitleView.bounds = CGRect(origin: .zero, size: balanceTitleSize) + balanceValueView.center = CGPoint(x: balanceBackgroundFrame.width - balanceSideInset - balanceValueSize.width / 2.0, y: topBalanceOriginY + balanceTitleSize.height + balanceValueSize.height / 2.0) + balanceValueView.bounds = CGRect(origin: .zero, size: balanceValueSize) + balanceIconView.center = CGPoint(x: balanceBackgroundFrame.width - balanceSideInset - balanceValueSize.width - balanceIconSize.width / 2.0 - 2.0, y: topBalanceOriginY + balanceTitleSize.height + balanceValueSize.height / 2.0 - UIScreenPixel) + balanceIconView.bounds = CGRect(origin: .zero, size: balanceIconSize) + } + let titleSize = self.title.update( transition: transition, component: AnyComponent(MultilineTextComponent( @@ -1119,10 +1137,7 @@ final class GiftStoreScreenComponent: Component { transition: transition, component: AnyComponent(FilterSelectorComponent( context: component.context, - colors: FilterSelectorComponent.Colors( - foreground: theme.list.itemPrimaryTextColor.withMultipliedAlpha(0.65), - background: theme.list.itemSecondaryTextColor.withMultipliedAlpha(0.15) - ), + theme: theme, items: filterItems, selectedItemId: self.selectedFilterId )), @@ -1134,7 +1149,7 @@ final class GiftStoreScreenComponent: Component { filterSelectorView.alpha = 0.0 component.overNavigationContainer.addSubview(filterSelectorView) } - transition.setFrame(view: filterSelectorView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - filterSize.width) / 2.0), y: topInset + 60.0 + 12.0), size: filterSize)) + transition.setFrame(view: filterSelectorView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - filterSize.width) / 2.0), y: topInset + 60.0 + 18.0), size: filterSize)) if let initialCount = self.initialCount, initialCount >= minimumCountToDisplayFilters { loadingTransition.setAlpha(view: filterSelectorView, alpha: 1.0) diff --git a/submodules/TelegramUI/Components/GlobalControlPanelsContext/Sources/GlobalControlPanelsContext.swift b/submodules/TelegramUI/Components/GlobalControlPanelsContext/Sources/GlobalControlPanelsContext.swift index 176bccca06..d42d3910c2 100644 --- a/submodules/TelegramUI/Components/GlobalControlPanelsContext/Sources/GlobalControlPanelsContext.swift +++ b/submodules/TelegramUI/Components/GlobalControlPanelsContext/Sources/GlobalControlPanelsContext.swift @@ -82,20 +82,76 @@ public final class GlobalControlPanelsContext { case accountFreeze case link(id: String, url: String, title: ServerSuggestionInfo.Item.Text, subtitle: ServerSuggestionInfo.Item.Text) } + + public final class GroupCall: Equatable { + public let peerId: EnginePeer.Id + public let isChannel: Bool + public let info: GroupCallInfo + public let topParticipants: [GroupCallParticipantsContext.Participant] + public let participantCount: Int + public let activeSpeakers: Set + public let groupCall: PresentationGroupCall? + + public init( + peerId: EnginePeer.Id, + isChannel: Bool, + info: GroupCallInfo, + topParticipants: [GroupCallParticipantsContext.Participant], + participantCount: Int, + activeSpeakers: Set, + groupCall: PresentationGroupCall? + ) { + self.peerId = peerId + self.isChannel = isChannel + self.info = info + self.topParticipants = topParticipants + self.participantCount = participantCount + self.activeSpeakers = activeSpeakers + self.groupCall = groupCall + } + + public static func ==(lhs: GroupCall, rhs: GroupCall) -> Bool { + if lhs.peerId != rhs.peerId { + return false + } + if lhs.isChannel != rhs.isChannel { + return false + } + if lhs.info != rhs.info { + return false + } + if lhs.topParticipants != rhs.topParticipants { + return false + } + if lhs.participantCount != rhs.participantCount { + return false + } + if lhs.activeSpeakers != rhs.activeSpeakers { + return false + } + if lhs.groupCall !== rhs.groupCall { + return false + } + return true + } + } public final class State { public let mediaPlayback: MediaPlayback? public let liveLocation: LiveLocation? public let chatListNotice: ChatListNotice? + public let groupCall: GroupCall? public init( mediaPlayback: MediaPlayback?, liveLocation: LiveLocation?, - chatListNotice: ChatListNotice? + chatListNotice: ChatListNotice?, + groupCall: GroupCall? ) { self.mediaPlayback = mediaPlayback self.liveLocation = liveLocation self.chatListNotice = chatListNotice + self.groupCall = groupCall } } @@ -120,12 +176,15 @@ public final class GlobalControlPanelsContext { var chatListNotice: ChatListNotice? var suggestedChatListNoticeDisposable: Disposable? + + var groupCall: GroupCall? + var currentGroupCallDisposable: Disposable? - init(queue: Queue, context: AccountContext, mediaPlayback: Bool, liveLocationMode: LiveLocationMode?, groupCalls: GroupCallPanelSource?, chatListNotices: Bool) { + init(queue: Queue, context: AccountContext, mediaPlayback: Bool, liveLocationMode: LiveLocationMode?, groupCalls: EnginePeer.Id?, chatListNotices: Bool) { self.queue = queue self.context = context - self.stateValue = State(mediaPlayback: nil, liveLocation: nil, chatListNotice: nil) + self.stateValue = State(mediaPlayback: nil, liveLocation: nil, chatListNotice: nil, groupCall: nil) if mediaPlayback { self.mediaStatusDisposable = (context.sharedContext.mediaManager.globalMediaPlayerState @@ -417,12 +476,119 @@ public final class GlobalControlPanelsContext { } }) } + + if let callManager = context.sharedContext.callManager, let peerId = groupCalls { + let currentGroupCall: Signal = callManager.currentGroupCallSignal + |> distinctUntilChanged(isEqual: { lhs, rhs in + return lhs == rhs + }) + |> map { call -> PresentationGroupCall? in + guard case let .group(call) = call else { + return nil + } + guard call.peerId == peerId && call.account.peerId == context.account.peerId else { + return nil + } + return call + } + + let availableGroupCall: Signal + if let peerId = groupCalls { + availableGroupCall = context.account.viewTracker.peerView(peerId) + |> map { peerView -> (CachedChannelData.ActiveCall?, EnginePeer?) in + let peer = peerView.peers[peerId].flatMap(EnginePeer.init) + if let cachedData = peerView.cachedData as? CachedChannelData { + return (cachedData.activeCall, peer) + } else if let cachedData = peerView.cachedData as? CachedGroupData { + return (cachedData.activeCall, peer) + } else { + return (nil, peer) + } + } + |> distinctUntilChanged(isEqual: { lhs, rhs in + return lhs.0 == rhs.0 + }) + |> mapToSignal { activeCall, peer -> Signal in + guard let activeCall = activeCall else { + return .single(nil) + } + + var isChannel = false + if let peer = peer, case let .channel(channel) = peer, case .broadcast = channel.info { + isChannel = true + } + + return Signal { [weak context] subscriber in + guard let context = context, let callContextCache = context.cachedGroupCallContexts as? AccountGroupCallContextCacheImpl else { + return EmptyDisposable + } + + let disposable = MetaDisposable() + + callContextCache.impl.syncWith { impl in + let callContext = impl.get(account: context.account, engine: context.engine, peerId: peerId, isChannel: isChannel, call: EngineGroupCallDescription(activeCall)) + disposable.set((callContext.context.panelData + |> deliverOnMainQueue).start(next: { panelData in + callContext.keep() + var updatedPanelData = panelData + if let panelData { + var updatedInfo = panelData.info + updatedInfo.subscribedToScheduled = activeCall.subscribedToScheduled + updatedPanelData = panelData.withInfo(updatedInfo) + } + subscriber.putNext(updatedPanelData) + })) + } + + return ActionDisposable { + disposable.dispose() + } + } + |> runOn(.mainQueue()) + } + } else { + availableGroupCall = .single(nil) + } + + let previousCurrentGroupCall = Atomic(value: nil) + self.currentGroupCallDisposable = combineLatest(queue: .mainQueue(), availableGroupCall, currentGroupCall).start(next: { [weak self] availableState, currentGroupCall in + guard let self else { + return + } + + let previousCurrentGroupCall = previousCurrentGroupCall.swap(currentGroupCall) + + let panelData: AccountGroupCallContextImpl.GroupCallPanelData? + if previousCurrentGroupCall != nil && currentGroupCall == nil && availableState?.participantCount == 1 { + panelData = nil + } else { + panelData = currentGroupCall != nil || (availableState?.participantCount == 0 && availableState?.info.scheduleTimestamp == nil && availableState?.info.isStream == false) ? nil : availableState + } + + let groupCall = panelData.flatMap { panelData in + return GroupCall( + peerId: panelData.peerId, + isChannel: panelData.isChannel, + info: panelData.info, + topParticipants: panelData.topParticipants, + participantCount: panelData.participantCount, + activeSpeakers: panelData.activeSpeakers, + groupCall: panelData.groupCall + ) + } + if self.groupCall != groupCall { + self.groupCall = groupCall + self.notifyStateUpdated() + } + }) + } } deinit { self.mediaStatusDisposable?.dispose() self.liveLocationDisposable?.dispose() self.suggestedChatListNoticeDisposable?.dispose() + self.currentGroupCallDisposable?.dispose() } private func notifyStateUpdated() { @@ -448,7 +614,8 @@ public final class GlobalControlPanelsContext { version: liveLocationState.version ) }, - chatListNotice: self.chatListNotice + chatListNotice: self.chatListNotice, + groupCall: self.groupCall ) self.statePipe.putNext(self.stateValue) } @@ -493,7 +660,7 @@ public final class GlobalControlPanelsContext { } } - public init(context: AccountContext, mediaPlayback: Bool, liveLocationMode: LiveLocationMode?, groupCalls: GroupCallPanelSource?, chatListNotices: Bool) { + public init(context: AccountContext, mediaPlayback: Bool, liveLocationMode: LiveLocationMode?, groupCalls: EnginePeer.Id?, chatListNotices: Bool) { self.impl = QueueLocalObject(queue: .mainQueue(), generate: { return Impl(queue: .mainQueue(), context: context, mediaPlayback: mediaPlayback, liveLocationMode: liveLocationMode, groupCalls: groupCalls, chatListNotices: chatListNotices) }) @@ -504,4 +671,28 @@ public final class GlobalControlPanelsContext { impl.dismissChatListNotice(parentController: parentController, notice: notice) } } + + public func setTempVoicePlaylistEnded(_ f: (() -> Void)?) { + self.impl.with { impl in + return impl.tempVoicePlaylistEnded = f + } + } + + public func setTempVoicePlaylistItemChanged(_ f: ((SharedMediaPlaylistItem?, SharedMediaPlaylistItem?) -> Void)?) { + self.impl.with { impl in + return impl.tempVoicePlaylistItemChanged = f + } + } + + public var tempVoicePlaylistCurrentItem: SharedMediaPlaylistItem? { + return self.impl.syncWith { impl in + return impl.tempVoicePlaylistCurrentItem + } + } + + public var playlistStateAndType: (SharedMediaPlaylistItem, SharedMediaPlaylistItem?, SharedMediaPlaylistItem?, MusicPlaybackSettingsOrder, MediaManagerPlayerType, Account, SharedMediaPlaylistLocation, Int)? { + return self.impl.syncWith { impl in + return impl.playlistStateAndType + } + } } diff --git a/submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/BUILD b/submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/BUILD new file mode 100644 index 0000000000..f3a92b4554 --- /dev/null +++ b/submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/BUILD @@ -0,0 +1,38 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "GroupCallHeaderPanelComponent", + module_name = "GroupCallHeaderPanelComponent", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/Display", + "//submodules/AsyncDisplayKit", + "//submodules/TelegramPresentationData", + "//submodules/AccountContext", + "//submodules/TelegramCore", + "//submodules/Postbox", + "//submodules/Components/ComponentDisplayAdapters", + "//submodules/TelegramUIPreferences", + "//submodules/SSignalKit/SwiftSignalKit", + "//submodules/ComponentFlow", + "//submodules/TelegramUI/Components/GlobalControlPanelsContext", + "//submodules/PresentationDataUtils", + "//submodules/TextFormat", + "//submodules/Markdown", + "//submodules/LocalizedPeerData", + "//submodules/LiveLocationTimerNode", + "//submodules/TelegramStringFormatting", + "//submodules/AppBundle", + "//submodules/AnimatedAvatarSetNode", + "//submodules/AudioBlob", + "//submodules/TelegramCallsUI", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/Sources/GroupCallHeaderPanelComponent.swift b/submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/Sources/GroupCallHeaderPanelComponent.swift new file mode 100644 index 0000000000..bd3d0802c4 --- /dev/null +++ b/submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/Sources/GroupCallHeaderPanelComponent.swift @@ -0,0 +1,124 @@ +import Foundation +import UIKit +import Display +import TelegramPresentationData +import ComponentFlow +import ComponentDisplayAdapters +import AccountContext +import TelegramCore +import GlobalControlPanelsContext +import SwiftSignalKit +import Postbox +import PresentationDataUtils + +public final class GroupCallHeaderPanelComponent: Component { + public let context: AccountContext + public let theme: PresentationTheme + public let strings: PresentationStrings + public let data: GlobalControlPanelsContext.GroupCall + public let onTapAction: () -> Void + public let onNotifyScheduledTapAction: () -> Void + + public init( + context: AccountContext, + theme: PresentationTheme, + strings: PresentationStrings, + data: GlobalControlPanelsContext.GroupCall, + onTapAction: @escaping () -> Void, + onNotifyScheduledTapAction: @escaping () -> Void + ) { + self.context = context + self.theme = theme + self.strings = strings + self.data = data + self.onTapAction = onTapAction + self.onNotifyScheduledTapAction = onNotifyScheduledTapAction + } + + public static func ==(lhs: GroupCallHeaderPanelComponent, rhs: GroupCallHeaderPanelComponent) -> Bool { + if lhs.context !== rhs.context { + return false + } + if lhs.theme !== rhs.theme { + return false + } + if lhs.strings !== rhs.strings { + return false + } + if lhs.data != rhs.data { + return false + } + return true + } + + public final class View: UIView { + private var panel: GroupCallNavigationAccessoryPanel? + + private var component: GroupCallHeaderPanelComponent? + private weak var state: EmptyComponentState? + + public override init(frame: CGRect) { + super.init(frame: frame) + } + + required public init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + deinit { + } + + func update(component: GroupCallHeaderPanelComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + let themeUpdated = self.component?.theme !== component.theme + + self.component = component + self.state = state + + let presentationData = component.context.sharedContext.currentPresentationData.with ({ $0 }).withUpdated(theme: component.theme) + + let panel: GroupCallNavigationAccessoryPanel + if let current = self.panel { + panel = current + } else { + panel = GroupCallNavigationAccessoryPanel( + context: component.context, + presentationData: presentationData, + tapAction: { [weak self] in + guard let self, let component = self.component else { + return + } + component.onTapAction() + }, + notifyScheduledTapAction: { [weak self] in + guard let self, let component = self.component else { + return + } + component.onNotifyScheduledTapAction() + } + ) + self.panel = panel + self.addSubview(panel.view) + } + + let size = CGSize(width: availableSize.width, height: 50.0) + let panelFrame = CGRect(origin: CGPoint(), size: size) + transition.setFrame(view: panel.view, frame: panelFrame) + panel.updateLayout(size: panelFrame.size, leftInset: 0.0, rightInset: 0.0, isHidden: false, transition: transition.containedViewLayoutTransition) + panel.update(data: component.data) + + if themeUpdated { + panel.updatePresentationData(presentationData) + } + + return size + } + } + + public func makeView() -> View { + return View(frame: CGRect()) + } + + public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) + } +} diff --git a/submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift b/submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/Sources/GroupCallNavigationAccessoryPanel.swift similarity index 95% rename from submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift rename to submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/Sources/GroupCallNavigationAccessoryPanel.swift index 24cfad99ba..643569e238 100644 --- a/submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift +++ b/submodules/TelegramUI/Components/GroupCallHeaderPanelComponent/Sources/GroupCallNavigationAccessoryPanel.swift @@ -12,6 +12,8 @@ import AppBundle import SwiftSignalKit import AnimatedAvatarSetNode import AudioBlob +import TelegramCallsUI +import GlobalControlPanelsContext func textForTimeout(value: Int32) -> String { if value < 3600 { @@ -32,52 +34,6 @@ func textForTimeout(value: Int32) -> String { private let titleFont = Font.semibold(15.0) private let subtitleFont = Font.regular(13.0) -public enum GroupCallPanelSource { - case none - case all - case peer(PeerId) -} - -public final class GroupCallPanelData { - public let peerId: PeerId - public let isChannel: Bool - public let info: GroupCallInfo - public let topParticipants: [GroupCallParticipantsContext.Participant] - public let participantCount: Int - public let activeSpeakers: Set - public let groupCall: PresentationGroupCall? - - public init( - peerId: PeerId, - isChannel: Bool, - info: GroupCallInfo, - topParticipants: [GroupCallParticipantsContext.Participant], - participantCount: Int, - activeSpeakers: Set, - groupCall: PresentationGroupCall? - ) { - self.peerId = peerId - self.isChannel = isChannel - self.info = info - self.topParticipants = topParticipants - self.participantCount = participantCount - self.activeSpeakers = activeSpeakers - self.groupCall = groupCall - } - - public func withInfo(_ info: GroupCallInfo) -> GroupCallPanelData { - return GroupCallPanelData( - peerId: self.peerId, - isChannel: self.isChannel, - info: info, - topParticipants: self.topParticipants, - participantCount: self.participantCount, - activeSpeakers: self.activeSpeakers, - groupCall: self.groupCall - ) - } -} - private final class FakeAudioLevelGenerator { private var isFirstTime: Bool = true private var nextTarget: Float = 0.0 @@ -106,7 +62,7 @@ private final class FakeAudioLevelGenerator { } } -public final class GroupCallNavigationAccessoryPanel: ASDisplayNode { +final class GroupCallNavigationAccessoryPanel: ASDisplayNode { private let context: AccountContext private var theme: PresentationTheme private var strings: PresentationStrings @@ -161,7 +117,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode { private let hapticFeedback = HapticFeedback() - private var currentData: GroupCallPanelData? + private var currentData: GlobalControlPanelsContext.GroupCall? private var validLayout: (CGSize, CGFloat, CGFloat, Bool)? public init(context: AccountContext, presentationData: PresentationData, tapAction: @escaping () -> Void, notifyScheduledTapAction: @escaping () -> Void) { @@ -375,7 +331,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode { } } - public func update(data: GroupCallPanelData) { + public func update(data: GlobalControlPanelsContext.GroupCall) { let previousData = self.currentData self.currentData = data @@ -635,8 +591,13 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode { self.tapButton.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width - 7.0 - 36.0 - 7.0, height: panelHeight)) if let avatarsContent = self.avatarsContent { - let avatarsSize = self.avatarsNode.update(context: self.context, content: avatarsContent, itemSize: CGSize(width: 32.0, height: 32.0), animated: true, synchronousLoad: true) - transition.updateFrame(node: self.avatarsNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - avatarsSize.width) / 2.0), y: floor((size.height - avatarsSize.height) / 2.0)), size: avatarsSize)) + var avatarsTransition = transition + if self.avatarsNode.bounds.isEmpty { + avatarsTransition = .immediate + } + + let avatarsSize = self.avatarsNode.update(context: self.context, content: avatarsContent, itemSize: CGSize(width: 32.0, height: 32.0), animated: avatarsTransition.isAnimated, synchronousLoad: true) + avatarsTransition.updateFrame(node: self.avatarsNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - avatarsSize.width) / 2.0), y: floor((size.height - avatarsSize.height) / 2.0)), size: avatarsSize)) } var joinText = self.strings.VoiceChat_PanelJoin diff --git a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackCurrentItem.swift b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackCurrentItem.swift index a536dab892..622412a738 100644 --- a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackCurrentItem.swift +++ b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackCurrentItem.swift @@ -170,7 +170,7 @@ class GroupStickerPackCurrentItemNode: ItemListRevealOptionsItemNode { self.removeButtonIcon = ASImageNode() self.removeButtonIcon.displaysAsynchronously = false - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) if let placeholderNode = self.placeholderNode { self.addSubnode(placeholderNode) diff --git a/submodules/TelegramUI/Components/HorizontalTabsComponent/Sources/HorizontalTabsComponent.swift b/submodules/TelegramUI/Components/HorizontalTabsComponent/Sources/HorizontalTabsComponent.swift index d65e05694d..9324fbe2b9 100644 --- a/submodules/TelegramUI/Components/HorizontalTabsComponent/Sources/HorizontalTabsComponent.swift +++ b/submodules/TelegramUI/Components/HorizontalTabsComponent/Sources/HorizontalTabsComponent.swift @@ -280,6 +280,8 @@ public final class HorizontalTabsComponent: Component { } private final class ItemView { + var frame: CGRect = CGRect() + var selectionFrame: CGRect = CGRect() let regularView = ComponentView() let selectedView = ComponentView() @@ -305,12 +307,13 @@ public final class HorizontalTabsComponent: Component { private var reorderingItemPosition: (initial: CGFloat, offset: CGFloat)? private var reorderingAutoScrollAnimator: ConstantDisplayLinkAnimator? private var initialReorderedItemIds: [AnyHashable]? - private var reorderedItemIds: [AnyHashable]? + public private(set) var reorderedItemIds: [AnyHashable]? private var layoutData: LayoutData? private var component: HorizontalTabsComponent? private weak var state: EmptyComponentState? + private var isUpdating: Bool = false override init(frame: CGRect) { self.lensView = LiquidLensView(kind: .noContainer) @@ -350,6 +353,19 @@ public final class HorizontalTabsComponent: Component { } self.alpha = self.lensView.isAnimating ? 1.0 : 0.7 }*/ + /*self.lensView.isLiftedAnimationCompleted = { [weak self] in + guard let self else { + return + } + if let temporaryLiftTimer = self.temporaryLiftTimer { + let _ = temporaryLiftTimer + /*self.temporaryLiftTimer = nil + temporaryLiftTimer.invalidate() + if !self.isUpdating { + self.state?.updated(transition: .spring(duration: 0.5)) + }*/ + } + }*/ let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.onTapGesture(_:))) self.tapRecognizer = tapRecognizer @@ -507,10 +523,7 @@ public final class HorizontalTabsComponent: Component { if case .ended = recognizer.state { let point = recognizer.location(in: self) for (id, itemView) in self.itemViews { - guard let itemView = itemView.regularView.view else { - continue - } - if itemView.convert(itemView.bounds, to: self).contains(point) { + if self.scrollView.convert(itemView.selectionFrame, to: self).contains(point) { if let tab = component.tabs.first(where: { $0.id == id }) { tab.action() } @@ -554,13 +567,18 @@ public final class HorizontalTabsComponent: Component { guard let component = self.component, let layoutData = self.layoutData else { return } - self.lensView.update(size: CGSize(width: layoutData.size.width - 3.0 * 2.0, height: layoutData.size.height - 3.0 * 2.0), selectionOrigin: CGPoint(x: -self.scrollView.contentOffset.x + layoutData.selectedItemFrame.minX, y: 0.0), selectionSize: CGSize(width: layoutData.selectedItemFrame.width + 6.0, height: layoutData.size.height - 3.0 * 2.0), inset: 0.0, isDark: component.theme.overallDarkAppearance, isLifted: self.temporaryLiftTimer != nil, transition: transition) + self.lensView.update(size: CGSize(width: layoutData.size.width - 3.0 * 2.0, height: layoutData.size.height - 3.0 * 2.0), selectionOrigin: CGPoint(x: -self.scrollView.contentOffset.x + layoutData.selectedItemFrame.minX, y: 0.0), selectionSize: CGSize(width: layoutData.selectedItemFrame.width, height: layoutData.size.height - 3.0 * 2.0), inset: 0.0, liftedInset: 6.0, isDark: component.theme.overallDarkAppearance, isLifted: self.temporaryLiftTimer != nil, transition: transition) transition.setPosition(view: self.selectedScrollView, position: CGRect(origin: CGPoint(x: 3.0, y: 0.0), size: CGSize(width: layoutData.size.width - 3.0 * 2.0, height: layoutData.size.height - 3.0 * 2.0)).center) transition.setBounds(view: self.selectedScrollView, bounds: CGRect(origin: CGPoint(x: self.scrollView.contentOffset.x, y: 0.0), size: CGSize(width: layoutData.size.width - 3.0 * 2.0, height: layoutData.size.height - 3.0 * 2.0))) } func update(component: HorizontalTabsComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { + self.isUpdating = true + defer { + self.isUpdating = false + } + var shouldFocusOnSelectedTab = self.isDraggingTabs if component.isEditing { @@ -578,13 +596,13 @@ public final class HorizontalTabsComponent: Component { self.temporaryLiftTimer = nil if !transition.animation.isImmediate { - self.temporaryLiftTimer = Foundation.Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false, block: { [weak self] timer in + self.temporaryLiftTimer = Foundation.Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false, block: { [weak self] _ in guard let self else { return } - if self.temporaryLiftTimer === timer { - self.temporaryLiftTimer = nil - self.state?.updated(transition: .spring(duration: 0.5)) + self.temporaryLiftTimer = nil + if !self.isUpdating { + self.state?.updated(transition: .easeInOut(duration: 0.2), isLocal: true) } }) } @@ -601,8 +619,6 @@ public final class HorizontalTabsComponent: Component { let sideInset: CGFloat = 0.0 - var contentWidth: CGFloat = sideInset - var validIds: [Tab.Id] = [] var orderedTabs = component.tabs @@ -620,6 +636,8 @@ public final class HorizontalTabsComponent: Component { } } + var items: [(tabId: AnyHashable, itemView: ItemView, size: CGSize, itemTransition: ComponentTransition)] = [] + for tab in orderedTabs { let tabId = tab.id validIds.append(tabId) @@ -664,11 +682,49 @@ public final class HorizontalTabsComponent: Component { containerSize: CGSize(width: 1000.0, height: sizeHeight - 3.0 * 2.0) ) - var itemFrame = CGRect(origin: CGPoint(x: contentWidth, y: 0.0), size: itemSize) - if tabId == self.reorderingItem, let (initial, offset) = self.reorderingItemPosition { - itemFrame.origin = CGPoint(x: initial + offset, y: 3.0 + itemFrame.minY) + items.append((tabId, itemView, itemSize, itemTransition)) + } + + var totalContentWidth: CGFloat = sideInset + for item in items { + totalContentWidth += item.size.width + } + totalContentWidth += sideInset + + let scrollContentWidth: CGFloat + if case .fill = component.layout, totalContentWidth < availableSize.width { + let regularItemWidth = floor((availableSize.width - 3.0 * 2.0 - sideInset * 2.0) / CGFloat(items.count)) + let lastItemWidth = (availableSize.width - 3.0 * 2.0 - sideInset * 2.0) - regularItemWidth * CGFloat(items.count - 1) + for i in 0 ..< items.count { + let item = items[i] + let itemWidth = (i == items.count - 1) ? lastItemWidth : regularItemWidth + var itemFrame = CGRect(origin: CGPoint(x: sideInset + regularItemWidth * CGFloat(i) + floor((itemWidth - item.size.width) * 0.5), y: 0.0), size: item.size) + if item.tabId == self.reorderingItem, let (initial, offset) = self.reorderingItemPosition { + itemFrame.origin = CGPoint(x: initial + offset, y: 3.0 + itemFrame.minY) + } + item.itemView.frame = itemFrame + item.itemView.selectionFrame = CGRect(origin: CGPoint(x: sideInset + regularItemWidth * CGFloat(i), y: 0.0), size: CGSize(width: itemWidth, height: item.size.height)) } + scrollContentWidth = availableSize.width - 3.0 * 2.0 + } else { + var contentWidth: CGFloat = sideInset + for item in items { + var itemFrame = CGRect(origin: CGPoint(x: contentWidth, y: 0.0), size: item.size) + if item.tabId == self.reorderingItem, let (initial, offset) = self.reorderingItemPosition { + itemFrame.origin = CGPoint(x: initial + offset, y: 3.0 + itemFrame.minY) + } + item.itemView.frame = itemFrame + item.itemView.selectionFrame = itemFrame + contentWidth += item.size.width + } + contentWidth += sideInset + scrollContentWidth = contentWidth + } + + for (tabId, itemView, _, itemTransition) in items { + let itemFrame = itemView.frame + if let itemRegularView = itemView.regularView.view, let itemSelectedView = itemView.selectedView.view { if itemRegularView.superview == nil { self.scrollView.addSubview(itemRegularView) @@ -695,10 +751,7 @@ public final class HorizontalTabsComponent: Component { itemTransition.setAlpha(view: itemSelectedView, alpha: 1.0) } } - - contentWidth += itemSize.width } - contentWidth += sideInset var removedIds: [Tab.Id] = [] for (id, itemView) in self.itemViews { @@ -724,21 +777,21 @@ public final class HorizontalTabsComponent: Component { if let selectedTab = component.selectedTab { for i in 0 ..< component.tabs.count { if component.tabs[i].id == selectedTab { - if let itemView = self.itemViews[component.tabs[i].id]?.regularView.view { - var selectedItemFrameValue = itemView.frame - if selectedTab == self.reorderingItem { - selectedItemFrameValue = itemView.convert(itemView.bounds, to: self.scrollView) + if let itemView = self.itemViews[component.tabs[i].id] { + var selectedItemFrameValue = itemView.selectionFrame + if selectedTab == self.reorderingItem, let itemSuperview = itemView.regularView.view?.superview { + selectedItemFrameValue = itemSuperview.convert(itemView.selectionFrame, to: self.scrollView) } var pendingItemFrame: CGRect? if self.tabSwitchFraction != 0.0 { if self.tabSwitchFraction > 0.0 && i != component.tabs.count - 1 { - if let nextItemView = self.itemViews[component.tabs[i + 1].id]?.regularView.view { - pendingItemFrame = nextItemView.frame + if let nextItemView = self.itemViews[component.tabs[i + 1].id] { + pendingItemFrame = nextItemView.selectionFrame } } else if self.tabSwitchFraction < 0.0 && i != 0 { - if let previousItemView = self.itemViews[component.tabs[i - 1].id]?.regularView.view { - pendingItemFrame = previousItemView.frame + if let previousItemView = self.itemViews[component.tabs[i - 1].id] { + pendingItemFrame = previousItemView.selectionFrame } } } @@ -755,14 +808,14 @@ public final class HorizontalTabsComponent: Component { } } - let contentSize = CGSize(width: contentWidth, height: sizeHeight - 3.0 * 2.0) + let contentSize = CGSize(width: scrollContentWidth, height: sizeHeight - 3.0 * 2.0) let sizeWidth: CGFloat switch component.layout { case .fill: sizeWidth = availableSize.width case .fit: - sizeWidth = min(availableSize.width, contentWidth + 3.0 * 2.0) + sizeWidth = min(availableSize.width, scrollContentWidth + 3.0 * 2.0) } let size = CGSize(width: sizeWidth, height: sizeHeight) @@ -782,14 +835,22 @@ public final class HorizontalTabsComponent: Component { var scrollViewBounds = CGRect(origin: self.scrollView.bounds.origin, size: scrollViewFrame.size) if shouldFocusOnSelectedTab || self.scrollView.bounds.size != scrollViewBounds.size { if shouldFocusOnSelectedTab, let selectedItemFrame { - if scrollViewBounds.minX + scrollViewBounds.width < selectedItemFrame.maxX { - scrollViewBounds.origin.x = selectedItemFrame.maxX - scrollViewBounds.width + let scrollLookahead: CGFloat = 100.0 + + if scrollViewBounds.minX + scrollViewBounds.width - scrollLookahead < selectedItemFrame.maxX { + scrollViewBounds.origin.x = selectedItemFrame.maxX - scrollViewBounds.width + scrollLookahead } - if scrollViewBounds.minX > selectedItemFrame.minX { - scrollViewBounds.origin.x = selectedItemFrame.minX + if scrollViewBounds.minX > selectedItemFrame.minX - scrollLookahead { + scrollViewBounds.origin.x = selectedItemFrame.minX - scrollLookahead + } + if scrollViewBounds.origin.x + scrollViewBounds.width > contentSize.width { + scrollViewBounds.origin.x = contentSize.width - scrollViewBounds.width + } + if scrollViewBounds.origin.x < 0.0 { + scrollViewBounds.origin.x = 0.0 } - transition.setBounds(view: self.scrollView, bounds: scrollViewBounds) } + transition.setBounds(view: self.scrollView, bounds: scrollViewBounds) } self.scrollView.layer.cornerRadius = (size.height - 3.0 * 2.0) * 0.5 diff --git a/submodules/TelegramUI/Components/ItemListDatePickerItem/Sources/ItemListDatePickerItem.swift b/submodules/TelegramUI/Components/ItemListDatePickerItem/Sources/ItemListDatePickerItem.swift index b5e0920f39..db1bb62322 100644 --- a/submodules/TelegramUI/Components/ItemListDatePickerItem/Sources/ItemListDatePickerItem.swift +++ b/submodules/TelegramUI/Components/ItemListDatePickerItem/Sources/ItemListDatePickerItem.swift @@ -131,7 +131,7 @@ public class ItemListDatePickerItemNode: ListViewItemNode, ItemListItemNode { self.containerNode = ASDisplayNode() self.containerNode.clipsToBounds = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.containerNode) diff --git a/submodules/TelegramUI/Components/LiquidLens/Sources/LiquidLensView.swift b/submodules/TelegramUI/Components/LiquidLens/Sources/LiquidLensView.swift index 7f327300a6..f616914617 100644 --- a/submodules/TelegramUI/Components/LiquidLens/Sources/LiquidLensView.swift +++ b/submodules/TelegramUI/Components/LiquidLens/Sources/LiquidLensView.swift @@ -69,15 +69,17 @@ public final class LiquidLensView: UIView { var selectionOrigin: CGPoint var selectionSize: CGSize var inset: CGFloat + var liftedInset: CGFloat var isDark: Bool var isLifted: Bool var isCollapsed: Bool - init(size: CGSize, selectionOrigin: CGPoint, selectionSize: CGSize, inset: CGFloat, isDark: Bool, isLifted: Bool, isCollapsed: Bool) { + init(size: CGSize, selectionOrigin: CGPoint, selectionSize: CGSize, inset: CGFloat, liftedInset: CGFloat, isDark: Bool, isLifted: Bool, isCollapsed: Bool) { self.size = size self.selectionOrigin = selectionOrigin self.selectionSize = selectionSize self.inset = inset + self.liftedInset = liftedInset self.isLifted = isLifted self.isDark = isDark self.isCollapsed = isCollapsed @@ -87,11 +89,13 @@ public final class LiquidLensView: UIView { private struct LensParams: Equatable { var baseFrame: CGRect var inset: CGFloat + var liftedInset: CGFloat var isLifted: Bool - init(baseFrame: CGRect, inset: CGFloat, isLifted: Bool) { + init(baseFrame: CGRect, inset: CGFloat, liftedInset: CGFloat, isLifted: Bool) { self.baseFrame = baseFrame self.inset = inset + self.liftedInset = liftedInset self.isLifted = isLifted } } @@ -137,6 +141,7 @@ public final class LiquidLensView: UIView { } } public var onUpdatedIsAnimating: ((Bool) -> Void)? + public var isLiftedAnimationCompleted: (() -> Void)? public init(kind: Kind) { self.containerView = UIView() @@ -286,8 +291,8 @@ public final class LiquidLensView: UIView { lensView.perform(NSSelectorFromString("setLiftedContainerView:"), with: view) } - public func update(size: CGSize, selectionOrigin: CGPoint, selectionSize: CGSize, inset: CGFloat, isDark: Bool, isLifted: Bool, isCollapsed: Bool = false, transition: ComponentTransition) { - let params = Params(size: size, selectionOrigin: selectionOrigin, selectionSize: selectionSize, inset: inset, isDark: isDark, isLifted: isLifted, isCollapsed: isCollapsed) + public func update(size: CGSize, selectionOrigin: CGPoint, selectionSize: CGSize, inset: CGFloat, liftedInset: CGFloat = 4.0, isDark: Bool, isLifted: Bool, isCollapsed: Bool = false, transition: ComponentTransition) { + let params = Params(size: size, selectionOrigin: selectionOrigin, selectionSize: selectionSize, inset: inset, liftedInset: liftedInset, isDark: isDark, isLifted: isLifted, isCollapsed: isCollapsed) if self.params == params { return } @@ -328,7 +333,7 @@ public final class LiquidLensView: UIView { guard let self else { return } - let liftedInset: CGFloat = params.isLifted ? 4.0 : -params.inset + let liftedInset: CGFloat = params.isLifted ? params.liftedInset : (-params.inset) lensView.bounds = CGRect(origin: CGPoint(), size: CGSize(width: params.baseFrame.width + liftedInset * 2.0, height: params.baseFrame.height + liftedInset * 2.0)) didProcessUpdate = true if shouldScheduleUpdate { @@ -348,6 +353,7 @@ public final class LiquidLensView: UIView { if !self.isApplyingLensParams { self.isAnimating = false } + self.isLiftedAnimationCompleted?() }) } if didProcessUpdate { @@ -360,7 +366,7 @@ public final class LiquidLensView: UIView { shouldScheduleUpdate = true } } else { - let liftedInset: CGFloat = params.isLifted ? 4.0 : -params.inset + let liftedInset: CGFloat = params.isLifted ? params.liftedInset : (-params.inset) let lensBounds = CGRect(origin: CGPoint(), size: CGSize(width: params.baseFrame.width + liftedInset * 2.0, height: params.baseFrame.height + liftedInset * 2.0)) let lensCenter = CGPoint(x: params.baseFrame.midX, y: params.baseFrame.midY) @@ -445,7 +451,7 @@ public final class LiquidLensView: UIView { } let baseLensFrame = CGRect(origin: CGPoint(x: params.selectionOrigin.x, y: 0.0), size: CGSize(width: params.selectionSize.width, height: params.size.height)) - self.updateLens(params: LensParams(baseFrame: baseLensFrame, inset: params.inset, isLifted: params.isLifted), transition: transition) + self.updateLens(params: LensParams(baseFrame: baseLensFrame, inset: params.inset, liftedInset: params.liftedInset, isLifted: params.isLifted), transition: transition) if let legacyContentMaskView = self.legacyContentMaskView { transition.setFrame(view: legacyContentMaskView, frame: CGRect(origin: CGPoint(), size: params.size)) diff --git a/submodules/TelegramUI/Components/NavigationBarImpl/BUILD b/submodules/TelegramUI/Components/NavigationBarImpl/BUILD index 722bffd862..e75599176b 100644 --- a/submodules/TelegramUI/Components/NavigationBarImpl/BUILD +++ b/submodules/TelegramUI/Components/NavigationBarImpl/BUILD @@ -17,6 +17,7 @@ swift_library( "//submodules/TelegramUI/Components/EdgeEffect", "//submodules/Components/ComponentDisplayAdapters", "//submodules/Components/MultilineTextComponent", + "//submodules/AppBundle", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationBarImpl.swift b/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationBarImpl.swift index 40bdaf5502..85702c934a 100644 --- a/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationBarImpl.swift +++ b/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationBarImpl.swift @@ -414,12 +414,12 @@ public final class NavigationBarImpl: ASDisplayNode, NavigationBar { self.leftButtonNodeImpl.updateItems([leftBarButtonItem], animated: animated) } else { self.leftButtonNodeImpl.updateItems([], animated: animated) - self.leftButtonNodeImpl.updateItems([UIBarButtonItem(title: self.presentationData.strings.close, style: .plain, target: nil, action: nil)], animated: animated) + self.leftButtonNodeImpl.updateItems([UIBarButtonItem(title: "___close", style: .plain, target: nil, action: nil)], animated: animated) } if self.leftButtonNodeImpl.supernode == nil { if let leftButtonsBackgroundView = self.leftButtonsBackgroundView { - leftButtonsBackgroundView.contentView.addSubview(self.leftButtonNodeImpl.view) + leftButtonsBackgroundView.container.addSubview(self.leftButtonNodeImpl.view) } else { self.buttonsContainerNode.view.addSubview(self.leftButtonNodeImpl.view) } @@ -464,9 +464,9 @@ public final class NavigationBarImpl: ASDisplayNode, NavigationBar { self.backButtonNodeImpl.updateManualText(backTitle, isBack: true) if self.backButtonNodeImpl.supernode == nil { if let leftButtonsBackgroundView = self.leftButtonsBackgroundView { - leftButtonsBackgroundView.contentView.addSubview(self.backButtonNodeImpl.view) - leftButtonsBackgroundView.contentView.addSubview(self.backButtonArrow.view) - leftButtonsBackgroundView.contentView.addSubview(self.badgeNode.view) + leftButtonsBackgroundView.container.addSubview(self.backButtonNodeImpl.view) + leftButtonsBackgroundView.container.addSubview(self.backButtonArrow.view) + leftButtonsBackgroundView.container.addSubview(self.badgeNode.view) } else { self.buttonsContainerNode.view.addSubview(self.backButtonNodeImpl.view) self.buttonsContainerNode.view.addSubview(self.backButtonArrow.view) @@ -513,7 +513,7 @@ public final class NavigationBarImpl: ASDisplayNode, NavigationBar { } if self.rightButtonNodeImpl.view.superview == nil { if let rightButtonsBackgroundView = self.rightButtonsBackgroundView { - rightButtonsBackgroundView.contentView.addSubview(self.rightButtonNodeImpl.view) + rightButtonsBackgroundView.container.addSubview(self.rightButtonNodeImpl.view) } else { self.buttonsContainerNode.view.addSubview(self.rightButtonNodeImpl.view) } @@ -550,8 +550,8 @@ public final class NavigationBarImpl: ASDisplayNode, NavigationBar { public let backgroundNode: NavigationBackgroundNode - private var leftButtonsBackgroundView: GlassBackgroundView? - private var rightButtonsBackgroundView: GlassBackgroundView? + private var leftButtonsBackgroundView: (background: GlassBackgroundView, container: UIView)? + private var rightButtonsBackgroundView: (background: GlassBackgroundView, container: UIView)? private let backButtonNodeImpl: NavigationButtonNodeImpl public var backButtonNode: NavigationButtonNode { @@ -578,6 +578,7 @@ public final class NavigationBarImpl: ASDisplayNode, NavigationBar { public var secondaryContentHeight: CGFloat + private var edgeEffectExtension: CGFloat = 0.0 private var edgeEffectView: EdgeEffectView? private var backgroundContainer: GlassBackgroundContainerView? @@ -661,13 +662,15 @@ public final class NavigationBarImpl: ASDisplayNode, NavigationBar { backgroundContainer.contentView.addSubview(self.customOverBackgroundContentView) - let leftButtonsBackgroundView = GlassBackgroundView() + let leftButtonsBackgroundView: (background: GlassBackgroundView, container: UIView) = (GlassBackgroundView(), UIView()) + leftButtonsBackgroundView.background.contentView.addSubview(leftButtonsBackgroundView.container) self.leftButtonsBackgroundView = leftButtonsBackgroundView - backgroundContainer.contentView.addSubview(leftButtonsBackgroundView) + backgroundContainer.contentView.addSubview(leftButtonsBackgroundView.background) - let rightButtonsBackgroundView = GlassBackgroundView() + let rightButtonsBackgroundView: (background: GlassBackgroundView, container: UIView) = (GlassBackgroundView(), UIView()) + rightButtonsBackgroundView.background.contentView.addSubview(rightButtonsBackgroundView.container) self.rightButtonsBackgroundView = rightButtonsBackgroundView - backgroundContainer.contentView.addSubview(rightButtonsBackgroundView) + backgroundContainer.contentView.addSubview(rightButtonsBackgroundView.background) } else { self.addSubnode(self.backgroundNode) self.view.addSubview(self.customOverBackgroundContentView) @@ -811,8 +814,9 @@ public final class NavigationBarImpl: ASDisplayNode, NavigationBar { edgeEffectView.isHidden = true } else { edgeEffectView.isHidden = false - let edgeEffectFrame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: size.height + additionalBackgroundHeight + 20.0)) - transition.updateFrame(view: edgeEffectView, frame: edgeEffectFrame) + let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: -20.0), size: CGSize(width: size.width, height: size.height + additionalBackgroundHeight + 20.0 + 20.0)) + transition.updatePosition(layer: edgeEffectView.layer, position: edgeEffectFrame.center) + transition.updateBounds(layer: edgeEffectView.layer, bounds: CGRect(origin: CGPoint(), size: edgeEffectFrame.size)) edgeEffectView.update(content: self.presentationData.theme.edgeEffectColor ?? .white, blur: true, rect: CGRect(origin: CGPoint(), size: edgeEffectFrame.size), edge: .top, edgeSize: 50.0, transition: ComponentTransition(transition)) } } @@ -959,14 +963,15 @@ public final class NavigationBarImpl: ASDisplayNode, NavigationBar { let leftButtonsBackgroundFrame = CGRect(origin: CGPoint(x: leftInset + 16.0, y: contentVerticalOrigin + floor((nominalHeight - 44.0) * 0.5)), size: CGSize(width: max(44.0, leftButtonsWidth), height: 44.0)) var leftButtonsBackgroundTransition = ComponentTransition(transition) - if leftButtonsBackgroundView.alpha == 0.0 { + if leftButtonsBackgroundView.background.alpha == 0.0 { leftButtonsBackgroundTransition = .immediate } - leftButtonsBackgroundTransition.setPosition(view: leftButtonsBackgroundView, position: leftButtonsBackgroundFrame.center) - leftButtonsBackgroundTransition.setBounds(view: leftButtonsBackgroundView, bounds: CGRect(origin: CGPoint(), size: leftButtonsBackgroundFrame.size)) - transition.updateAlpha(layer: leftButtonsBackgroundView.layer, alpha: leftButtonsWidth == 0.0 ? 0.0 : 1.0) - leftButtonsBackgroundView.update(size: leftButtonsBackgroundFrame.size, cornerRadius: leftButtonsBackgroundFrame.height * 0.5, isDark: self.presentationData.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: UIColor(white: self.presentationData.theme.overallDarkAppearance ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, isVisible: leftButtonsWidth != 0.0, transition: leftButtonsBackgroundTransition) + leftButtonsBackgroundTransition.setPosition(view: leftButtonsBackgroundView.background, position: leftButtonsBackgroundFrame.center) + leftButtonsBackgroundTransition.setBounds(view: leftButtonsBackgroundView.background, bounds: CGRect(origin: CGPoint(), size: leftButtonsBackgroundFrame.size)) + leftButtonsBackgroundTransition.setFrame(view: leftButtonsBackgroundView.container, frame: CGRect(origin: CGPoint(), size: leftButtonsBackgroundFrame.size)) + ComponentTransition(transition).setAlpha(view: leftButtonsBackgroundView.background, alpha: leftButtonsWidth == 0.0 ? 0.0 : 1.0) + leftButtonsBackgroundView.background.update(size: leftButtonsBackgroundFrame.size, cornerRadius: leftButtonsBackgroundFrame.height * 0.5, isDark: self.presentationData.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: UIColor(white: self.presentationData.theme.overallDarkAppearance ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, isVisible: leftButtonsWidth != 0.0, transition: leftButtonsBackgroundTransition) } if let rightButtonsBackgroundView = self.rightButtonsBackgroundView { @@ -975,15 +980,27 @@ public final class NavigationBarImpl: ASDisplayNode, NavigationBar { let rightButtonsBackgroundFrame = CGRect(origin: CGPoint(x: size.width - rightInset - 16.0 - rightButtonsWidth, y: contentVerticalOrigin + floor((nominalHeight - 44.0) * 0.5)), size: CGSize(width: rightButtonsWidth, height: 44.0)) var rightButtonsBackgroundTransition = ComponentTransition(transition) - if rightButtonsBackgroundView.isHidden { + if rightButtonsBackgroundView.background.isHidden { rightButtonsBackgroundTransition = .immediate } + rightButtonsBackgroundView.container.layer.cornerRadius = 44.0 * 0.5 - rightButtonsBackgroundTransition.setFrame(view: rightButtonsBackgroundView, frame: rightButtonsBackgroundFrame) - rightButtonsBackgroundView.isHidden = false - rightButtonsBackgroundView.update(size: rightButtonsBackgroundFrame.size, cornerRadius: rightButtonsBackgroundFrame.height * 0.5, isDark: self.presentationData.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: UIColor(white: self.presentationData.theme.overallDarkAppearance ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, transition: rightButtonsBackgroundTransition) + rightButtonsBackgroundTransition.setFrame(view: rightButtonsBackgroundView.background, frame: rightButtonsBackgroundFrame) + + if rightButtonsBackgroundView.container.bounds.size != rightButtonsBackgroundFrame.size { + rightButtonsBackgroundView.container.clipsToBounds = true + let rightButtonsBackgroundViewContainer = rightButtonsBackgroundView.container + rightButtonsBackgroundTransition.setFrame(view: rightButtonsBackgroundView.container, frame: CGRect(origin: CGPoint(), size: rightButtonsBackgroundFrame.size), completion: { [weak rightButtonsBackgroundViewContainer] flag in + if flag, let rightButtonsBackgroundViewContainer { + rightButtonsBackgroundViewContainer.clipsToBounds = false + } + }) + } + + rightButtonsBackgroundView.background.isHidden = false + rightButtonsBackgroundView.background.update(size: rightButtonsBackgroundFrame.size, cornerRadius: rightButtonsBackgroundFrame.height * 0.5, isDark: self.presentationData.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: UIColor(white: self.presentationData.theme.overallDarkAppearance ? 0.0 : 1.0, alpha: 0.6)), isInteractive: true, transition: rightButtonsBackgroundTransition) } else { - rightButtonsBackgroundView.isHidden = true + rightButtonsBackgroundView.background.isHidden = true } } @@ -1031,6 +1048,20 @@ public final class NavigationBarImpl: ASDisplayNode, NavigationBar { } } + public func updateEdgeEffectExtension(value: CGFloat, transition: ContainedViewLayoutTransition) { + if self.edgeEffectExtension == value { + return + } + self.edgeEffectExtension = value + self.applyEdgeEffectExtension(transition: transition) + } + + private func applyEdgeEffectExtension(transition: ContainedViewLayoutTransition) { + if let edgeEffectView = self.edgeEffectView { + transition.updateTransform(layer: edgeEffectView.layer, transform: CATransform3DMakeTranslation(0.0, max(0.0, min(20.0, self.edgeEffectExtension)), 0.0)) + } + } + public var intrinsicCanTransitionInline: Bool = true public var passthroughTouches = true diff --git a/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationButtonNode.swift b/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationButtonNode.swift index 0d4f353514..0446f196a0 100644 --- a/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationButtonNode.swift +++ b/submodules/TelegramUI/Components/NavigationBarImpl/Sources/NavigationButtonNode.swift @@ -3,6 +3,7 @@ import AsyncDisplayKit import Display import ComponentFlow import MultilineTextComponent +import AppBundle let glassBackArrowImage: UIImage? = { let imageSize = CGSize(width: 44.0, height: 44.0) @@ -21,6 +22,10 @@ let glassBackArrowImage: UIImage? = { })?.withRenderingMode(.alwaysTemplate) }() +let glassCloseImage: UIImage? = { + return generateTintedImage(image: UIImage(bundleImageName: "Navigation/Close"), color: .white)?.withRenderingMode(.alwaysTemplate) +}() + private final class ItemComponent: Component { enum Content: Equatable { case back @@ -120,7 +125,11 @@ private final class ItemComponent: Component { if item.image != nil { iconImage = item.image } else if let title = item.title { - titleString = title + if title == "___close" { + iconImage = glassCloseImage + } else { + titleString = title + } } } @@ -271,6 +280,11 @@ private final class NavigationButtonItemNode: ImmediateTextNode { self.addSubnode(imageNode) } self.imageNode?.image = image + if self.imageNode?.image?.renderingMode == .alwaysTemplate { + self.imageNode?.tintColor = self.color + } else { + self.imageNode?.tintColor = nil + } } else if let imageNode = self.imageNode { imageNode.removeFromSupernode() self.imageNode = nil @@ -297,6 +311,9 @@ private final class NavigationButtonItemNode: ImmediateTextNode { public var color: UIColor = UIColor(rgb: 0x0088ff) { didSet { + if self.imageNode?.image?.renderingMode == .alwaysTemplate { + self.imageNode?.tintColor = self.color + } if let text = self._text { self.attributedText = NSAttributedString(string: text, attributes: self.attributesForCurrentState()) } @@ -658,8 +675,13 @@ public final class NavigationButtonNodeImpl: ContextControllerSourceNode, Naviga } node.alpha = self.manualAlpha node.item = items[i] - node.image = items[i].image - node.text = items[i].title ?? "" + if items[i].title == "___close" { + //node.image = glassCloseImage + node.image = generateTintedImage(image: UIImage(bundleImageName: "Navigation/Close"), color: self.color) + } else { + node.image = items[i].image + node.text = items[i].title ?? "" + } node.bold = items[i].style == .done node.isEnabled = items[i].isEnabled node.node = items[i].customDisplayNode @@ -732,11 +754,11 @@ public final class NavigationButtonNodeImpl: ContextControllerSourceNode, Naviga } } - if !isLeftAligned { + /*if !isLeftAligned { for disappearingNode in self.disappearingNodes { disappearingNode.node.frame = disappearingNode.frame.offsetBy(dx: nodeOrigin.x - disappearingNode.size.width, dy: (totalHeight - disappearingNode.size.height) * 0.5) } - } + }*/ return CGSize(width: nodeOrigin.x, height: totalHeight) } diff --git a/submodules/TelegramUI/Components/PeerInfo/MessagePriceItem/Sources/MessagePriceItem.swift b/submodules/TelegramUI/Components/PeerInfo/MessagePriceItem/Sources/MessagePriceItem.swift index 02aa0262c9..2323498da8 100644 --- a/submodules/TelegramUI/Components/PeerInfo/MessagePriceItem/Sources/MessagePriceItem.swift +++ b/submodules/TelegramUI/Components/PeerInfo/MessagePriceItem/Sources/MessagePriceItem.swift @@ -245,7 +245,7 @@ private class MessagePriceItemNode: ListViewItemNode { self.button = ComponentView() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.leftTextNode) self.addSubnode(self.rightTextNode) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoCoverComponent.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoCoverComponent.swift index dccc9e198b..55e0aa00ac 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoCoverComponent.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoCoverComponent.swift @@ -447,31 +447,33 @@ public final class PeerInfoCoverComponent: Component { let gradientWidth: CGFloat let gradientHeight: CGFloat = component.defaultHeight + let gradientInset: CGFloat = 100.0 + let gradientRelativeInset: CGFloat = gradientInset / gradientHeight if case .custom = component.subject { gradientWidth = gradientHeight self.backgroundView.backgroundColor = backgroundColor - self.backgroundGradientLayer.startPoint = CGPoint(x: 0.5, y: component.avatarCenter.y / gradientHeight) - self.backgroundGradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0) + self.backgroundGradientLayer.startPoint = CGPoint(x: 0.5, y: component.avatarCenter.y / gradientHeight + gradientRelativeInset) + self.backgroundGradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0 - gradientRelativeInset) self.backgroundGradientLayer.type = .radial self.backgroundGradientLayer.colors = [secondaryBackgroundColor.cgColor, backgroundColor.cgColor] } else if case .status = component.subject { gradientWidth = availableSize.width self.backgroundView.backgroundColor = secondaryBackgroundColor self.backgroundGradientLayer.startPoint = component.gradientCenter - self.backgroundGradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0) + self.backgroundGradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0 - gradientRelativeInset) self.backgroundGradientLayer.type = .radial self.backgroundGradientLayer.colors = [backgroundColor.cgColor, secondaryBackgroundColor.cgColor] } else { gradientWidth = availableSize.width self.backgroundView.backgroundColor = secondaryBackgroundColor - self.backgroundGradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0) + self.backgroundGradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0 - gradientRelativeInset) self.backgroundGradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0) self.backgroundGradientLayer.type = .axial self.backgroundGradientLayer.colors = [backgroundColor.cgColor, secondaryBackgroundColor.cgColor] } self.backgroundGradientLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0) - let backgroundGradientFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - gradientWidth) / 2.0), y: component.gradientOnTop ? 0.0 : availableSize.height - gradientHeight), size: CGSize(width: gradientWidth, height: gradientHeight)) + let backgroundGradientFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - gradientWidth) / 2.0), y: component.gradientOnTop ? 0.0 : availableSize.height - gradientHeight), size: CGSize(width: gradientWidth, height: gradientHeight)).insetBy(dx: 0.0, dy: -gradientInset) if !transition.animation.isImmediate { let previousPosition = self.backgroundGradientLayer.position let updatedPosition = CGPoint(x: backgroundGradientFrame.minX, y: backgroundGradientFrame.maxY) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift index f27025c670..97fc64166b 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift @@ -157,6 +157,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { var navigationTitle: String? let navigationButtonContainer: PeerInfoHeaderNavigationButtonContainerNode let searchContainer: ASDisplayNode + var searchEdgeEffectView: EdgeEffectView? let searchBarContainer: SparseNode let editingEdgeEffectView: EdgeEffectView @@ -304,7 +305,6 @@ final class PeerInfoHeaderNode: ASDisplayNode { self?.requestUpdateLayout?(false) } - self.addSubnode(self.searchContainer) self.view.addSubview(self.headerEdgeEffectView) self.view.addSubview(self.backgroundBannerView) self.titleNodeContainer.addSubnode(self.titleNode) @@ -332,6 +332,8 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.addSubnode(self.avatarOverlayNode) self.view.addSubview(self.editingEdgeEffectView) self.addSubnode(self.navigationButtonContainer) + + self.addSubnode(self.searchContainer) self.addSubnode(self.searchBarContainer) self.avatarListNode.avatarContainerNode.tapped = { [weak self] in @@ -736,6 +738,40 @@ final class PeerInfoHeaderNode: ASDisplayNode { } ComponentTransition(transition).setAlpha(view: self.editingEdgeEffectView, alpha: editingBackgroundAlpha) + if isSearching { + let searchNavigationHeight: CGFloat + if isSettings { + searchNavigationHeight = statusBarHeight + 10.0 + } else { + searchNavigationHeight = navigationHeight + 10.0 + } + + let searchEdgeEffectHeight: CGFloat = 40.0 + let searchEdgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: searchNavigationHeight)) + + let searchEdgeEffectView: EdgeEffectView + var searchEdgeEffectTransition = ComponentTransition(transition) + if let current = self.searchEdgeEffectView { + searchEdgeEffectView = current + } else { + searchEdgeEffectTransition = .immediate + searchEdgeEffectView = EdgeEffectView() + self.searchEdgeEffectView = searchEdgeEffectView + self.searchContainer.view.superview?.insertSubview(searchEdgeEffectView, aboveSubview: self.searchContainer.view) + if transition.isAnimated { + searchEdgeEffectView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + } + } + + transition.updateFrame(view: searchEdgeEffectView, frame: searchEdgeEffectFrame) + searchEdgeEffectView.update(content: presentationData.theme.list.blocksBackgroundColor, blur: true, rect: searchEdgeEffectFrame, edge: .top, edgeSize: searchEdgeEffectHeight, transition: searchEdgeEffectTransition) + } else if let searchEdgeEffectView = self.searchEdgeEffectView { + self.searchEdgeEffectView = nil + transition.updateAlpha(layer: searchEdgeEffectView.layer, alpha: 0.0, completion: { [weak searchEdgeEffectView] _ in + searchEdgeEffectView?.removeFromSuperview() + }) + } + let backgroundBannerAlpha: CGFloat do { @@ -1120,7 +1156,11 @@ final class PeerInfoHeaderNode: ASDisplayNode { var titleBrightness: CGFloat = 0.0 navigationContentsPrimaryColor.getHue(nil, saturation: nil, brightness: &titleBrightness, alpha: nil) - self.controller?.setStatusBarStyle(titleBrightness > 0.5 ? .White : .Black, animated: !isFirstTime && animateHeader) + if isSearching { + self.controller?.setStatusBarStyle(presentationData.theme.overallDarkAppearance ? .White : .Black, animated: !isFirstTime && animateHeader) + } else { + self.controller?.setStatusBarStyle(titleBrightness > 0.5 ? .White : .Black, animated: !isFirstTime && animateHeader) + } self.avatarListNode.avatarContainerNode.updateTransitionFraction(transitionFraction, transition: transition) self.avatarListNode.listContainerNode.currentItemNode?.updateTransitionFraction(transitionFraction, transition: transition) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoPaneContainerNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoPaneContainerNode.swift index ffde375e18..d7f066a4f4 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoPaneContainerNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoPaneContainerNode.swift @@ -957,7 +957,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat self.currentParams = (size, sideInset, bottomInset, deviceMetrics, visibleHeight, expansionFraction, presentationData, data, areTabsHidden, disableTabSwitching, navigationHeight) - self.backgroundColor = presentationData.theme.list.blocksBackgroundColor + self.backgroundColor = presentationData.theme.list.blocksBackgroundColor.mixedWith(presentationData.theme.list.plainBackgroundColor, alpha: expansionFraction) let isScrollingLockedAtTop = expansionFraction < 1.0 - CGFloat.ulpOfOne @@ -1220,7 +1220,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat let edgeEffectHeight: CGFloat = 60.0 let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: 60.0 + 6.0)) transition.updateFrame(view: self.edgeEffectView, frame: edgeEffectFrame) - self.edgeEffectView.update(content: presentationData.theme.list.blocksBackgroundColor, blur: true, alpha: 1.0, rect: edgeEffectFrame, edge: .top, edgeSize: edgeEffectHeight, transition: ComponentTransition(transition)) + self.edgeEffectView.update(content: presentationData.theme.list.blocksBackgroundColor.mixedWith(presentationData.theme.list.plainBackgroundColor, alpha: expansionFraction), blur: true, alpha: 1.0, rect: edgeEffectFrame, edge: .top, edgeSize: edgeEffectHeight, transition: ComponentTransition(transition)) ComponentTransition(transition).setAlpha(view: self.edgeEffectView, alpha: tabsAlpha) var canManageTabs = false diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 962f534e6b..3636efd088 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -3123,6 +3123,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private var personalChannelsDisposable: Disposable? + private var effectiveAreaExpansionFraction: CGFloat = 0.0 + private let _ready = Promise() var ready: Promise { return self._ready @@ -4844,8 +4846,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro guard let self else { return } - for (_, section) in self.regularSections { - transition.updateAlpha(node: section, alpha: alpha) + if !self.state.isEditing { + for (_, section) in self.regularSections { + transition.updateAlpha(node: section, alpha: alpha) + } } } @@ -12527,7 +12531,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro func updatePresentationData(_ presentationData: PresentationData) { self.presentationData = presentationData - self.backgroundColor = self.presentationData.theme.list.blocksBackgroundColor + self.backgroundColor = self.presentationData.theme.list.blocksBackgroundColor.mixedWith(self.presentationData.theme.list.plainBackgroundColor, alpha: self.effectiveAreaExpansionFraction) self.updateNavigationExpansionPresentation(isExpanded: self.headerNode.isAvatarExpanded, animated: false) @@ -12992,15 +12996,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if self.state.isEditing { effectiveAreaExpansionFraction = 0.0 } else if self.isSettings { - var paneAreaExpansionDelta = (self.headerNode.frame.maxY - navigationHeight) - self.scrollNode.view.contentOffset.y - paneAreaExpansionDelta = max(0.0, min(paneAreaExpansionDelta, paneAreaExpansionDistance)) - effectiveAreaExpansionFraction = 1.0 - paneAreaExpansionDelta / paneAreaExpansionDistance + effectiveAreaExpansionFraction = 0.0 } else { var paneAreaExpansionDelta = (self.paneContainerNode.frame.minY - navigationHeight) - self.scrollNode.view.contentOffset.y paneAreaExpansionDelta = max(0.0, min(paneAreaExpansionDelta, paneAreaExpansionDistance)) effectiveAreaExpansionFraction = 1.0 - paneAreaExpansionDelta / paneAreaExpansionDistance } + self.effectiveAreaExpansionFraction = effectiveAreaExpansionFraction + self.backgroundColor = self.presentationData.theme.list.blocksBackgroundColor.mixedWith(self.presentationData.theme.list.plainBackgroundColor, alpha: self.effectiveAreaExpansionFraction) + let visibleHeight = self.scrollNode.view.contentOffset.y + self.scrollNode.view.bounds.height - self.paneContainerNode.frame.minY var bottomInset = layout.intrinsicInsets.bottom @@ -13031,7 +13036,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if self.isSettings { leftNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .qrCode, isForExpandedView: false)) rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .edit, isForExpandedView: false)) - rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .search, isForExpandedView: true)) } else if self.isMyProfile { rightNavigationButtons.append(PeerInfoHeaderNavigationButtonSpec(key: .edit, isForExpandedView: false)) } else if peerInfoCanEdit(peer: self.data?.peer, chatLocation: self.chatLocation, threadData: self.data?.threadData, cachedData: self.data?.cachedData, isContact: self.data?.isContact) { diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/PeerInfoStoryGridScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/PeerInfoStoryGridScreen.swift index 22e0ecf465..925c3098b3 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/PeerInfoStoryGridScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/PeerInfoStoryGridScreen.swift @@ -676,7 +676,7 @@ public class PeerInfoStoryGridScreen: ViewControllerComponentContainer { let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } if self.selectionModeCompletion != nil { - self.titleView?.titleContent = .custom(presentationData.strings.Stories_AddStoriesTitle, nil, false) + self.titleView?.titleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(presentationData.strings.Stories_AddStoriesTitle))], subtitle: nil, isEnabled: false) } else { switch self.scope { case .saved: @@ -691,7 +691,7 @@ public class PeerInfoStoryGridScreen: ViewControllerComponentContainer { } else { title = nil } - self.titleView?.titleContent = .custom(presentationData.strings.StoryList_TitleSaved, title, false) + self.titleView?.titleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(presentationData.strings.StoryList_TitleSaved))], subtitle: title, isEnabled: false) if paneNode.isSelectionModeActive { self.navigationItem.setRightBarButton(self.doneBarButtonItem, animated: false) @@ -708,7 +708,7 @@ public class PeerInfoStoryGridScreen: ViewControllerComponentContainer { } else { title = presentationData.strings.StoryList_TitleArchive } - self.titleView?.titleContent = .custom(title, nil, false) + self.titleView?.titleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(title))], subtitle: nil, isEnabled: false) var hasMenu = false if componentView.selectedCount != 0 { diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/StorySearchGridScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/StorySearchGridScreen.swift index 025a670357..3a15d11259 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/StorySearchGridScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/StorySearchGridScreen.swift @@ -277,12 +277,12 @@ public final class StorySearchGridScreen: ViewControllerComponentContainer { switch self.scope { case let .query(peer, query): if let peer, let addressName = peer.addressName { - self.titleView?.titleContent = .custom("\(query)@\(addressName)", title, false) + self.titleView?.titleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text("\(query)@\(addressName)"))], subtitle: title, isEnabled: false) } else { - self.titleView?.titleContent = .custom("\(query)", title, false) + self.titleView?.titleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text("\(query)"))], subtitle: title, isEnabled: false) } case .location: - self.titleView?.titleContent = .custom(presentationData.strings.StoryGridScreen_TitleLocationSearch, nil, false) + self.titleView?.titleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(presentationData.strings.StoryGridScreen_TitleLocationSearch))], subtitle: nil, isEnabled: false) } } diff --git a/submodules/TelegramUI/Components/Settings/PeerNameColorItem/Sources/PeerNameColorItem.swift b/submodules/TelegramUI/Components/Settings/PeerNameColorItem/Sources/PeerNameColorItem.swift index c9306e0290..6c3100f894 100644 --- a/submodules/TelegramUI/Components/Settings/PeerNameColorItem/Sources/PeerNameColorItem.swift +++ b/submodules/TelegramUI/Components/Settings/PeerNameColorItem/Sources/PeerNameColorItem.swift @@ -370,7 +370,7 @@ public final class PeerNameColorItemNode: ListViewItemNode, ItemListItemNode { self.maskNode = ASImageNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.containerNode) } diff --git a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/EmojiPickerItem.swift b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/EmojiPickerItem.swift index e4f962bbcb..ac2ea87e4c 100644 --- a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/EmojiPickerItem.swift +++ b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/EmojiPickerItem.swift @@ -99,7 +99,7 @@ final class EmojiPickerItemNode: ListViewItemNode { self.maskNode = ASImageNode() self.maskNode.isUserInteractionEnabled = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.clipsToBounds = true } diff --git a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorChatPreviewItem.swift b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorChatPreviewItem.swift index f305e4f51d..1c58240bba 100644 --- a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorChatPreviewItem.swift +++ b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorChatPreviewItem.swift @@ -186,7 +186,7 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode { self.containerNode = ASDisplayNode() self.containerNode.subnodeTransform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.clipsToBounds = true self.isUserInteractionEnabled = false diff --git a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorProfilePreviewItem.swift b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorProfilePreviewItem.swift index 475187589b..dd7f756419 100644 --- a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorProfilePreviewItem.swift +++ b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorProfilePreviewItem.swift @@ -142,7 +142,7 @@ final class PeerNameColorProfilePreviewItemNode: ListViewItemNode { let avatarFont = avatarPlaceholderFont(size: floor(100.0 * 16.0 / 37.0)) self.avatarNode = AvatarNode(font: avatarFont) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.clipsToBounds = true self.isUserInteractionEnabled = false diff --git a/submodules/TelegramUI/Components/Settings/QuickReactionSetupController/Sources/ItemListReactionItem.swift b/submodules/TelegramUI/Components/Settings/QuickReactionSetupController/Sources/ItemListReactionItem.swift index 523d024785..c111061686 100644 --- a/submodules/TelegramUI/Components/Settings/QuickReactionSetupController/Sources/ItemListReactionItem.swift +++ b/submodules/TelegramUI/Components/Settings/QuickReactionSetupController/Sources/ItemListReactionItem.swift @@ -151,7 +151,7 @@ public class ItemListReactionItemNode: ListViewItemNode, ItemListItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.titleNode) self.view.addSubview(self.iconView) diff --git a/submodules/TelegramUI/Components/Settings/QuickReactionSetupController/Sources/ReactionChatPreviewItem.swift b/submodules/TelegramUI/Components/Settings/QuickReactionSetupController/Sources/ReactionChatPreviewItem.swift index e72575346d..f8ebea85bd 100644 --- a/submodules/TelegramUI/Components/Settings/QuickReactionSetupController/Sources/ReactionChatPreviewItem.swift +++ b/submodules/TelegramUI/Components/Settings/QuickReactionSetupController/Sources/ReactionChatPreviewItem.swift @@ -116,7 +116,7 @@ class ReactionChatPreviewItemNode: ListViewItemNode { self.containerNode = ASDisplayNode() self.containerNode.subnodeTransform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.clippingNode) self.clippingNode.addSubnode(self.containerNode) diff --git a/submodules/TelegramUI/Components/Settings/ThemeCarouselItem/Sources/ThemeCarouselItem.swift b/submodules/TelegramUI/Components/Settings/ThemeCarouselItem/Sources/ThemeCarouselItem.swift index a34c56bc77..7f8a58041d 100644 --- a/submodules/TelegramUI/Components/Settings/ThemeCarouselItem/Sources/ThemeCarouselItem.swift +++ b/submodules/TelegramUI/Components/Settings/ThemeCarouselItem/Sources/ThemeCarouselItem.swift @@ -259,7 +259,7 @@ private final class ThemeCarouselThemeItemIconNode: ListViewItemNode { self.activateAreaNode = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) self.containerNode.addSubnode(self.imageNode) @@ -725,7 +725,7 @@ public class ThemeCarouselThemeItemNode: ListViewItemNode, ItemListItemNode { self.listNode = ListView() self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.containerNode) self.addSubnode(self.listNode) diff --git a/submodules/TelegramUI/Components/Settings/ThemeSettingsThemeItem/Sources/ThemeSettingsThemeItem.swift b/submodules/TelegramUI/Components/Settings/ThemeSettingsThemeItem/Sources/ThemeSettingsThemeItem.swift index 7fd014433a..4108dd4274 100644 --- a/submodules/TelegramUI/Components/Settings/ThemeSettingsThemeItem/Sources/ThemeSettingsThemeItem.swift +++ b/submodules/TelegramUI/Components/Settings/ThemeSettingsThemeItem/Sources/ThemeSettingsThemeItem.swift @@ -229,7 +229,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode { self.activateAreaNode = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) self.containerNode.addSubnode(self.imageNode) @@ -549,7 +549,7 @@ public class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode { self.listNode = ListView() self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.containerNode) self.addSubnode(self.listNode) diff --git a/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift index c767e89908..4e6e46b1db 100644 --- a/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift @@ -131,7 +131,7 @@ private final class WallpaperPatternItemNode : ListViewItemNode { init() { self.wallpaperNode = SettingsThemeWallpaperNode(displayLoading: true) - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.wallpaperNode) } diff --git a/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridSearchColorsItem.swift b/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridSearchColorsItem.swift index 2056b25cb9..842c90037f 100644 --- a/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridSearchColorsItem.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridSearchColorsItem.swift @@ -180,7 +180,7 @@ class ThemeGridSearchColorsItemNode: ListViewItemNode { self.separatorNode = ASDisplayNode() self.separatorNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.separatorNode) diff --git a/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift b/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift index 51d3786ebe..1da25b3807 100644 --- a/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift +++ b/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift @@ -1019,7 +1019,7 @@ private final class ItemComponent: Component { font: Font.regular(13.0), background: component.theme.rootController.tabBar.badgeBackgroundColor, foreground: component.theme.rootController.tabBar.badgeTextColor, - insets: UIEdgeInsets(top: 0.0, left: 6.0, bottom: 1.0, right: 6.0) + insets: UIEdgeInsets(top: 0.0, left: 5.0, bottom: 1.0, right: 5.0) )), environment: {}, containerSize: CGSize(width: 100.0, height: 100.0) diff --git a/submodules/TelegramUI/Components/TokenListTextField/Sources/EditableTokenListNode.swift b/submodules/TelegramUI/Components/TokenListTextField/Sources/EditableTokenListNode.swift index 1b0f27498b..03e2207b99 100644 --- a/submodules/TelegramUI/Components/TokenListTextField/Sources/EditableTokenListNode.swift +++ b/submodules/TelegramUI/Components/TokenListTextField/Sources/EditableTokenListNode.swift @@ -339,8 +339,6 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { self.scrollNode.addSubnode(self.placeholderNode) self.scrollNode.addSubnode(self.textFieldScrollNode) self.textFieldScrollNode.addSubnode(self.textFieldNode) - //self.scrollNode.addSubnode(self.caretIndicatorNode) - self.clipsToBounds = true self.textFieldNode.textField.delegate = self self.textFieldNode.textField.addTarget(self, action: #selector(self.textFieldChanged(_:)), for: .editingChanged) @@ -383,7 +381,6 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { let sideInset: CGFloat = 12.0 + leftInset let verticalInset: CGFloat = 6.0 - var animationDelay = 0.0 var currentOffset = CGPoint(x: sideInset, y: verticalInset) for token in tokens { diff --git a/submodules/TelegramUI/Components/TranslateHeaderPanelComponent/Sources/ChatTranslationPanelNode.swift b/submodules/TelegramUI/Components/TranslateHeaderPanelComponent/Sources/ChatTranslationPanelNode.swift index 9905cf01c1..1849c6f15b 100644 --- a/submodules/TelegramUI/Components/TranslateHeaderPanelComponent/Sources/ChatTranslationPanelNode.swift +++ b/submodules/TelegramUI/Components/TranslateHeaderPanelComponent/Sources/ChatTranslationPanelNode.swift @@ -17,6 +17,8 @@ import TranslateUI import TelegramUIPreferences import TelegramNotices import PremiumUI +import ComponentFlow +import ComponentDisplayAdapters final class ChatTranslationPanelNode: ASDisplayNode { private let context: AccountContext @@ -123,6 +125,7 @@ final class ChatTranslationPanelNode: ASDisplayNode { }), for: []) } + var textUpdated = false if themeUpdated || previousInfo?.isActive != info.isActive { var languageCode = strings.baseLanguageCode let rawSuffix = "-raw" @@ -142,12 +145,31 @@ final class ChatTranslationPanelNode: ASDisplayNode { } let buttonText = info.isActive ? strings.Conversation_Translation_ShowOriginal : translateTitle + if self.buttonTextNode.attributedText?.string != buttonText { + textUpdated = true + } self.buttonTextNode.attributedText = NSAttributedString(string: buttonText, font: Font.regular(17.0), textColor: theme.chat.inputPanel.panelControlColor) } let panelHeight: CGFloat = 40.0 let contentRightInset: CGFloat = 11.0 + rightInset + + var copyTextView: UIView? + if textUpdated, transition.isAnimated { + if let copyView = self.buttonTextNode.layer.snapshotContentTreeAsView(unhide: false) { + copyTextView = copyView + self.buttonTextNode.view.superview?.insertSubview(copyView, belowSubview: self.buttonTextNode.view) + transition.updateAlpha(layer: copyView.layer, alpha: 0.0, completion: { [weak copyView] _ in + copyView?.removeFromSuperview() + }) + ComponentTransition(transition).setBlur(layer: copyView.layer, radius: 8.0) + + ComponentTransition(transition).animateBlur(layer: self.buttonTextNode.layer, fromRadius: 8.0, toRadius: 0.0) + self.buttonTextNode.alpha = 0.0 + transition.updateAlpha(layer: self.buttonTextNode.layer, alpha: 1.0) + } + } let moreButtonSize = self.moreButton.measure(CGSize(width: 100.0, height: panelHeight)) transition.updateFrame(node: self.moreButton, frame: CGRect(origin: CGPoint(x: width - contentRightInset - moreButtonSize.width, y: floorToScreenPixels((panelHeight - moreButtonSize.height) / 2.0) - 1.0), size: moreButtonSize)) @@ -174,6 +196,9 @@ final class ChatTranslationPanelNode: ASDisplayNode { let buttonTextFrame = CGRect(origin: CGPoint(x: buttonPadding + icon.size.width + buttonSpacing, y: floorToScreenPixels((buttonSize.height - buttonTextSize.height) / 2.0)), size: buttonTextSize) transition.updatePosition(node: self.buttonTextNode, position: buttonTextFrame.center) + if let copyTextView { + transition.updatePosition(layer: copyTextView.layer, position: buttonTextFrame.center) + } self.buttonTextNode.bounds = CGRect(origin: CGPoint(), size: buttonTextFrame.size) } diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift index 2bc4a62c3b..3fa19ee577 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift @@ -692,7 +692,7 @@ extension ChatControllerImpl { self.displayNode = ChatControllerNode(context: self.context, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, subject: self.subject, controllerInteraction: self.controllerInteraction!, chatPresentationInterfaceState: self.presentationInterfaceState, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, navigationBar: self.navigationBar, statusBar: self.statusBar, backgroundNode: self.chatBackgroundNode, controller: self) - if let currentItem = self.tempVoicePlaylistCurrentItem { + if let currentItem = self.globalControlPanelsContext?.tempVoicePlaylistCurrentItem { self.chatDisplayNode.historyNode.voicePlaylistItemChanged(nil, currentItem) } @@ -4613,12 +4613,12 @@ extension ChatControllerImpl { liveLocationMode = self.chatLocation.peerId.flatMap(GlobalControlPanelsContext.LiveLocationMode.peer) } - var groupCallPanelSource: GroupCallPanelSource? + var groupCallPanelSource: EnginePeer.Id? switch self.chatLocation { case let .peer(peerId): switch self.subject { case .message, .none: - groupCallPanelSource = .peer(peerId) + groupCallPanelSource = peerId default: break } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 3f6a3fa9dd..bf126f0caa 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -720,7 +720,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.moreBarButton = MoreHeaderButton(color: self.presentationData.theme.chat.inputPanel.panelControlColor) self.moreBarButton.isUserInteractionEnabled = true - super.init(context: context, navigationBarPresentationData: navigationBarPresentationData, mediaAccessoryPanelVisibility: .none, locationBroadcastPanelSource: .none, groupCallPanelSource: .none) + super.init(context: context, navigationBarPresentationData: navigationBarPresentationData) self.automaticallyControlPresentationContextLayout = false self.blocksBackgroundWhenInOverlay = true @@ -6820,7 +6820,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if case .standard(.default) = self.presentationInterfaceState.mode, self.raiseToListen == nil { self.raiseToListen = RaiseToListenManager(shouldActivate: { [weak self] in - if let strongSelf = self, strongSelf.isNodeLoaded && strongSelf.canReadHistoryValue, strongSelf.presentationInterfaceState.interfaceState.editMessage == nil, strongSelf.playlistStateAndType == nil { + if let strongSelf = self, strongSelf.isNodeLoaded && strongSelf.canReadHistoryValue, strongSelf.presentationInterfaceState.interfaceState.editMessage == nil, strongSelf.globalControlPanelsContext?.playlistStateAndType == nil { if !strongSelf.context.sharedContext.currentMediaInputSettings.with({ $0.enableRaiseToSpeak }) { return false } @@ -6861,7 +6861,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self?.deactivateRaiseGesture() }) self.raiseToListen?.enabled = self.canReadHistoryValue - self.tempVoicePlaylistEnded = { [weak self] in + self.globalControlPanelsContext?.setTempVoicePlaylistEnded({ [weak self] in guard let strongSelf = self else { return } @@ -6878,14 +6878,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.returnInputViewFocus = false strongSelf.chatDisplayNode.ensureInputViewFocused() } - } - self.tempVoicePlaylistItemChanged = { [weak self] previousItem, currentItem in + }) + self.globalControlPanelsContext?.setTempVoicePlaylistItemChanged({ [weak self] previousItem, currentItem in guard let strongSelf = self else { return } strongSelf.chatDisplayNode.historyNode.voicePlaylistItemChanged(previousItem, currentItem) - } + }) } if let arguments = self.presentationArguments as? ChatControllerOverlayPresentationData { diff --git a/submodules/TelegramUI/Sources/ChatControllerContentData.swift b/submodules/TelegramUI/Sources/ChatControllerContentData.swift index 31d439a2f6..3caadb682d 100644 --- a/submodules/TelegramUI/Sources/ChatControllerContentData.swift +++ b/submodules/TelegramUI/Sources/ChatControllerContentData.swift @@ -519,32 +519,44 @@ extension ChatControllerImpl { if case .reply = info { let titleContent: ChatTitleContent if case let .reply(hasQuote) = messageOptionsTitleInfo, hasQuote { - titleContent = .custom(strings.Chat_TitleQuoteSelection, subtitleText, false) + titleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(strings.Chat_TitleQuoteSelection))], subtitle: subtitleText, isEnabled: false) } else { - titleContent = .custom(strings.Chat_TitleReply, subtitleText, false) + titleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(strings.Chat_TitleReply))], subtitle: subtitleText, isEnabled: false) } strongSelf.state.chatTitleContent = titleContent } else if case .link = info { - strongSelf.state.chatTitleContent = .custom(strings.Chat_TitleLinkOptions, subtitleText, false) + strongSelf.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(strings.Chat_TitleLinkOptions))], subtitle: subtitleText, isEnabled: false) } else if displayedCount == 1 { - strongSelf.state.chatTitleContent = .custom(strings.Conversation_ForwardOptions_ForwardTitleSingle, subtitleText, false) + strongSelf.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(strings.Conversation_ForwardOptions_ForwardTitleSingle))], subtitle: subtitleText, isEnabled: false) } else { - strongSelf.state.chatTitleContent = .custom(strings.Conversation_ForwardOptions_ForwardTitle(Int32(displayedCount ?? 1)), subtitleText, false) + strongSelf.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(strings.Conversation_ForwardOptions_ForwardTitle(Int32(displayedCount ?? 1))))], subtitle: subtitleText, isEnabled: false) } } else if let selectionState = configuration.selectionState { if selectionState.selectedIds.count > 0 { - strongSelf.state.chatTitleContent = .custom(strings.Conversation_SelectedMessages(Int32(selectionState.selectedIds.count)), nil, false) + let rawText = strings.Conversation_SelectedMessagesFormat(Int32(selectionState.selectedIds.count)) + var items: [ChatTitleContent.TitleTextItem] = [] + if let range = rawText.range(of: "{}") { + if range.lowerBound != rawText.startIndex { + items.append(ChatTitleContent.TitleTextItem(id: AnyHashable("selection_0"), content: .text(String(rawText[rawText.startIndex ..< range.lowerBound])))) + } + items.append(ChatTitleContent.TitleTextItem(id: AnyHashable("selection_1"), content: .number(selectionState.selectedIds.count, minDigits: 1))) + if range.upperBound != rawText.endIndex { + items.append(ChatTitleContent.TitleTextItem(id: AnyHashable("selection_2"), content: .text(String(rawText[range.upperBound ..< rawText.endIndex])))) + } + } + + strongSelf.state.chatTitleContent = .custom(title: items, subtitle: nil, isEnabled: false) } else { if let reportReason = configuration.reportReason { - strongSelf.state.chatTitleContent = .custom(reportReason.title, strings.Conversation_SelectMessages, false) + strongSelf.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(1), content: .text(reportReason.title))], subtitle: strings.Conversation_SelectMessages, isEnabled: false) } else { - strongSelf.state.chatTitleContent = .custom(strings.Conversation_SelectMessages, nil, false) + strongSelf.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(2), content: .text(strings.Conversation_SelectMessages))], subtitle: nil, isEnabled: false) } } } else if let peer = peerViewMainPeer(peerView) { if case .pinnedMessages = configuration.subject { - strongSelf.state.chatTitleContent = .custom(strings.Chat_TitlePinnedMessages(Int32(displayedCount ?? 1)), nil, false) + strongSelf.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(strings.Chat_TitlePinnedMessages(Int32(displayedCount ?? 1))))], subtitle: nil, isEnabled: false) } else if let channel = peer as? TelegramChannel, channel.isMonoForum { if let linkedMonoforumId = channel.linkedMonoforumId, let mainPeer = peerView.peers[linkedMonoforumId] { strongSelf.state.chatTitleContent = .peer(peerView: ChatTitleContent.PeerData( @@ -557,7 +569,7 @@ extension ChatControllerImpl { cachedData: nil ), customTitle: nil, customSubtitle: strings.Chat_Monoforum_Subtitle, onlineMemberCount: (nil, nil), isScheduledMessages: false, isMuted: nil, customMessageCount: nil, isEnabled: true) } else { - strongSelf.state.chatTitleContent = .custom(channel.debugDisplayTitle, nil, true) + strongSelf.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(channel.debugDisplayTitle))], subtitle: nil, isEnabled: true) } } else { strongSelf.state.chatTitleContent = .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: nil, customSubtitle: nil, onlineMemberCount: onlineMemberCount, isScheduledMessages: isScheduledMessages, isMuted: nil, customMessageCount: nil, isEnabled: hasPeerInfo) @@ -1549,7 +1561,7 @@ extension ChatControllerImpl { } strongSelf.state.infoAvatar = .emojiStatus(content: avatarContent, contextActionIsEnabled: infoContextActionIsEnabled) } else if chatLocation.threadId == EngineMessage.newTopicThreadId { - strongSelf.state.chatTitleContent = .custom(strongSelf.presentationData.strings.Chat_MessageHeaderBotNewThread, nil, false) + strongSelf.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(strongSelf.presentationData.strings.Chat_MessageHeaderBotNewThread))], subtitle: nil, isEnabled: false) strongSelf.state.infoAvatar = nil } else { strongSelf.state.chatTitleContent = .replyThread(type: replyThreadType, count: count) @@ -1742,11 +1754,11 @@ extension ChatControllerImpl { case let .quickReplyMessageInput(shortcut, shortcutType): switch shortcutType { case .generic: - self.state.chatTitleContent = .custom("\(shortcut)", nil, false) + self.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text("\(shortcut)"))], subtitle: nil, isEnabled: false) case .greeting: - self.state.chatTitleContent = .custom(strings.QuickReply_TitleGreetingMessage, nil, false) + self.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(strings.QuickReply_TitleGreetingMessage))], subtitle: nil, isEnabled: false) case .away: - self.state.chatTitleContent = .custom(strings.QuickReply_TitleAwayMessage, nil, false) + self.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(strings.QuickReply_TitleAwayMessage))], subtitle: nil, isEnabled: false) } case let .businessLinkSetup(link): let linkUrl: String @@ -1756,10 +1768,10 @@ extension ChatControllerImpl { linkUrl = link.url } - self.state.chatTitleContent = .custom(link.title ?? strings.Business_Links_EditLinkTitle, linkUrl, false) + self.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(link.title ?? strings.Business_Links_EditLinkTitle))], subtitle: linkUrl, isEnabled: false) } } else { - self.state.chatTitleContent = .custom(" ", nil, false) + self.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(" "))], subtitle: nil, isEnabled: false) } self.peerDisposable = (peerView diff --git a/submodules/TelegramUI/Sources/ChatControllerEditChat.swift b/submodules/TelegramUI/Sources/ChatControllerEditChat.swift index 85b0428962..cbba13b727 100644 --- a/submodules/TelegramUI/Sources/ChatControllerEditChat.swift +++ b/submodules/TelegramUI/Sources/ChatControllerEditChat.swift @@ -9,6 +9,7 @@ import TelegramPresentationData import PresentationDataUtils import QuickReplyNameAlertController import BusinessLinkNameAlertController +import ChatTitleView extension ChatControllerImpl { func editChat() { @@ -54,7 +55,7 @@ extension ChatControllerImpl { strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameDisplayOrder: self.presentationData.nameDisplayOrder, - content: .custom("\(value)", nil, false), + content: .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text("\(value)"))], subtitle: nil, isEnabled: false), transition: .immediate ) @@ -108,7 +109,7 @@ extension ChatControllerImpl { strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameDisplayOrder: self.presentationData.nameDisplayOrder, - content: .custom(value.isEmpty ? self.presentationData.strings.Business_Links_EditLinkTitle : value, linkUrl, false), + content: .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(value.isEmpty ? self.presentationData.strings.Business_Links_EditLinkTitle : value))], subtitle: linkUrl, isEnabled: false), transition: .immediate ) if case let .customChatContents(customChatContents) = self.subject { diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 55216c5f81..fb490b31fa 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -59,6 +59,7 @@ import AdPanelHeaderPanelComponent import MessageFeeHeaderPanelComponent import LegacyChatHeaderPanelComponent import ChatSearchNavigationContentNode +import GroupCallHeaderPanelComponent final class VideoNavigationControllerDropContentItem: NavigationControllerDropContentItem { let itemNode: OverlayMediaItemNode @@ -1360,6 +1361,61 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { ))) ) } + if let groupCall = self.controller?.globalControlPanelsContextState?.groupCall { + headerPanels.append(HeaderPanelContainerComponent.Panel( + key: "groupCall", + orderIndex: 2, + component: AnyComponent(GroupCallHeaderPanelComponent( + context: self.context, + theme: self.chatPresentationInterfaceState.theme, + strings: self.chatPresentationInterfaceState.strings, + data: groupCall, + onTapAction: { [weak self] in + guard let self, let groupCall = self.controller?.globalControlPanelsContextState?.groupCall else { + return + } + self.controller?.joinGroupCall( + peerId: groupCall.peerId, + invite: nil, + activeCall: EngineGroupCallDescription( + id: groupCall.info.id, + accessHash: groupCall.info.accessHash, + title: groupCall.info.title, + scheduleTimestamp: groupCall.info.scheduleTimestamp, + subscribedToScheduled: groupCall.info.subscribedToScheduled, + isStream: groupCall.info.isStream + ) + ) + }, + onNotifyScheduledTapAction: { [weak self] in + guard let self, let controller = self.controller, let groupCall = self.controller?.globalControlPanelsContextState?.groupCall else { + return + } + if groupCall.info.scheduleTimestamp != nil && !groupCall.info.subscribedToScheduled { + let _ = self.context.engine.calls.toggleScheduledGroupCallSubscription(peerId: groupCall.peerId, reference: .id(id: groupCall.info.id, accessHash: groupCall.info.accessHash), subscribe: true).startStandalone() + + controller.controllerInteraction?.displayUndo( + .universal( + animation: "anim_set_notification", + scale: 0.06, + colors: [ + "Middle.Group 1.Fill 1": UIColor.white, + "Top.Group 1.Fill 1": UIColor.white, + "Bottom.Group 1.Fill 1": UIColor.white, + "EXAMPLE.Group 1.Fill 1": UIColor.white, + "Line.Group 1.Stroke 1": UIColor.white + ], + title: nil, + text: controller.presentationData.strings.Chat_ToastSubscribedToScheduledLiveStream_Text, + customUndoText: nil, + timeout: nil + ) + ) + } + } + ))) + ) + } var hasTranslationPanel = false if let _ = self.chatPresentationInterfaceState.translationState, self.emptyType == nil { @@ -1561,9 +1617,9 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { switch floatingTopicsPanelComponent.location { case .side: - floatingTopicsPanelInsets.left += 72.0 + 8.0 + 8.0 + floatingTopicsPanelInsets.left += 72.0 + 10.0 + 10.0 case .top: - floatingTopicsPanelInsets.top += 40.0 + 8.0 + floatingTopicsPanelInsets.top += 40.0 + 10.0 } } else if let floatingTopicsPanel = self.floatingTopicsPanel { self.floatingTopicsPanel = nil @@ -1857,7 +1913,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { updateExtraNavigationBarBackgroundHeight(0.0, 0.0, nil, transition) - var sidePanelTopInset: CGFloat = insets.top + var sidePanelTopInset: CGFloat = insets.top + 4.0 let contentBounds = CGRect(x: 0.0, y: 0.0, width: layout.size.width - wrappingInsets.left - wrappingInsets.right, height: layout.size.height - wrappingInsets.top - wrappingInsets.bottom) @@ -2126,7 +2182,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { } if self.secondaryInputPanelNode != nil { - secondaryInputPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - bottomOverflowOffset - inputPanelsHeight - secondaryInputPanelSize!.height - 8.0), size: CGSize(width: layout.size.width, height: secondaryInputPanelSize!.height)) + secondaryInputPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - bottomOverflowOffset - inputPanelsHeight - 8.0 - secondaryInputPanelSize!.height - 8.0), size: CGSize(width: layout.size.width, height: secondaryInputPanelSize!.height)) if self.dismissedAsOverlay { secondaryInputPanelFrame!.origin.y = layout.size.height } @@ -2458,7 +2514,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { self.floatingTopicsPanelContainer.view.addSubview(headerPanelsComponentView) } headerPanelsTransition.setFrame(view: headerPanelsComponentView, frame: headerPanelsFrame) - sidePanelTopInset += headerPanelsSize.height + sidePanelTopInset += headerPanelsSize.height + 2.0 } let floatingTopicsPanelContainerFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 0.0, height: layout.size.height)) @@ -2560,10 +2616,8 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { inputContextPanelNode.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: insets.bottom + inputPanelsHeight + 8.0, transition: .immediate, interfaceState: self.chatPresentationInterfaceState) } - if !inputContextPanelNode.frame.equalTo(panelFrame) || inputContextPanelNode.theme !== self.chatPresentationInterfaceState.theme { - transition.updateFrame(node: inputContextPanelNode, frame: panelFrame) - inputContextPanelNode.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: 0.0, transition: transition, interfaceState: self.chatPresentationInterfaceState) - } + transition.updateFrame(node: inputContextPanelNode, frame: panelFrame) + inputContextPanelNode.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: insets.bottom + inputPanelsHeight + 8.0, transition: transition, interfaceState: self.chatPresentationInterfaceState) } if let overlayContextPanelNode = self.overlayContextPanelNode { diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index baccfdfddc..91fe9c6229 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -906,7 +906,6 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto } } - self.dynamicBounceEnabled = !self.currentPresentationData.disableAnimations self.experimentalSnapScrollToItem = false //self.debugInfo = true @@ -2434,7 +2433,6 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto let chatPresentationData = ChatPresentationData(theme: themeData, fontSize: presentationData.chatFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: true, largeEmoji: presentationData.largeEmoji, chatBubbleCorners: presentationData.chatBubbleCorners, animatedEmojiScale: animatedEmojiConfig.scale) strongSelf.currentPresentationData = chatPresentationData - strongSelf.dynamicBounceEnabled = false strongSelf.forEachItemHeaderNode { itemHeaderNode in if let dateNode = itemHeaderNode as? ChatMessageDateHeaderNodeImpl { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceInputContextPanels.swift b/submodules/TelegramUI/Sources/ChatInterfaceInputContextPanels.swift index e0a074b468..0944f199b8 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceInputContextPanels.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceInputContextPanels.swift @@ -153,35 +153,8 @@ func textInputContextPanel(context: AccountContext, chatPresentationInterfaceSta } else { return nil } - case let .contextRequestResult(_, results): - let _ = results + case .contextRequestResult: return nil - /*if let results = results, (!results.results.isEmpty || results.switchPeer != nil || results.webView != nil) { - switch results.presentation { - case .list: - if let currentPanel = currentPanel as? VerticalListContextResultsChatInputContextPanelNode { - currentPanel.updateResults(results) - return currentPanel - } else { - let panel = VerticalListContextResultsChatInputContextPanelNode(context: context, theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings, fontSize: chatPresentationInterfaceState.fontSize, chatPresentationContext: controllerInteraction.presentationContext) - panel.interfaceInteraction = interfaceInteraction - panel.updateResults(results) - return panel - } - case .media: - if let currentPanel = currentPanel as? HorizontalListContextResultsChatInputContextPanelNode { - currentPanel.updateResults(results) - return currentPanel - } else { - let panel = HorizontalListContextResultsChatInputContextPanelNode(context: context, theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings, fontSize: chatPresentationInterfaceState.fontSize, chatPresentationContext: controllerInteraction.presentationContext) - panel.interfaceInteraction = interfaceInteraction - panel.updateResults(results) - return panel - } - } - } else { - return nil - }*/ } } diff --git a/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift index d889eeaa7c..a13a8cb780 100644 --- a/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift @@ -157,7 +157,7 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode { self.tintSubtitleNode.attributedText = NSAttributedString(string: self.subtitleNode.attributedText?.string ?? "", font: Font.regular(13.0), textColor: .black) let panelHeight = defaultHeight(metrics: metrics) - let textSize = self.textNode.updateLayout(CGSize(width: width - leftInset - rightInset - 8.0 * 2.0, height: panelHeight)) + let textSize = self.textNode.updateLayout(CGSize(width: width - leftInset - rightInset - 16.0 * 2.0, height: panelHeight)) let subtitleSize = self.subtitleNode.updateLayout(CGSize(width: width - leftInset - rightInset - 8.0 * 2.0, height: panelHeight)) var originX: CGFloat = leftInset + floor((width - leftInset - rightInset - textSize.width) / 2.0) @@ -196,7 +196,8 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode { combinedFrame = combinedFrame.union(iconView.frame) } combinedFrame = combinedFrame.insetBy(dx: -12.0, dy: -6.0) - combinedFrame.origin.y += 1.0 + combinedFrame.size.height = 40.0 + combinedFrame.origin.y = floorToScreenPixels((panelHeight - 40.0) * 0.5) self.textNode.frame = textFrame.offsetBy(dx: -combinedFrame.minX, dy: -combinedFrame.minY) self.tintTextNode.frame = self.textNode.frame diff --git a/submodules/TelegramUI/Sources/ChatTagSearchInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTagSearchInputPanelNode.swift index 84622b6005..6d82c91f10 100644 --- a/submodules/TelegramUI/Sources/ChatTagSearchInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTagSearchInputPanelNode.swift @@ -108,6 +108,14 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode { } override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat { + var leftInset = leftInset + 8.0 + var rightInset = rightInset + 8.0 + + if bottomInset <= 32.0 { + leftInset += 18.0 + rightInset += 18.0 + } + let params = Params(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, interfaceState: interfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded) if let currentLayout = self.currentLayout, currentLayout.params == params { return currentLayout.height @@ -332,7 +340,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode { buttonView.alpha = 0.0 self.view.addSubview(buttonView) } - let listModeFrame = CGRect(origin: CGPoint(x: params.width - params.rightInset - 20.0 - 8.0 - buttonSize.width, y: floor((size.height - buttonSize.height) * 0.5)), size: buttonSize) + let listModeFrame = CGRect(origin: CGPoint(x: params.width - params.rightInset - 8.0 - buttonSize.width, y: floor((size.height - buttonSize.height) * 0.5)), size: buttonSize) listModeButtonFrameValue = listModeFrame listModeButtonTransition.setPosition(view: buttonView, position: CGPoint(x: listModeFrame.minX + listModeFrame.width * buttonView.layer.anchorPoint.x, y: listModeFrame.minY + listModeFrame.height * buttonView.layer.anchorPoint.y)) listModeButtonTransition.setBounds(view: buttonView, bounds: CGRect(origin: CGPoint(), size: listModeFrame.size)) @@ -349,7 +357,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode { } } - var nextLeftX: CGFloat = 16.0 + 8.0 + var nextLeftX: CGFloat = params.leftInset var calendarButtonFrameValue: CGRect? var membersButtonFrameValue: CGRect? @@ -547,7 +555,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode { } } - var leftControlsBackgroundFrame = CGRect(origin: CGPoint(x: 20.0, y: floor((height - 40.0) * 0.5)), size: CGSize(width: 0.0, height: 40.0)) + var leftControlsBackgroundFrame = CGRect(origin: CGPoint(x: params.leftInset, y: floor((height - 40.0) * 0.5)), size: CGSize(width: 0.0, height: 40.0)) leftControlsBackgroundFrame.size.width = max(40.0, leftControlsRect.maxX - leftControlsBackgroundFrame.minX) transition.setFrame(view: self.leftControlsBackgroundView, frame: leftControlsBackgroundFrame) self.leftControlsBackgroundView.update(size: leftControlsBackgroundFrame.size, cornerRadius: leftControlsBackgroundFrame.height * 0.5, isDark: params.interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: params.interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: transition) @@ -568,7 +576,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode { } } - var rightControlsBackgroundFrame = CGRect(origin: CGPoint(x: params.width - params.rightInset - 20.0, y: floor((height - 40.0) * 0.5)), size: CGSize(width: 0.0, height: 40.0)) + var rightControlsBackgroundFrame = CGRect(origin: CGPoint(x: params.width - params.rightInset, y: floor((height - 40.0) * 0.5)), size: CGSize(width: 0.0, height: 40.0)) rightControlsBackgroundFrame.size.width = max(40.0, rightControlsRect.maxX - rightControlsRect.minX + 8.0 * 2.0) rightControlsBackgroundFrame.origin.x -= rightControlsBackgroundFrame.width transition.setFrame(view: self.rightControlsBackgroundView, frame: rightControlsBackgroundFrame) diff --git a/submodules/TelegramUI/Sources/CommandChatInputPanelItem.swift b/submodules/TelegramUI/Sources/CommandChatInputPanelItem.swift index 3b7fd42713..8d27ec66e3 100644 --- a/submodules/TelegramUI/Sources/CommandChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/CommandChatInputPanelItem.swift @@ -107,7 +107,7 @@ final class CommandChatInputPanelItemNode: ListViewItemNode { self.activateAreaNode = AccessibilityAreaNode() self.activateAreaNode.accessibilityTraits = [.button] - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.separatorNode) diff --git a/submodules/TelegramUI/Sources/CommandMenuChatInputPanelItem.swift b/submodules/TelegramUI/Sources/CommandMenuChatInputPanelItem.swift index 48db2d5460..e27f05e592 100644 --- a/submodules/TelegramUI/Sources/CommandMenuChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/CommandMenuChatInputPanelItem.swift @@ -144,7 +144,7 @@ final class CommandMenuChatInputPanelItemNode: ListViewItemNode { self.activateAreaNode = AccessibilityAreaNode() self.activateAreaNode.accessibilityTraits = [.button] - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.clippingNode) self.clippingNode.addSubnode(self.shadowNode) diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionController.swift b/submodules/TelegramUI/Sources/ContactMultiselectionController.swift index a4b097b5f7..403a2852f8 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionController.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionController.swift @@ -109,7 +109,8 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection self.titleView = CounterControllerTitleView(theme: self.presentationData.theme) - super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData)) + super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData, style: .glass)) + self._hasGlassStyle = true self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift index 3a2d3bc9cd..08c8d27e4d 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift @@ -277,7 +277,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { } } - self.tokenListNode = EditableTokenListNode(context: self.context, presentationTheme: self.presentationData.theme, theme: EditableTokenListNodeTheme(backgroundColor: .clear, separatorColor: self.presentationData.theme.rootController.navigationBar.separatorColor, placeholderTextColor: self.presentationData.theme.list.itemPlaceholderTextColor, primaryTextColor: self.presentationData.theme.list.itemPrimaryTextColor, tokenBackgroundColor: self.presentationData.theme.list.itemCheckColors.strokeColor.withAlphaComponent(0.25), selectedTextColor: self.presentationData.theme.list.itemCheckColors.foregroundColor, selectedBackgroundColor: self.presentationData.theme.list.itemCheckColors.fillColor, accentColor: self.presentationData.theme.list.itemAccentColor, keyboardColor: self.presentationData.theme.rootController.keyboardColor), placeholder: placeholder, shortPlaceholder: shortPlaceholder) + self.tokenListNode = EditableTokenListNode(context: self.context, theme: self.presentationData.theme, placeholder: placeholder, shortPlaceholder: shortPlaceholder) super.init() @@ -413,6 +413,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { var insets = layout.insets(options: [.input]) insets.top += navigationBarHeight insets.top += strongSelf.tokenListNode.bounds.size.height + insets.top += 10.0 + 10.0 var headerInsets = layout.insets(options: [.input]) headerInsets.top += actualNavigationBarHeight @@ -465,16 +466,17 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { var insets = layout.insets(options: [.input]) insets.top += navigationBarHeight + insets.top += 10.0 - let tokenListHeight = self.tokenListNode.updateLayout(tokens: self.editableTokens, width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: transition) + let tokenListHeight = self.tokenListNode.updateLayout(tokens: self.editableTokens, width: layout.size.width - (16.0 + layout.safeInsets.left) * 2.0, leftInset: 0.0, rightInset: 0.0, transition: transition) - transition.updateFrame(node: self.tokenListNode, frame: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: tokenListHeight))) + transition.updateFrame(node: self.tokenListNode, frame: CGRect(origin: CGPoint(x: 16.0 + layout.safeInsets.left, y: insets.top), size: CGSize(width: layout.size.width - (16.0 + layout.safeInsets.left) * 2.0, height: tokenListHeight))) var headerInsets = layout.insets(options: [.input]) headerInsets.top += actualNavigationBarHeight - insets.top += tokenListHeight - headerInsets.top += tokenListHeight + headerInsets.top += 10.0 + tokenListHeight + 8.0 + insets = headerInsets if let footerPanelNode = self.footerPanelNode { var count = 0 diff --git a/submodules/TelegramUI/Sources/EmojisChatInputPanelItem.swift b/submodules/TelegramUI/Sources/EmojisChatInputPanelItem.swift index d193f2c4dc..99908fef41 100644 --- a/submodules/TelegramUI/Sources/EmojisChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/EmojisChatInputPanelItem.swift @@ -100,7 +100,7 @@ final class EmojisChatInputPanelItemNode: ListViewItemNode { self.symbolNode = TextNode() self.symbolNode.transform = CATransform3DMakeRotation(CGFloat.pi / 2.0, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.symbolNode) } diff --git a/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift b/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift index 0ffafe066d..9dfef707b0 100644 --- a/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/HashtagChatInputPanelItem.swift @@ -149,7 +149,7 @@ final class HashtagChatInputPanelItemNode: ListViewItemNode { self.activateAreaNode = AccessibilityAreaNode() self.activateAreaNode.accessibilityTraits = [.button] - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.separatorNode) self.addSubnode(self.titleNode) diff --git a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift index 4209c7fd69..ed79bfdbf4 100644 --- a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift @@ -133,7 +133,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode CMTimebaseSetRate(timebase!, rate: 0.0) self.timebase = timebase! - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.imageNodeBackground) diff --git a/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift b/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift index e59b7c15d3..928dba8aa7 100644 --- a/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/MentionChatInputPanelItem.swift @@ -126,7 +126,7 @@ final class MentionChatInputPanelItemNode: ListViewItemNode { self.activateAreaNode = AccessibilityAreaNode() self.activateAreaNode.accessibilityTraits = [.button] - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.separatorNode) diff --git a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelButtonItem.swift b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelButtonItem.swift index f79a3a6d7b..9e944a2875 100644 --- a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelButtonItem.swift +++ b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelButtonItem.swift @@ -96,7 +96,7 @@ final class VerticalListContextResultsChatInputPanelButtonItemNode: ListViewItem self.titleNode = TextNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.separatorNode) diff --git a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift index 274d87dbb1..86c40fa8a4 100644 --- a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift @@ -118,7 +118,7 @@ final class VerticalListContextResultsChatInputPanelItemNode: ListViewItemNode { self.iconImageNode.isLayerBacked = !smartInvertColorsEnabled() self.iconImageNode.displaysAsynchronously = false - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.separatorNode) diff --git a/submodules/TelegramUpdateUI/Sources/UpdateInfoItem.swift b/submodules/TelegramUpdateUI/Sources/UpdateInfoItem.swift index d64c98a5fa..f079434561 100644 --- a/submodules/TelegramUpdateUI/Sources/UpdateInfoItem.swift +++ b/submodules/TelegramUpdateUI/Sources/UpdateInfoItem.swift @@ -152,7 +152,7 @@ class UpdateInfoItemNode: ListViewItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.addSubnode(self.iconNode) self.addSubnode(self.overlayNode) diff --git a/submodules/TranslateUI/Sources/LocalizationListItem.swift b/submodules/TranslateUI/Sources/LocalizationListItem.swift index 0b3dda5f43..07ba6eba56 100644 --- a/submodules/TranslateUI/Sources/LocalizationListItem.swift +++ b/submodules/TranslateUI/Sources/LocalizationListItem.swift @@ -184,7 +184,7 @@ class LocalizationListItemNode: ItemListRevealOptionsItemNode { self.activateArea = AccessibilityAreaNode() - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.containerNode) diff --git a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift index 820628afde..cb232aa309 100644 --- a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift @@ -981,6 +981,9 @@ public final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgrou } private static var cachedSharedPattern: (PatternKey, UIImage)? + public private(set) var isDark: Bool? + public var isDarkUpdated: (() -> Void)? + private let _isReady = ValuePromise(false, ignoreRepeated: true) public var isReady: Signal { return self._isReady.get() diff --git a/submodules/WebSearchUI/Sources/WebSearchRecentQueryItem.swift b/submodules/WebSearchUI/Sources/WebSearchRecentQueryItem.swift index 071baf87de..a6f0d79fac 100644 --- a/submodules/WebSearchUI/Sources/WebSearchRecentQueryItem.swift +++ b/submodules/WebSearchUI/Sources/WebSearchRecentQueryItem.swift @@ -89,7 +89,7 @@ class WebSearchRecentQueryItemNode: ItemListRevealOptionsItemNode { self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode.isLayerBacked = true - super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) + super.init(layerBacked: false, rotated: false, seeThrough: false) self.addSubnode(self.backgroundNode) self.addSubnode(self.separatorNode) diff --git a/submodules/WebUI/Sources/WebAppMessageChatPreviewItem.swift b/submodules/WebUI/Sources/WebAppMessageChatPreviewItem.swift index 9f6133b1d6..68f3050050 100644 --- a/submodules/WebUI/Sources/WebAppMessageChatPreviewItem.swift +++ b/submodules/WebUI/Sources/WebAppMessageChatPreviewItem.swift @@ -160,7 +160,7 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode { self.containerNode = ASDisplayNode() self.containerNode.subnodeTransform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) - super.init(layerBacked: false, dynamicBounce: false) + super.init(layerBacked: false) self.clipsToBounds = true self.isUserInteractionEnabled = false