Group boosts

This commit is contained in:
Ilya Laktyushin 2024-02-07 18:57:18 +04:00
parent a8cff5c5e0
commit 714bcf7af3
9 changed files with 31 additions and 112 deletions

View File

@ -11214,3 +11214,13 @@ Sorry for the inconvenience.";
"GroupBoost.AdditionalFeatures" = "Additional Features";
"GroupBoost.AdditionalFeaturesText" = "By gaining **boosts**, your group reaches higher levels and unlocks more features.";
"Stats.Boosts.Group.NoBoostersYet" = "No users currently boost your group";
"Stats.Boosts.Group.BoostersInfo" = "Your group is currently boosted by these members.";
"Group.Appearance.PreviewAuthor" = "Jessica";
"GroupBoost.Title" = "Boost Group";
"GroupBoost.Info" = "Members of your group can **boost** it so that it **levels up** and gets **exclusive features**.";
"Chat.GroupEmojiTooltip" = "All members of this group can\nuse the # **%@** pack";

View File

@ -75,98 +75,6 @@ public final class BoostHeaderBackgroundComponent: Component {
Queue.mainQueue().justDispatch {
self._ready.set(.single(true))
self.onReady()
}
}
}
private func onReady() {
self.playAppearanceAnimation(explode: true)
}
private func playAppearanceAnimation(velocity: CGFloat? = nil, smallAngle: Bool = false, mirror: Bool = false, explode: Bool = false) {
guard let scene = self.sceneView.scene else {
return
}
let currentTime = CACurrentMediaTime()
self.previousInteractionTimestamp = currentTime
if explode, let node = scene.rootNode.childNode(withName: "swirl", recursively: false), let particlesLeft = scene.rootNode.childNode(withName: "particles_left", recursively: false), let particlesRight = scene.rootNode.childNode(withName: "particles_right", recursively: false), let particlesBottomLeft = scene.rootNode.childNode(withName: "particles_left_bottom", recursively: false), let particlesBottomRight = scene.rootNode.childNode(withName: "particles_right_bottom", recursively: false) {
if let leftParticleSystem = particlesLeft.particleSystems?.first, let rightParticleSystem = particlesRight.particleSystems?.first, let leftBottomParticleSystem = particlesBottomLeft.particleSystems?.first, let rightBottomParticleSystem = particlesBottomRight.particleSystems?.first {
leftParticleSystem.speedFactor = 2.0
leftParticleSystem.particleVelocity = 1.6
leftParticleSystem.birthRate = 60.0
leftParticleSystem.particleLifeSpan = 4.0
rightParticleSystem.speedFactor = 2.0
rightParticleSystem.particleVelocity = 1.6
rightParticleSystem.birthRate = 60.0
rightParticleSystem.particleLifeSpan = 4.0
// leftBottomParticleSystem.speedFactor = 2.0
leftBottomParticleSystem.particleVelocity = 1.6
leftBottomParticleSystem.birthRate = 24.0
leftBottomParticleSystem.particleLifeSpan = 7.0
// rightBottomParticleSystem.speedFactor = 2.0
rightBottomParticleSystem.particleVelocity = 1.6
rightBottomParticleSystem.birthRate = 24.0
rightBottomParticleSystem.particleLifeSpan = 7.0
node.physicsField?.isActive = true
Queue.mainQueue().after(1.0) {
node.physicsField?.isActive = false
leftParticleSystem.birthRate = 12.0
leftParticleSystem.particleVelocity = 1.2
leftParticleSystem.particleLifeSpan = 3.0
rightParticleSystem.birthRate = 12.0
rightParticleSystem.particleVelocity = 1.2
rightParticleSystem.particleLifeSpan = 3.0
leftBottomParticleSystem.particleVelocity = 1.2
leftBottomParticleSystem.birthRate = 7.0
leftBottomParticleSystem.particleLifeSpan = 5.0
rightBottomParticleSystem.particleVelocity = 1.2
rightBottomParticleSystem.birthRate = 7.0
rightBottomParticleSystem.particleLifeSpan = 5.0
let leftAnimation = POPBasicAnimation()
leftAnimation.property = (POPAnimatableProperty.property(withName: "speedFactor", initializer: { property in
property?.readBlock = { particleSystem, values in
values?.pointee = (particleSystem as! SCNParticleSystem).speedFactor
}
property?.writeBlock = { particleSystem, values in
(particleSystem as! SCNParticleSystem).speedFactor = values!.pointee
}
property?.threshold = 0.01
}) as! POPAnimatableProperty)
leftAnimation.fromValue = 1.2 as NSNumber
leftAnimation.toValue = 0.85 as NSNumber
leftAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
leftAnimation.duration = 0.5
leftParticleSystem.pop_add(leftAnimation, forKey: "speedFactor")
let rightAnimation = POPBasicAnimation()
rightAnimation.property = (POPAnimatableProperty.property(withName: "speedFactor", initializer: { property in
property?.readBlock = { particleSystem, values in
values?.pointee = (particleSystem as! SCNParticleSystem).speedFactor
}
property?.writeBlock = { particleSystem, values in
(particleSystem as! SCNParticleSystem).speedFactor = values!.pointee
}
property?.threshold = 0.01
}) as! POPAnimatableProperty)
rightAnimation.fromValue = 1.2 as NSNumber
rightAnimation.toValue = 0.85 as NSNumber
rightAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
rightAnimation.duration = 0.5
rightParticleSystem.pop_add(rightAnimation, forKey: "speedFactor")
}
}
}
}

View File

@ -318,7 +318,7 @@ private final class BoostHeaderComponent: CombinedComponent {
transition: context.transition
)
context.add(stars
.position(CGPoint(x: size.width / 2.0, y: size.height / 2.0 + 20.0))
.position(CGPoint(x: size.width / 2.0, y: size.height / 2.0 + 10.0))
)
let level = component.status.level

View File

@ -963,10 +963,10 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
if let boostersState, boostersState.count > 0 {
boostersTitle = presentationData.strings.Stats_Boosts_Boosts(boostersState.count)
boostersPlaceholder = nil
boostersFooter = isGroup ? "Your group is currently boosted by these members." : presentationData.strings.Stats_Boosts_BoostersInfo
boostersFooter = isGroup ? presentationData.strings.Stats_Boosts_Group_BoostersInfo : presentationData.strings.Stats_Boosts_BoostersInfo
} else {
boostersTitle = presentationData.strings.Stats_Boosts_BoostsNone
boostersPlaceholder = presentationData.strings.Stats_Boosts_NoBoostersYet
boostersPlaceholder = isGroup ? presentationData.strings.Stats_Boosts_Group_NoBoostersYet : presentationData.strings.Stats_Boosts_NoBoostersYet
boostersFooter = nil
}
entries.append(.boostersTitle(presentationData.theme, boostersTitle))
@ -1303,14 +1303,13 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
return map
}
//TODO:localize
var title: ItemListControllerTitle
var headerItem: BoostHeaderItem?
var leftNavigationButton: ItemListNavigationButton?
var boostsOnly = false
if isGroup, section == .boosts, let boostStatus {
title = .text("")
headerItem = BoostHeaderItem(context: context, theme: presentationData.theme, strings: presentationData.strings, status: boostStatus, title: "Boost Group", text: "Members of your group can **boost** it so that it **levels up** and gets **exclusive features**.", openBoost: {
headerItem = BoostHeaderItem(context: context, theme: presentationData.theme, strings: presentationData.strings, status: boostStatus, title: presentationData.strings.GroupBoost_Title, text: presentationData.strings.GroupBoost_Info, openBoost: {
openBoostImpl?(false)
}, createGiveaway: {
arguments.openGifts()

View File

@ -1493,7 +1493,7 @@ final class ChannelAppearanceScreenComponent: Component {
photo: peer.profileImageRepresentations,
nameColor: resolvedState.nameColor,
backgroundEmojiId: replyFileId,
reply: (peer.compactDisplayTitle, environment.strings.Channel_Appearance_ExampleReplyText),
reply: (peer.compactDisplayTitle, environment.strings.Channel_Appearance_ExampleReplyText, resolvedState.nameColor),
linkPreview: (environment.strings.Channel_Appearance_ExampleLinkWebsite, environment.strings.Channel_Appearance_ExampleLinkTitle, environment.strings.Channel_Appearance_ExampleLinkText),
text: environment.strings.Channel_Appearance_ExampleText
)
@ -1624,11 +1624,11 @@ final class ChannelAppearanceScreenComponent: Component {
let incomingMessageItem = PeerNameColorChatPreviewItem.MessageItem(
outgoing: false,
peerId: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0)),
author: peer.compactDisplayTitle,
photo: peer.profileImageRepresentations,
author: environment.strings.Group_Appearance_PreviewAuthor,
photo: [],
nameColor: .red,
backgroundEmojiId: nil,
reply: (environment.strings.Appearance_PreviewReplyAuthor, environment.strings.Appearance_PreviewReplyText),
backgroundEmojiId: 5301072507598550489,
reply: (environment.strings.Appearance_PreviewReplyAuthor, environment.strings.Appearance_PreviewReplyText, .violet),
linkPreview: nil,
text: environment.strings.Appearance_PreviewIncomingText
)

View File

@ -35,7 +35,7 @@ final class PeerNameColorChatPreviewItem: ListViewItem, ItemListItem, ListItemCo
if lhs.backgroundEmojiId != rhs.backgroundEmojiId {
return false
}
if let lhsReply = lhs.reply, let rhsReply = rhs.reply, lhsReply.0 != rhsReply.0 || lhsReply.1 != rhsReply.1 {
if let lhsReply = lhs.reply, let rhsReply = rhs.reply, lhsReply.0 != rhsReply.0 || lhsReply.1 != rhsReply.1 || lhsReply.2 != rhsReply.2 {
return false
} else if (lhs.reply == nil) != (rhs.reply == nil) {
return false
@ -57,7 +57,7 @@ final class PeerNameColorChatPreviewItem: ListViewItem, ItemListItem, ListItemCo
let photo: [TelegramMediaImageRepresentation]
let nameColor: PeerNameColor
let backgroundEmojiId: Int64?
let reply: (String, String)?
let reply: (String, String, PeerNameColor)?
let linkPreview: (String, String, String)?
let text: String
}
@ -220,15 +220,19 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode {
var items: [ListViewItem] = []
for messageItem in item.messageItems.reversed() {
let authorPeerId = messageItem.peerId
let replyAuthorPeerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(10))
var peers = SimpleDictionary<PeerId, Peer>()
var messages = SimpleDictionary<MessageId, Message>()
peers[authorPeerId] = TelegramUser(id: authorPeerId, accessHash: nil, firstName: messageItem.author, lastName: "", username: nil, phone: nil, photo: messageItem.photo, botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: messageItem.nameColor, backgroundEmojiId: messageItem.backgroundEmojiId, profileColor: nil, profileBackgroundEmojiId: nil)
let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3)
if let (_, text) = messageItem.reply {
messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: peers[authorPeerId], text: text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
if let (replyAuthor, text, replyColor) = messageItem.reply {
peers[replyAuthorPeerId] = TelegramUser(id: authorPeerId, accessHash: nil, firstName: replyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: replyColor, backgroundEmojiId: messageItem.backgroundEmojiId, profileColor: nil, profileBackgroundEmojiId: nil)
messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: peers[replyAuthorPeerId], text: text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
}
var media: [Media] = []

View File

@ -315,7 +315,7 @@ private func peerNameColorScreenEntries(
photo: peer.profileImageRepresentations,
nameColor: nameColor,
backgroundEmojiId: backgroundEmojiId,
reply: (peer.compactDisplayTitle, replyText),
reply: (peer.compactDisplayTitle, replyText, nameColor),
linkPreview: (presentationData.strings.NameColor_ChatPreview_LinkSite, presentationData.strings.NameColor_ChatPreview_LinkTitle, presentationData.strings.NameColor_ChatPreview_LinkText),
text: messageText
)

View File

@ -15673,10 +15673,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
guard let emojiPack = (self.peerView?.cachedData as? CachedChannelData)?.emojiPack, let thumbnailFileId = emojiPack.thumbnailFileId else {
return
}
//TODO:localize
let _ = (self.context.engine.stickers.resolveInlineStickers(fileIds: [thumbnailFileId])
|> deliverOnMainQueue).start(next: { files in
guard let emojiFile = files.values.first else {
|> deliverOnMainQueue).start(next: { [weak self] files in
guard let self, let emojiFile = files.values.first else {
return
}
@ -15687,7 +15686,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return nil
})
let text = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString("All members of this group can\nuse the # **\(emojiPack.title)** pack", attributes: markdownAttributes))
let text = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(self.presentationData.strings.Chat_GroupEmojiTooltip(emojiPack.title).string, attributes: markdownAttributes))
let range = (text.string as NSString).range(of: "#")
if range.location != NSNotFound {
@ -15699,7 +15698,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
account: self.context.account,
sharedContext: self.context.sharedContext,
text: .attributedString(text: text),
// style: .customBlur(UIColor(rgb: 0x000000, alpha: 0.8), 2.0),
location: .point(rect.offsetBy(dx: 0.0, dy: -3.0), .bottom),
displayDuration: .default,
cornerRadius: 10.0,