Various fixes

This commit is contained in:
Ilya Laktyushin 2023-11-27 19:30:11 +04:00
parent 31925248bd
commit 3cc5782dec
7 changed files with 151 additions and 82 deletions

View File

@ -10554,3 +10554,6 @@ Sorry for the inconvenience.";
"Chat.ChannelRecommendation.PremiumTooltip" = "Subcribe to [Telegram Premium]() to unlock up to **100** channels."; "Chat.ChannelRecommendation.PremiumTooltip" = "Subcribe to [Telegram Premium]() to unlock up to **100** channels.";
"Story.ForwardAuthorHiddenTooltip" = "The account was hidden by the user"; "Story.ForwardAuthorHiddenTooltip" = "The account was hidden by the user";
"Premium.Limits.RecommendedChannels" = "Similar Channels";
"Premium.Limits.RecommendedChannelsInfo" = "View up to 100 similar channels.";

View File

@ -198,29 +198,32 @@ private enum Limit: CaseIterable {
case folders case folders
case chatsPerFolder case chatsPerFolder
case account case account
case recommendedChannels
func title(strings: PresentationStrings) -> String { func title(strings: PresentationStrings) -> String {
switch self { switch self {
case .groups: case .groups:
return strings.Premium_Limits_GroupsAndChannels return strings.Premium_Limits_GroupsAndChannels
case .pins: case .pins:
return strings.Premium_Limits_PinnedChats return strings.Premium_Limits_PinnedChats
case .publicLinks: case .publicLinks:
return strings.Premium_Limits_PublicLinks return strings.Premium_Limits_PublicLinks
case .savedGifs: case .savedGifs:
return strings.Premium_Limits_SavedGifs return strings.Premium_Limits_SavedGifs
case .favedStickers: case .favedStickers:
return strings.Premium_Limits_FavedStickers return strings.Premium_Limits_FavedStickers
case .about: case .about:
return strings.Premium_Limits_Bio return strings.Premium_Limits_Bio
case .captions: case .captions:
return strings.Premium_Limits_Captions return strings.Premium_Limits_Captions
case .folders: case .folders:
return strings.Premium_Limits_Folders return strings.Premium_Limits_Folders
case .chatsPerFolder: case .chatsPerFolder:
return strings.Premium_Limits_ChatsPerFolder return strings.Premium_Limits_ChatsPerFolder
case .account: case .account:
return strings.Premium_Limits_Accounts return strings.Premium_Limits_Accounts
case .recommendedChannels:
return strings.Premium_Limits_RecommendedChannels
} }
} }
@ -246,6 +249,8 @@ private enum Limit: CaseIterable {
return strings.Premium_Limits_ChatsPerFolderInfo return strings.Premium_Limits_ChatsPerFolderInfo
case .account: case .account:
return strings.Premium_Limits_AccountsInfo return strings.Premium_Limits_AccountsInfo
case .recommendedChannels:
return strings.Premium_Limits_RecommendedChannelsInfo
} }
} }
@ -272,6 +277,8 @@ private enum Limit: CaseIterable {
value = configuration.maxFolderChatsCount value = configuration.maxFolderChatsCount
case .account: case .account:
value = isPremium ? 4 : 3 value = isPremium ? 4 : 3
case .recommendedChannels:
value = configuration.maxChannelRecommendationsCount
} }
return "\(value)" return "\(value)"
} }
@ -360,7 +367,8 @@ private final class LimitsListComponent: CombinedComponent {
UIColor(rgb: 0xdb5887), UIColor(rgb: 0xdb5887),
UIColor(rgb: 0xdb496f), UIColor(rgb: 0xdb496f),
UIColor(rgb: 0xe95d44), UIColor(rgb: 0xe95d44),
UIColor(rgb: 0xf2822a) UIColor(rgb: 0xf2822a),
UIColor(rgb: 0xfdb529)
] ]
let items: [AnyComponentWithIdentity<Empty>] = Limit.allCases.enumerated().map { index, value in let items: [AnyComponentWithIdentity<Empty>] = Limit.allCases.enumerated().map { index, value in

View File

@ -87,8 +87,8 @@ enum StatsPostItem: Equatable {
} else { } else {
return false return false
} }
case let .story(lhsStory): case let .story(lhsPeer, lhsStory):
if case let .story(rhsStory) = rhs, lhsStory == rhsStory { if case let .story(rhsPeer, rhsStory) = rhs, lhsPeer == rhsPeer, lhsStory == rhsStory {
return true return true
} else { } else {
return false return false
@ -97,7 +97,7 @@ enum StatsPostItem: Equatable {
} }
case message(Message) case message(Message)
case story(EngineStoryItem) case story(EnginePeer, EngineStoryItem)
var isStory: Bool { var isStory: Bool {
if case .story = self { if case .story = self {
@ -111,7 +111,7 @@ enum StatsPostItem: Equatable {
switch self { switch self {
case let .message(message): case let .message(message):
return message.timestamp return message.timestamp
case let .story(story): case let .story(_, story):
return story.timestamp return story.timestamp
} }
} }
@ -656,7 +656,7 @@ private enum StatsEntry: ItemListNodeEntry {
return StatsMessageItem(context: arguments.context, presentationData: presentationData, peer: peer, item: post, views: interactions.views, reactions: interactions.reactions, forwards: interactions.forwards, sectionId: self.section, style: .blocks, action: { return StatsMessageItem(context: arguments.context, presentationData: presentationData, peer: peer, item: post, views: interactions.views, reactions: interactions.reactions, forwards: interactions.forwards, sectionId: self.section, style: .blocks, action: {
arguments.openPostStats(EnginePeer(peer), post) arguments.openPostStats(EnginePeer(peer), post)
}, openStory: { sourceView in }, openStory: { sourceView in
if case let .story(story) = post { if case let .story(_, story) = post {
arguments.openStory(story, sourceView) arguments.openStory(story, sourceView)
} }
}, contextAction: !post.isStory ? { node, gesture in }, contextAction: !post.isStory ? { node, gesture in
@ -908,7 +908,7 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
if let stories { if let stories {
for story in stories.items { for story in stories.items {
if let _ = interactions[.story(peerId: peer.id, id: story.id)] { if let _ = interactions[.story(peerId: peer.id, id: story.id)] {
posts.append(.story(story)) posts.append(.story(peer, story))
} }
} }
} }
@ -923,7 +923,7 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
if let interactions = interactions[.message(id: message.id)] { if let interactions = interactions[.message(id: message.id)] {
entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), post, interactions)) entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), post, interactions))
} }
case let .story(story): case let .story(_, story):
if let interactions = interactions[.story(peerId: peer.id, id: story.id)] { if let interactions = interactions[.story(peerId: peer.id, id: story.id)] {
entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), post, interactions)) entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), post, interactions))
} }
@ -1313,7 +1313,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
switch post { switch post {
case let .message(message): case let .message(message):
subject = .message(id: message.id) subject = .message(id: message.id)
case let .story(story): case let .story(_, story):
subject = .story(peerId: peerId, id: story.id, item: story, fromStory: false) subject = .story(peerId: peerId, id: story.id, item: story, fromStory: false)
} }
controller?.push(messageStatsController(context: context, subject: subject)) controller?.push(messageStatsController(context: context, subject: subject))

View File

@ -21,11 +21,13 @@ private final class MessageStatsControllerArguments {
let context: AccountContext let context: AccountContext
let loadDetailedGraph: (StatsGraph, Int64) -> Signal<StatsGraph?, NoError> let loadDetailedGraph: (StatsGraph, Int64) -> Signal<StatsGraph?, NoError>
let openMessage: (EngineMessage.Id) -> Void let openMessage: (EngineMessage.Id) -> Void
let openStory: (EnginePeer.Id, EngineStoryItem, UIView) -> Void
init(context: AccountContext, loadDetailedGraph: @escaping (StatsGraph, Int64) -> Signal<StatsGraph?, NoError>, openMessage: @escaping (EngineMessage.Id) -> Void) { init(context: AccountContext, loadDetailedGraph: @escaping (StatsGraph, Int64) -> Signal<StatsGraph?, NoError>, openMessage: @escaping (EngineMessage.Id) -> Void, openStory: @escaping (EnginePeer.Id, EngineStoryItem, UIView) -> Void) {
self.context = context self.context = context
self.loadDetailedGraph = loadDetailedGraph self.loadDetailedGraph = loadDetailedGraph
self.openMessage = openMessage self.openMessage = openMessage
self.openStory = openStory
} }
} }
@ -47,7 +49,7 @@ private enum StatsEntry: ItemListNodeEntry {
case reactionsGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, ChartType, Bool) case reactionsGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, ChartType, Bool)
case publicForwardsTitle(PresentationTheme, String) case publicForwardsTitle(PresentationTheme, String)
case publicForward(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, EngineMessage) case publicForward(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsPostItem)
var section: ItemListSectionId { var section: ItemListSectionId {
switch self { switch self {
@ -133,8 +135,8 @@ private enum StatsEntry: ItemListNodeEntry {
} else { } else {
return false return false
} }
case let .publicForward(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsMessage): case let .publicForward(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPost):
if case let .publicForward(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsMessage) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsMessage.id == rhsMessage.id { if case let .publicForward(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPost) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsPost == rhsPost {
return true return true
} else { } else {
return false return false
@ -164,38 +166,44 @@ private enum StatsEntry: ItemListNodeEntry {
} }
}) })
}, sectionId: self.section, style: .blocks) }, sectionId: self.section, style: .blocks)
case let .publicForward(_, _, _, _, message): case let .publicForward(_, _, _, _, item):
var views: Int32 = 0 var views: Int32 = 0
var forwards: Int32 = 0 var forwards: Int32 = 0
var reactions: Int32 = 0 var reactions: Int32 = 0
for attribute in message.attributes {
if let viewsAttribute = attribute as? ViewCountMessageAttribute { let peer: Peer
views = Int32(viewsAttribute.count) switch item {
} else if let forwardsAttribute = attribute as? ForwardCountMessageAttribute { case let .message(message):
forwards = Int32(forwardsAttribute.count) peer = message.peers[message.id.peerId]!
} else if let reactionsAttribute = attribute as? ReactionsMessageAttribute { for attribute in message.attributes {
reactions = reactionsAttribute.reactions.reduce(0, { partialResult, reaction in if let viewsAttribute = attribute as? ViewCountMessageAttribute {
return partialResult + reaction.count views = Int32(viewsAttribute.count)
}) } else if let forwardsAttribute = attribute as? ForwardCountMessageAttribute {
forwards = Int32(forwardsAttribute.count)
} else if let reactionsAttribute = attribute as? ReactionsMessageAttribute {
reactions = reactionsAttribute.reactions.reduce(0, { partialResult, reaction in
return partialResult + reaction.count
})
}
} }
case let .story(peerValue, story):
peer = peerValue._asPeer()
views = Int32(story.views?.seenCount ?? 0)
forwards = Int32(story.views?.forwardCount ?? 0)
reactions = Int32(story.views?.reactedCount ?? 0)
} }
let peer = message.peers[message.id.peerId]! return StatsMessageItem(context: arguments.context, presentationData: presentationData, peer: peer, item: item, views: views, reactions: reactions, forwards: forwards, isPeer: true, sectionId: self.section, style: .blocks, action: {
return StatsMessageItem(context: arguments.context, presentationData: presentationData, peer: peer, item: .message(message._asMessage()), views: views, reactions: reactions, forwards: forwards, isPeer: true, sectionId: self.section, style: .blocks, action: { switch item {
arguments.openMessage(message.id) case let .message(message):
}, openStory: { _ in }, contextAction: nil) arguments.openMessage(message.id)
// var views: Int32 = 0 case .story:
// for attribute in message.attributes { break
// if let viewsAttribute = attribute as? ViewCountMessageAttribute { }
// views = Int32(viewsAttribute.count) }, openStory: { view in
// break if case let .story(peer, story) = item {
// } arguments.openStory(peer.id, story, view)
// } }
// }, contextAction: nil)
//
// let text: String = presentationData.strings.Stats_MessageViews(views)
// return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: PresentationDateTimeFormat(), nameDisplayOrder: .firstLast, context: arguments.context, peer: EnginePeer(message.peers[message.id.peerId]!), height: .generic, aliasHandling: .standard, nameColor: .primary, nameStyle: .plain, presence: nil, text: .text(text, .secondary), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: nil), revealOptions: nil, switchValue: nil, enabled: true, highlighted: false, selectable: true, sectionId: self.section, action: {
// arguments.openMessage(message.id)
// }, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, contextAction: nil)
} }
} }
} }
@ -243,7 +251,7 @@ private func messageStatsControllerEntries(data: PostStats?, storyViews: EngineS
entries.append(.publicForwardsTitle(presentationData.theme, presentationData.strings.Stats_MessagePublicForwardsTitle.uppercased())) entries.append(.publicForwardsTitle(presentationData.theme, presentationData.strings.Stats_MessagePublicForwardsTitle.uppercased()))
var index: Int32 = 0 var index: Int32 = 0
for message in messages.messages { for message in messages.messages {
entries.append(.publicForward(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, EngineMessage(message))) entries.append(.publicForward(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, .message(message)))
index += 1 index += 1
} }
} }
@ -254,9 +262,9 @@ private func messageStatsControllerEntries(data: PostStats?, storyViews: EngineS
for forward in forwards.forwards { for forward in forwards.forwards {
switch forward { switch forward {
case let .message(message): case let .message(message):
entries.append(.publicForward(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, message)) entries.append(.publicForward(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, .message(message._asMessage())))
case let .story(story): case let .story(peer, story):
let _ = story entries.append(.publicForward(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, .story(peer, story)))
} }
index += 1 index += 1
} }
@ -296,7 +304,7 @@ public func messageStatsController(context: AccountContext, updatedPresentationD
let anyStatsContext: Any let anyStatsContext: Any
let dataSignal: Signal<PostStats?, NoError> let dataSignal: Signal<PostStats?, NoError>
var loadDetailedGraphImpl: ((StatsGraph, Int64) -> Signal<StatsGraph?, NoError>)? var loadDetailedGraphImpl: ((StatsGraph, Int64) -> Signal<StatsGraph?, NoError>)?
var openStoryImpl: ((EngineStoryItem, UIView) -> Void)? var openStoryImpl: ((EnginePeer.Id, EngineStoryItem, UIView) -> Void)?
var forwardsContext: StoryStatsPublicForwardsContext? var forwardsContext: StoryStatsPublicForwardsContext?
let peerId: EnginePeer.Id let peerId: EnginePeer.Id
@ -363,6 +371,8 @@ public func messageStatsController(context: AccountContext, updatedPresentationD
return loadDetailedGraphImpl?(graph, x) ?? .single(nil) return loadDetailedGraphImpl?(graph, x) ?? .single(nil)
}, openMessage: { messageId in }, openMessage: { messageId in
navigateToMessageImpl?(messageId) navigateToMessageImpl?(messageId)
}, openStory: { peerId, story, view in
openStoryImpl?(peerId, story, view)
}) })
let longLoadingSignal: Signal<Bool, NoError> = .single(false) |> then(.single(true) |> delay(2.0, queue: Queue.mainQueue())) let longLoadingSignal: Signal<Bool, NoError> = .single(false) |> then(.single(true) |> delay(2.0, queue: Queue.mainQueue()))
@ -422,7 +432,7 @@ public func messageStatsController(context: AccountContext, updatedPresentationD
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: nil, rightNavigationButton: iconNode.flatMap { ItemListNavigationButton(content: .node($0), style: .regular, enabled: true, action: { [weak iconNode] in let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: nil, rightNavigationButton: iconNode.flatMap { ItemListNavigationButton(content: .node($0), style: .regular, enabled: true, action: { [weak iconNode] in
if let iconNode, let storyItem { if let iconNode, let storyItem {
openStoryImpl?(storyItem, iconNode.view) openStoryImpl?(peerId, storyItem, iconNode.view)
} }
}) }, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) }) }, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: messageStatsControllerEntries(data: data, storyViews: storyViews, messages: search?.0, forwards: forwards, presentationData: presentationData), style: .blocks, emptyStateItem: emptyStateItem, crossfadeState: previous == nil, animateChanges: false) let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: messageStatsControllerEntries(data: data, storyViews: storyViews, messages: search?.0, forwards: forwards, presentationData: presentationData), style: .blocks, emptyStateItem: emptyStateItem, crossfadeState: previous == nil, animateChanges: false)
@ -464,7 +474,7 @@ public func messageStatsController(context: AccountContext, updatedPresentationD
} }
}) })
} }
openStoryImpl = { [weak controller] story, sourceView in openStoryImpl = { [weak controller] peerId, story, sourceView in
let storyContent = SingleStoryContentContextImpl(context: context, storyId: StoryId(peerId: peerId, id: story.id), storyItem: story, readGlobally: false) let storyContent = SingleStoryContentContextImpl(context: context, storyId: StoryId(peerId: peerId, id: story.id), storyItem: story, readGlobally: false)
let _ = (storyContent.state let _ = (storyContent.state
|> take(1) |> take(1)

View File

@ -13,6 +13,7 @@ import ItemListUI
import PresentationDataUtils import PresentationDataUtils
import PhotoResources import PhotoResources
import AvatarStoryIndicatorComponent import AvatarStoryIndicatorComponent
import AvatarNode
public class StatsMessageItem: ListViewItem, ItemListItem { public class StatsMessageItem: ListViewItem, ItemListItem {
let context: AccountContext let context: AccountContext
@ -82,7 +83,6 @@ public class StatsMessageItem: ListViewItem, ItemListItem {
public func selected(listView: ListView){ public func selected(listView: ListView){
listView.clearHighlightAnimated(true) listView.clearHighlightAnimated(true)
self.action?()
} }
} }
@ -105,6 +105,7 @@ final class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
private var extractedRect: CGRect? private var extractedRect: CGRect?
private var nonExtractedRect: CGRect? private var nonExtractedRect: CGRect?
var avatarNode: AvatarNode?
let contentImageNode: TransformImageNode let contentImageNode: TransformImageNode
var storyIndicator: ComponentView<Empty>? var storyIndicator: ComponentView<Empty>?
var storyButton: HighlightTrackingButton? var storyButton: HighlightTrackingButton?
@ -245,11 +246,30 @@ final class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
return result return result
} }
override func selected() {
guard let item = self.item else {
return
}
if item.isPeer {
if case .story = item.item {
self.storyPressed()
} else {
item.action?()
}
} else {
item.action?()
}
}
@objc private func storyPressed() { @objc private func storyPressed() {
guard let item = self.item else { guard let item = self.item else {
return return
} }
item.openStory(self.contentImageNode.view) if let avatarNode = self.avatarNode {
item.openStory(avatarNode.view)
} else {
item.openStory(self.contentImageNode.view)
}
} }
public func asyncLayout() -> (_ item: StatsMessageItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { public func asyncLayout() -> (_ item: StatsMessageItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
@ -316,7 +336,7 @@ final class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
} }
} }
timestamp = message.timestamp timestamp = message.timestamp
case let .story(story): case let .story(_, story):
text = item.presentationData.strings.Message_Story text = item.presentationData.strings.Message_Story
timestamp = story.timestamp timestamp = story.timestamp
if let image = story.media._asMedia() as? TelegramMediaImage { if let image = story.media._asMedia() as? TelegramMediaImage {
@ -349,7 +369,7 @@ final class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
} else if let file = contentImageMedia as? TelegramMediaFile { } else if let file = contentImageMedia as? TelegramMediaFile {
updateImageSignal = mediaGridMessageVideo(postbox: item.context.account.postbox, userLocation: .peer(message.id.peerId), videoReference: .message(message: MessageReference(message), media: file), autoFetchFullSizeThumbnail: true) updateImageSignal = mediaGridMessageVideo(postbox: item.context.account.postbox, userLocation: .peer(message.id.peerId), videoReference: .message(message: MessageReference(message), media: file), autoFetchFullSizeThumbnail: true)
} }
case let .story(story): case let .story(_, story):
if let peerReference = PeerReference(item.peer) { if let peerReference = PeerReference(item.peer) {
if let image = contentImageMedia as? TelegramMediaImage { if let image = contentImageMedia as? TelegramMediaImage {
updateImageSignal = mediaGridMessagePhoto(account: item.context.account, userLocation: .peer(item.peer.id), photoReference: .story(peer: peerReference, id: story.id, media: image)) updateImageSignal = mediaGridMessagePhoto(account: item.context.account, userLocation: .peer(item.peer.id), photoReference: .story(peer: peerReference, id: story.id, media: image))
@ -435,15 +455,36 @@ final class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor
} }
var dimensions: CGSize?
if let contentImageMedia = contentImageMedia as? TelegramMediaImage {
dimensions = largestRepresentationForPhoto(contentImageMedia)?.dimensions.cgSize
} else if let contentImageMedia = contentImageMedia as? TelegramMediaFile {
dimensions = contentImageMedia.dimensions?.cgSize
}
var contentImageSize = CGSize(width: 40.0, height: 40.0) var contentImageSize = CGSize(width: 40.0, height: 40.0)
var contentImageInset = leftInset - 6.0 var contentImageInset = leftInset - 6.0
var dimensions: CGSize?
if item.isPeer {
let avatarNode: AvatarNode
if let current = strongSelf.avatarNode {
avatarNode = current
} else {
avatarNode = AvatarNode(font: avatarPlaceholderFont(size: floor(40.0 * 16.0 / 37.0)))
strongSelf.offsetContainerNode.addSubnode(avatarNode)
strongSelf.avatarNode = avatarNode
}
avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: EnginePeer(item.peer))
if case .story = item.item {
contentImageInset += 3.0
contentImageSize = CGSize(width: 34.0, height: 34.0)
}
} else {
strongSelf.avatarNode?.removeFromSupernode()
strongSelf.avatarNode = nil
if let contentImageMedia = contentImageMedia as? TelegramMediaImage {
dimensions = largestRepresentationForPhoto(contentImageMedia)?.dimensions.cgSize
} else if let contentImageMedia = contentImageMedia as? TelegramMediaFile {
dimensions = contentImageMedia.dimensions?.cgSize
}
}
if let dimensions = dimensions { if let dimensions = dimensions {
let makeImageLayout = strongSelf.contentImageNode.asyncLayout() let makeImageLayout = strongSelf.contentImageNode.asyncLayout()
@ -540,6 +581,10 @@ final class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
let contentImageFrame = CGRect(origin: CGPoint(x: contentImageInset, y: floorToScreenPixels((height - contentImageSize.height) / 2.0)), size: contentImageSize) let contentImageFrame = CGRect(origin: CGPoint(x: contentImageInset, y: floorToScreenPixels((height - contentImageSize.height) / 2.0)), size: contentImageSize)
strongSelf.contentImageNode.frame = contentImageFrame strongSelf.contentImageNode.frame = contentImageFrame
if let avatarNode = strongSelf.avatarNode {
avatarNode.frame = contentImageFrame
}
let titleFrame = CGRect(origin: CGPoint(x: totalLeftInset, y: 9.0), size: titleLayout.size) let titleFrame = CGRect(origin: CGPoint(x: totalLeftInset, y: 9.0), size: titleLayout.size)
strongSelf.titleNode.frame = titleFrame strongSelf.titleNode.frame = titleFrame

View File

@ -281,7 +281,8 @@ private final class StoryStatsPublicForwardsContextImpl {
resultForwards.append(.message(EngineMessage(renderedMessage))) resultForwards.append(.message(EngineMessage(renderedMessage)))
} }
case let .publicForwardStory(apiPeer, apiStory): case let .publicForwardStory(apiPeer, apiStory):
if let storedItem = Stories.StoredItem(apiStoryItem: apiStory, peerId: apiPeer.peerId, transaction: transaction), case let .item(item) = storedItem, let media = item.media {
if let storedItem = Stories.StoredItem(apiStoryItem: apiStory, peerId: apiPeer.peerId, transaction: transaction), case let .item(item) = storedItem, let media = item.media, let peer = peers[apiPeer.peerId] {
let mappedItem = EngineStoryItem( let mappedItem = EngineStoryItem(
id: item.id, id: item.id,
timestamp: item.timestamp, timestamp: item.timestamp,
@ -316,7 +317,7 @@ private final class StoryStatsPublicForwardsContextImpl {
myReaction: item.myReaction, myReaction: item.myReaction,
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) } forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) }
) )
resultForwards.append(.story(mappedItem)) resultForwards.append(.story(EnginePeer(peer), mappedItem))
} }
} }
} }
@ -359,7 +360,7 @@ public final class StoryStatsPublicForwardsContext {
public struct State: Equatable { public struct State: Equatable {
public enum Forward: Equatable { public enum Forward: Equatable {
case message(EngineMessage) case message(EngineMessage)
case story(EngineStoryItem) case story(EnginePeer, EngineStoryItem)
} }
public var forwards: [Forward] public var forwards: [Forward]
public var isLoadingMore: Bool public var isLoadingMore: Bool

View File

@ -116,7 +116,9 @@ final class StoryAuthorInfoComponent: Component {
let timeString = stringForStoryActivityTimestamp(strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, preciseTime: true, relativeTimestamp: component.timestamp, relativeTo: timestamp, short: true) let timeString = stringForStoryActivityTimestamp(strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, preciseTime: true, relativeTimestamp: component.timestamp, relativeTo: timestamp, short: true)
let combinedString = NSMutableAttributedString() let combinedString = NSMutableAttributedString()
combinedString.append(NSAttributedString(string: authorName, font: Font.medium(11.0), textColor: titleColor)) combinedString.append(NSAttributedString(string: authorName, font: Font.medium(11.0), textColor: titleColor))
combinedString.append(NSAttributedString(string: "\(timeString)", font: Font.regular(11.0), textColor: subtitleColor)) if timeString.count < 6 {
combinedString.append(NSAttributedString(string: "\(timeString)", font: Font.regular(11.0), textColor: subtitleColor))
}
subtitle = combinedString subtitle = combinedString
subtitleTruncationType = .middle subtitleTruncationType = .middle
} else { } else {