mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
3bbb677b0d
commit
45fa1b5ddb
@ -264,6 +264,7 @@
|
||||
"PUSH_MESSAGE_SAME_WALLPAPER" = "%1$@ set the same wallpaper for the chat with you";
|
||||
|
||||
"PUSH_MESSAGE_UNIQUE_STARGIFT" = "%1$@ sent you a Gift";
|
||||
"PUSH_MESSAGE_STARGIFT_UPGRADE" = "%1$@ upgraded your Gift";
|
||||
|
||||
"PUSH_REMINDER_TITLE" = "🗓 Reminder";
|
||||
"PUSH_SENDER_YOU" = "📅 You";
|
||||
|
@ -1266,6 +1266,8 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
var verifiedIconComponent: EmojiStatusComponent?
|
||||
var credibilityIconView: ComponentHostView<Empty>?
|
||||
var credibilityIconComponent: EmojiStatusComponent?
|
||||
var statusIconView: ComponentHostView<Empty>?
|
||||
var statusIconComponent: EmojiStatusComponent?
|
||||
let mutedIconNode: ASImageNode
|
||||
var itemTagList: ComponentView<Empty>?
|
||||
var actionButtonTitleNode: TextNode?
|
||||
@ -2142,6 +2144,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
var currentMutedIconImage: UIImage?
|
||||
var currentCredibilityIconContent: EmojiStatusComponent.Content?
|
||||
var currentVerifiedIconContent: EmojiStatusComponent.Content?
|
||||
var currentStatusIconContent: EmojiStatusComponent.Content?
|
||||
var currentSecretIconImage: UIImage?
|
||||
var currentForwardedIcon: UIImage?
|
||||
var currentStoryIcon: UIImage?
|
||||
@ -3098,7 +3101,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
} else if peer.isFake {
|
||||
currentCredibilityIconContent = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
||||
} else if let emojiStatus = peer.emojiStatus, !premiumConfiguration.isPremiumDisabled {
|
||||
currentCredibilityIconContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
||||
currentStatusIconContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||
currentCredibilityIconContent = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
||||
}
|
||||
@ -3126,7 +3129,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
} else if peer.isFake {
|
||||
currentCredibilityIconContent = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
||||
} else if let emojiStatus = peer.emojiStatus, !premiumConfiguration.isPremiumDisabled {
|
||||
currentCredibilityIconContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
||||
currentStatusIconContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||
currentCredibilityIconContent = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
||||
}
|
||||
@ -3180,6 +3183,22 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
if let currentStatusIconContent {
|
||||
if titleIconsWidth.isZero {
|
||||
titleIconsWidth += 4.0
|
||||
} else {
|
||||
titleIconsWidth += 2.0
|
||||
}
|
||||
switch currentStatusIconContent {
|
||||
case let .text(_, string):
|
||||
let textString = NSAttributedString(string: string, font: Font.bold(10.0), textColor: .black, paragraphAlignment: .center)
|
||||
let stringRect = textString.boundingRect(with: CGSize(width: 100.0, height: 16.0), options: .usesLineFragmentOrigin, context: nil)
|
||||
titleIconsWidth += floor(stringRect.width) + 11.0
|
||||
default:
|
||||
titleIconsWidth += 8.0
|
||||
}
|
||||
}
|
||||
|
||||
let layoutOffset: CGFloat = 0.0
|
||||
|
||||
let rawContentWidth = params.width - leftInset - params.rightInset - 10.0 - editingOffset
|
||||
@ -4514,6 +4533,41 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
} else {
|
||||
lastLineRect = CGRect(origin: CGPoint(), size: titleLayout.size)
|
||||
}
|
||||
|
||||
if let currentStatusIconContent {
|
||||
let statusIconView: ComponentHostView<Empty>
|
||||
if let current = strongSelf.statusIconView {
|
||||
statusIconView = current
|
||||
} else {
|
||||
statusIconView = ComponentHostView<Empty>()
|
||||
strongSelf.statusIconView = statusIconView
|
||||
strongSelf.mainContentContainerNode.view.addSubview(statusIconView)
|
||||
}
|
||||
|
||||
let statusIconComponent = EmojiStatusComponent(
|
||||
context: item.context,
|
||||
animationCache: item.interaction.animationCache,
|
||||
animationRenderer: item.interaction.animationRenderer,
|
||||
content: currentStatusIconContent,
|
||||
isVisibleForAnimations: strongSelf.visibilityStatus && item.context.sharedContext.energyUsageSettings.loopEmoji,
|
||||
action: nil
|
||||
)
|
||||
strongSelf.statusIconComponent = statusIconComponent
|
||||
|
||||
let iconOrigin: CGFloat = nextTitleIconOrigin
|
||||
let containerSize = CGSize(width: 20.0, height: 20.0)
|
||||
let iconSize = statusIconView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(statusIconComponent),
|
||||
environment: {},
|
||||
containerSize: containerSize
|
||||
)
|
||||
transition.updateFrame(view: statusIconView, frame: CGRect(origin: CGPoint(x: iconOrigin, y: floorToScreenPixels(titleFrame.maxY - lastLineRect.height * 0.5 - iconSize.height / 2.0) - UIScreenPixel), size: iconSize))
|
||||
nextTitleIconOrigin += statusIconView.bounds.width + 4.0
|
||||
} else if let statusIconView = strongSelf.statusIconView {
|
||||
strongSelf.statusIconView = nil
|
||||
statusIconView.removeFromSuperview()
|
||||
}
|
||||
|
||||
if let currentCredibilityIconContent {
|
||||
let credibilityIconView: ComponentHostView<Empty>
|
||||
|
@ -950,12 +950,13 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
||||
titleTransition = .immediate
|
||||
}
|
||||
|
||||
let iconSpacing: CGFloat = 2.0
|
||||
let titleSideInset: CGFloat = 6.0
|
||||
var titleFrame: CGRect
|
||||
if size.height > 40.0 {
|
||||
var titleInsets: UIEdgeInsets = .zero
|
||||
if case .emojiStatus = self.titleVerifiedIcon, verifiedIconWidth > 0.0 {
|
||||
titleInsets.left = verifiedIconWidth + 2.0
|
||||
titleInsets.left = verifiedIconWidth + iconSpacing
|
||||
}
|
||||
|
||||
var titleSize = self.titleTextNode.updateLayout(size: CGSize(width: clearBounds.width - leftIconWidth - credibilityIconWidth - verifiedIconWidth - statusIconWidth - rightIconWidth - titleSideInset * 2.0, height: size.height), insets: titleInsets, animated: titleTransition.isAnimated)
|
||||
|
@ -123,6 +123,11 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
let titleExpandedVerifiedIconView: ComponentHostView<Empty>
|
||||
var titleExpandedVerifiedIconSize: CGSize?
|
||||
|
||||
let titleStatusIconView: ComponentHostView<Empty>
|
||||
var statusIconSize: CGSize?
|
||||
let titleExpandedStatusIconView: ComponentHostView<Empty>
|
||||
var titleExpandedStatusIconSize: CGSize?
|
||||
|
||||
let subtitleNodeContainer: ASDisplayNode
|
||||
let subtitleNodeRawContainer: ASDisplayNode
|
||||
let subtitleNode: MultiScaleTextNode
|
||||
@ -217,6 +222,12 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
self.titleExpandedVerifiedIconView = ComponentHostView<Empty>()
|
||||
self.titleNode.stateNode(forKey: TitleNodeStateExpanded)?.view.addSubview(self.titleExpandedVerifiedIconView)
|
||||
|
||||
self.titleStatusIconView = ComponentHostView<Empty>()
|
||||
self.titleNode.stateNode(forKey: TitleNodeStateRegular)?.view.addSubview(self.titleStatusIconView)
|
||||
|
||||
self.titleExpandedStatusIconView = ComponentHostView<Empty>()
|
||||
self.titleNode.stateNode(forKey: TitleNodeStateExpanded)?.view.addSubview(self.titleExpandedStatusIconView)
|
||||
|
||||
self.subtitleNodeContainer = ASDisplayNode()
|
||||
self.subtitleNodeRawContainer = ASDisplayNode()
|
||||
self.subtitleNode = MultiScaleTextNode(stateKeys: [TitleNodeStateRegular, TitleNodeStateExpanded])
|
||||
@ -465,6 +476,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
|
||||
private var currentCredibilityIcon: CredibilityIcon?
|
||||
private var currentVerifiedIcon: CredibilityIcon?
|
||||
private var currentStatusIcon: CredibilityIcon?
|
||||
|
||||
private var currentPanelStatusData: PeerInfoStatusData?
|
||||
func update(width: CGFloat, containerHeight: CGFloat, containerInset: CGFloat, statusBarHeight: CGFloat, navigationHeight: CGFloat, isModalOverlay: Bool, isMediaOnly: Bool, contentOffset: CGFloat, paneContainerY: CGFloat, presentationData: PresentationData, peer: Peer?, cachedData: CachedPeerData?, threadData: MessageHistoryThreadData?, peerNotificationSettings: TelegramPeerNotificationSettings?, threadNotificationSettings: TelegramPeerNotificationSettings?, globalNotificationSettings: EngineGlobalNotificationSettings?, statusData: PeerInfoStatusData?, panelStatusData: (PeerInfoStatusData?, PeerInfoStatusData?, CGFloat?), isSecretChat: Bool, isContact: Bool, isSettings: Bool, state: PeerInfoState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, transition: ContainedViewLayoutTransition, additive: Bool, animateHeader: Bool) -> CGFloat {
|
||||
@ -521,9 +533,10 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
self.presentationData = presentationData
|
||||
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: self.context.currentAppConfiguration.with { $0 })
|
||||
var credibilityIcon: CredibilityIcon
|
||||
var credibilityIcon: CredibilityIcon = .none
|
||||
var verifiedIcon: CredibilityIcon = .none
|
||||
if let peer = peer {
|
||||
var statusIcon: CredibilityIcon = .none
|
||||
if let peer {
|
||||
if peer.id == self.context.account.peerId && !self.isSettings && !self.isMyProfile {
|
||||
credibilityIcon = .none
|
||||
} else if peer.isFake {
|
||||
@ -531,7 +544,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
} else if peer.isScam {
|
||||
credibilityIcon = .scam
|
||||
} else if let emojiStatus = peer.emojiStatus, !premiumConfiguration.isPremiumDisabled {
|
||||
credibilityIcon = .emojiStatus(emojiStatus)
|
||||
statusIcon = .emojiStatus(emojiStatus)
|
||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled && (peer.id != self.context.account.peerId || self.isSettings || self.isMyProfile) {
|
||||
credibilityIcon = .premium
|
||||
} else {
|
||||
@ -543,8 +556,6 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
if let verificationIconFileId = peer.verificationIconFileId {
|
||||
verifiedIcon = .emojiStatus(PeerEmojiStatus(fileId: verificationIconFileId, expirationDate: nil))
|
||||
}
|
||||
} else {
|
||||
credibilityIcon = .none
|
||||
}
|
||||
|
||||
var isForum = false
|
||||
@ -808,7 +819,70 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.displayPremiumIntro?(strongSelf.titleCredibilityIconView, currentEmojiStatus, strongSelf.emojiStatusFileAndPackTitle.get(), false)
|
||||
if case .premium = strongSelf.currentCredibilityIcon {
|
||||
strongSelf.displayPremiumIntro?(strongSelf.titleCredibilityIconView, currentEmojiStatus, strongSelf.emojiStatusFileAndPackTitle.get(), false)
|
||||
}
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 26.0, height: 26.0)
|
||||
)
|
||||
let expandedIconSize = self.titleExpandedCredibilityIconView.update(
|
||||
transition: ComponentTransition(navigationTransition),
|
||||
component: AnyComponent(EmojiStatusComponent(
|
||||
context: self.context,
|
||||
animationCache: self.animationCache,
|
||||
animationRenderer: self.animationRenderer,
|
||||
content: emojiExpandedStatusContent,
|
||||
isVisibleForAnimations: true,
|
||||
useSharedAnimation: true,
|
||||
action: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if case .premium = strongSelf.currentCredibilityIcon {
|
||||
strongSelf.displayPremiumIntro?(strongSelf.titleExpandedCredibilityIconView, currentEmojiStatus, strongSelf.emojiStatusFileAndPackTitle.get(), true)
|
||||
}
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 26.0, height: 26.0)
|
||||
)
|
||||
|
||||
self.credibilityIconSize = iconSize
|
||||
self.titleExpandedCredibilityIconSize = expandedIconSize
|
||||
}
|
||||
|
||||
do {
|
||||
self.currentStatusIcon = statusIcon
|
||||
|
||||
var currentEmojiStatus: PeerEmojiStatus?
|
||||
let emojiRegularStatusContent: EmojiStatusComponent.Content
|
||||
let emojiExpandedStatusContent: EmojiStatusComponent.Content
|
||||
switch statusIcon {
|
||||
case let .emojiStatus(emojiStatus):
|
||||
currentEmojiStatus = emojiStatus
|
||||
emojiRegularStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: presentationData.theme.list.mediaPlaceholderColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
||||
emojiExpandedStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: navigationContentsAccentColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
||||
default:
|
||||
emojiRegularStatusContent = .none
|
||||
emojiExpandedStatusContent = .none
|
||||
}
|
||||
|
||||
let iconSize = self.titleStatusIconView.update(
|
||||
transition: ComponentTransition(navigationTransition),
|
||||
component: AnyComponent(EmojiStatusComponent(
|
||||
context: self.context,
|
||||
animationCache: self.animationCache,
|
||||
animationRenderer: self.animationRenderer,
|
||||
content: emojiRegularStatusContent,
|
||||
isVisibleForAnimations: true,
|
||||
useSharedAnimation: true,
|
||||
action: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.displayPremiumIntro?(strongSelf.titleStatusIconView, currentEmojiStatus, strongSelf.emojiStatusFileAndPackTitle.get(), false)
|
||||
},
|
||||
emojiFileUpdated: { [weak self] emojiFile in
|
||||
guard let strongSelf = self else {
|
||||
@ -851,7 +925,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 26.0, height: 26.0)
|
||||
)
|
||||
let expandedIconSize = self.titleExpandedCredibilityIconView.update(
|
||||
let expandedIconSize = self.titleExpandedStatusIconView.update(
|
||||
transition: ComponentTransition(navigationTransition),
|
||||
component: AnyComponent(EmojiStatusComponent(
|
||||
context: self.context,
|
||||
@ -864,15 +938,15 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.displayPremiumIntro?(strongSelf.titleExpandedCredibilityIconView, currentEmojiStatus, strongSelf.emojiStatusFileAndPackTitle.get(), true)
|
||||
strongSelf.displayPremiumIntro?(strongSelf.titleExpandedStatusIconView, currentEmojiStatus, strongSelf.emojiStatusFileAndPackTitle.get(), true)
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 26.0, height: 26.0)
|
||||
)
|
||||
|
||||
self.credibilityIconSize = iconSize
|
||||
self.titleExpandedCredibilityIconSize = expandedIconSize
|
||||
self.statusIconSize = iconSize
|
||||
self.titleExpandedStatusIconSize = expandedIconSize
|
||||
}
|
||||
|
||||
do {
|
||||
@ -1307,6 +1381,25 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
var nextIconX: CGFloat = titleSize.width
|
||||
var nextExpandedIconX: CGFloat = titleExpandedSize.width
|
||||
|
||||
if let statusIconSize = self.statusIconSize, let titleExpandedStatusIconSize = self.titleExpandedStatusIconSize, statusIconSize.width > 0.0 {
|
||||
let offset = (statusIconSize.width + 4.0) / 2.0
|
||||
|
||||
let leftOffset: CGFloat = nextIconX + 4.0
|
||||
let leftExpandedOffset: CGFloat = nextExpandedIconX + 4.0
|
||||
titleHorizontalOffset -= offset
|
||||
|
||||
var collapsedTransitionOffset: CGFloat = 0.0
|
||||
if let navigationTransition = self.navigationTransition {
|
||||
collapsedTransitionOffset = -10.0 * navigationTransition.fraction
|
||||
}
|
||||
|
||||
transition.updateFrame(view: self.titleStatusIconView, frame: CGRect(origin: CGPoint(x: leftOffset + collapsedTransitionOffset, y: floor((titleSize.height - statusIconSize.height) / 2.0)), size: statusIconSize))
|
||||
transition.updateFrame(view: self.titleExpandedStatusIconView, frame: CGRect(origin: CGPoint(x: leftExpandedOffset, y: floor((titleExpandedSize.height - titleExpandedStatusIconSize.height) / 2.0) + 1.0), size: titleExpandedStatusIconSize))
|
||||
|
||||
nextIconX += 4.0 + statusIconSize.width
|
||||
nextExpandedIconX += 4.0 + titleExpandedStatusIconSize.width
|
||||
}
|
||||
|
||||
if let credibilityIconSize = self.credibilityIconSize, let titleExpandedCredibilityIconSize = self.titleExpandedCredibilityIconSize, credibilityIconSize.width > 0.0 {
|
||||
let offset = (credibilityIconSize.width + 4.0) / 2.0
|
||||
|
||||
@ -1325,7 +1418,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
nextIconX += 4.0 + credibilityIconSize.width
|
||||
nextExpandedIconX += 4.0 + titleExpandedCredibilityIconSize.width
|
||||
}
|
||||
|
||||
|
||||
if let verifiedIconSize = self.verifiedIconSize, let titleExpandedVerifiedIconSize = self.titleExpandedVerifiedIconSize, verifiedIconSize.width > 0.0 {
|
||||
let leftOffset: CGFloat
|
||||
let leftExpandedOffset: CGFloat
|
||||
@ -2220,7 +2313,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
|
||||
if !(self.state?.isEditing ?? false) {
|
||||
switch self.currentCredibilityIcon {
|
||||
case .premium, .emojiStatus:
|
||||
case .premium:
|
||||
let iconFrame = self.titleCredibilityIconView.convert(self.titleCredibilityIconView.bounds, to: self.view)
|
||||
let expandedIconFrame = self.titleExpandedCredibilityIconView.convert(self.titleExpandedCredibilityIconView.bounds, to: self.view)
|
||||
if expandedIconFrame.contains(point) && self.isAvatarExpanded {
|
||||
@ -2231,6 +2324,18 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
default:
|
||||
break
|
||||
}
|
||||
switch self.currentStatusIcon {
|
||||
case .emojiStatus:
|
||||
let iconFrame = self.titleStatusIconView.convert(self.titleStatusIconView.bounds, to: self.view)
|
||||
let expandedIconFrame = self.titleExpandedStatusIconView.convert(self.titleExpandedStatusIconView.bounds, to: self.view)
|
||||
if expandedIconFrame.contains(point) && self.isAvatarExpanded {
|
||||
return self.titleExpandedStatusIconView.hitTest(self.view.convert(point, to: self.titleExpandedStatusIconView), with: event)
|
||||
} else if iconFrame.contains(point) {
|
||||
return self.titleStatusIconView.hitTest(self.view.convert(point, to: self.titleStatusIconView), with: event)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if let subtitleBackgroundButton = self.subtitleBackgroundButton, subtitleBackgroundButton.view.convert(subtitleBackgroundButton.bounds, to: self.view).contains(point) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user