Various improvements

This commit is contained in:
Ilya Laktyushin 2022-04-15 19:48:29 +04:00
parent 92d53e6ca6
commit 6e4b9a82e9
11 changed files with 132 additions and 33 deletions

View File

@ -125,7 +125,7 @@ class InviteLinkHeaderItemNode: ListViewItemNode {
strongSelf.item = item
strongSelf.accessibilityLabel = attributedText.string
let iconSize = CGSize(width: 96.0, height: 96.0)
let iconSize = CGSize(width: 128.0, height: 128.0)
strongSelf.animationNode.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: -10.0), size: iconSize)
strongSelf.animationNode.updateLayout(size: iconSize)

View File

@ -83,6 +83,7 @@ private final class ItemListRevealOptionNode: ASDisplayNode {
private let iconNode: ASImageNode?
private let animationNode: SimpleAnimationNode?
private var animationScale: CGFloat = 1.0
private var animationNodeOffset: CGFloat = 0.0
private var animationNodeFlip = false
var alignment: ItemListRevealOptionAlignment?
@ -102,7 +103,8 @@ private final class ItemListRevealOptionNode: ASDisplayNode {
self.iconNode = iconNode
self.animationNode = nil
case let .animation(animation, _, offset, replaceColors, flip):
case let .animation(animation, scale, offset, replaceColors, flip):
self.animationScale = scale
self.iconNode = nil
var colors: [UInt32: UInt32] = [:]
if let replaceColors = replaceColors {
@ -194,7 +196,7 @@ private final class ItemListRevealOptionNode: ASDisplayNode {
}
if let animationNode = self.animationNode {
let imageSize = animationNode.size
let imageSize = CGSize(width: animationNode.size.width * self.animationScale, height: animationNode.size.height * self.animationScale)
let iconOffset: CGFloat = -2.0 + self.animationNodeOffset
let titleIconSpacing: CGFloat = 11.0
let iconFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - imageSize.width + sideInset) / 2.0), y: contentRect.midY - imageSize.height / 2.0 + iconOffset), size: imageSize)

View File

@ -455,6 +455,7 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry {
case let .joinToSendEveryone(_, text, selected):
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
arguments.updateJoinToSend(.everyone)
arguments.toggleApproveMembers(false)
})
case let .joinToSendMembers(_, text, selected):
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
@ -816,13 +817,24 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa
entries.append(.privateLinkManageInfo(presentationData.theme, presentationData.strings.InviteLink_CreateInfo))
}
}
if isGroup {
var isDiscussion = false
if let cachedData = view.cachedData as? CachedChannelData, case .known = cachedData.linkedDiscussionPeerId {
isDiscussion = true
}
if isDiscussion {
entries.append(.joinToSendHeader(presentationData.theme, presentationData.strings.Group_Setup_WhoCanSendMessages_Title.uppercased()))
entries.append(.joinToSendEveryone(presentationData.theme, presentationData.strings.Group_Setup_WhoCanSendMessages_Everyone, joinToSend == .everyone))
entries.append(.joinToSendMembers(presentationData.theme, presentationData.strings.Group_Setup_WhoCanSendMessages_OnlyMembers, joinToSend == .members))
}
entries.append(.joinToSendHeader(presentationData.theme, presentationData.strings.Group_Setup_WhoCanSendMessages_Title.uppercased()))
entries.append(.joinToSendEveryone(presentationData.theme, presentationData.strings.Group_Setup_WhoCanSendMessages_Everyone, joinToSend == .everyone))
entries.append(.joinToSendMembers(presentationData.theme, presentationData.strings.Group_Setup_WhoCanSendMessages_OnlyMembers, joinToSend == .members))
entries.append(.approveMembers(presentationData.theme, presentationData.strings.Group_Setup_ApproveNewMembers, approveMembers))
entries.append(.approveMembersInfo(presentationData.theme, presentationData.strings.Group_Setup_ApproveNewMembersInfo))
if !isDiscussion || joinToSend == .members {
entries.append(.approveMembers(presentationData.theme, presentationData.strings.Group_Setup_ApproveNewMembers, approveMembers))
entries.append(.approveMembersInfo(presentationData.theme, presentationData.strings.Group_Setup_ApproveNewMembersInfo))
}
}
entries.append(.forwardingHeader(presentationData.theme, isGroup ? presentationData.strings.Group_Setup_ForwardingGroupTitle.uppercased() : presentationData.strings.Group_Setup_ForwardingChannelTitle.uppercased()))
entries.append(.forwardingDisabled(presentationData.theme, presentationData.strings.Group_Setup_ForwardingDisabled, !forwardingEnabled))
@ -1074,6 +1086,12 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
let toggleCopyProtectionDisposable = MetaDisposable()
actionsDisposable.add(toggleCopyProtectionDisposable)
let toggleJoinToSendDisposable = MetaDisposable()
actionsDisposable.add(toggleJoinToSendDisposable)
let toggleRequestToJoinDisposable = MetaDisposable()
actionsDisposable.add(toggleRequestToJoinDisposable)
let arguments = ChannelVisibilityControllerArguments(context: context, updateCurrentType: { type in
updateState { state in
return state.withUpdatedSelectedType(type)
@ -1358,11 +1376,11 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
}
if let updatedJoinToSend = state.joinToSend {
toggleCopyProtectionDisposable.set(context.engine.peers.toggleChannelJoinToSend(peerId: peerId, enabled: updatedJoinToSend == .members).start())
toggleJoinToSendDisposable.set(context.engine.peers.toggleChannelJoinToSend(peerId: peerId, enabled: updatedJoinToSend == .members).start())
}
if let updatedApproveMembers = state.approveMembers {
toggleCopyProtectionDisposable.set(context.engine.peers.toggleChannelJoinRequest(peerId: peerId, enabled: updatedApproveMembers).start())
toggleRequestToJoinDisposable.set(context.engine.peers.toggleChannelJoinRequest(peerId: peerId, enabled: updatedApproveMembers).start())
}
if let updatedAddressNameValue = updatedAddressNameValue {

View File

@ -16,7 +16,8 @@ extension BotMenuButton {
extension BotInfo {
convenience init(apiBotInfo: Api.BotInfo) {
switch apiBotInfo {
case let .botInfo(_, _, description, _, apiCommands, apiMenuButton):
case let .botInfo(_, _, description, descriptionPhoto, apiCommands, apiMenuButton):
let photo: TelegramMediaImage? = descriptionPhoto.flatMap(telegramMediaImageFromApiPhoto)
var commands: [BotCommand] = []
if let apiCommands = apiCommands {
commands = apiCommands.map { command in
@ -30,7 +31,7 @@ extension BotInfo {
if let apiMenuButton = apiMenuButton {
menuButton = BotMenuButton(apiBotMenuButton: apiMenuButton)
}
self.init(description: description ?? "", commands: commands, menuButton: menuButton)
self.init(description: description ?? "", photo: photo, commands: commands, menuButton: menuButton)
}
}
}

View File

@ -1467,14 +1467,14 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
updatedState.updateCachedPeerData(peer.peerId, { current in
if peer.peerId.namespace == Namespaces.Peer.CloudUser, let previous = current as? CachedUserData {
if let botInfo = previous.botInfo {
return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, commands: commands, menuButton: botInfo.menuButton))
return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, photo: botInfo.photo, commands: commands, menuButton: botInfo.menuButton))
}
} else if peer.peerId.namespace == Namespaces.Peer.CloudGroup, let previous = current as? CachedGroupData {
if let index = previous.botInfos.firstIndex(where: { $0.peerId == botPeerId }) {
var updatedBotInfos = previous.botInfos
let previousBotInfo = updatedBotInfos[index]
updatedBotInfos.remove(at: index)
updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, commands: commands, menuButton: previousBotInfo.botInfo.menuButton)), at: index)
updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, photo: previousBotInfo.botInfo.photo, commands: commands, menuButton: previousBotInfo.botInfo.menuButton)), at: index)
return previous.withUpdatedBotInfos(updatedBotInfos)
}
} else if peer.peerId.namespace == Namespaces.Peer.CloudChannel, let previous = current as? CachedChannelData {
@ -1482,7 +1482,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
var updatedBotInfos = previous.botInfos
let previousBotInfo = updatedBotInfos[index]
updatedBotInfos.remove(at: index)
updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, commands: commands, menuButton: previousBotInfo.botInfo.menuButton)), at: index)
updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, photo: previousBotInfo.botInfo.photo, commands: commands, menuButton: previousBotInfo.botInfo.menuButton)), at: index)
return previous.withUpdatedBotInfos(updatedBotInfos)
}
}
@ -1494,7 +1494,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
updatedState.updateCachedPeerData(botPeerId, { current in
if let previous = current as? CachedUserData {
if let botInfo = previous.botInfo {
return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, commands: botInfo.commands, menuButton: menuButton))
return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, photo: botInfo.photo, commands: botInfo.commands, menuButton: menuButton))
}
}
return current

View File

@ -47,23 +47,35 @@ public enum BotMenuButton: PostboxCoding, Hashable {
public final class BotInfo: PostboxCoding, Equatable {
public let description: String
public let photo: TelegramMediaImage?
public let commands: [BotCommand]
public let menuButton: BotMenuButton
public init(description: String, commands: [BotCommand], menuButton: BotMenuButton) {
public init(description: String, photo: TelegramMediaImage?, commands: [BotCommand], menuButton: BotMenuButton) {
self.description = description
self.photo = photo
self.commands = commands
self.menuButton = menuButton
}
public init(decoder: PostboxDecoder) {
self.description = decoder.decodeStringForKey("d", orElse: "")
if let photo = decoder.decodeObjectForKey("ph", decoder: { TelegramMediaImage(decoder: $0) }) as? TelegramMediaImage {
self.photo = photo
} else {
self.photo = nil
}
self.commands = decoder.decodeObjectArrayWithDecoderForKey("c")
self.menuButton = (decoder.decodeObjectForKey("b", decoder: { BotMenuButton(decoder: $0) }) as? BotMenuButton) ?? .commands
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeString(self.description, forKey: "d")
if let photo = self.photo {
encoder.encodeObject(photo, forKey: "ph")
} else {
encoder.encodeNil(forKey: "ph")
}
encoder.encodeObjectArray(self.commands, forKey: "c")
encoder.encodeObject(self.menuButton, forKey: "b")
}

View File

@ -8,6 +8,8 @@ import TelegramCore
import TelegramPresentationData
import TextFormat
import UrlEscaping
import PhotoResources
import AccountContext
private let messageFont = Font.regular(17.0)
private let messageBoldFont = Font.semibold(17.0)
@ -18,14 +20,18 @@ private let messageFixedFont = UIFont(name: "Menlo-Regular", size: 16.0) ?? UIFo
final class ChatBotInfoItem: ListViewItem {
fileprivate let title: String
fileprivate let text: String
fileprivate let photo: TelegramMediaImage?
fileprivate let controllerInteraction: ChatControllerInteraction
fileprivate let presentationData: ChatPresentationData
fileprivate let context: AccountContext
init(title: String, text: String, controllerInteraction: ChatControllerInteraction, presentationData: ChatPresentationData) {
init(title: String, text: String, photo: TelegramMediaImage?, controllerInteraction: ChatControllerInteraction, presentationData: ChatPresentationData, context: AccountContext) {
self.title = title
self.text = text
self.photo = photo
self.controllerInteraction = controllerInteraction
self.presentationData = presentationData
self.context = context
}
func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
@ -76,10 +82,13 @@ final class ChatBotInfoItemNode: ListViewItemNode {
let offsetContainer: ASDisplayNode
let backgroundNode: ASImageNode
let imageNode: TransformImageNode
let titleNode: TextNode
let textNode: TextNode
private var linkHighlightingNode: LinkHighlightingNode?
private let fetchDisposable = MetaDisposable()
var currentTextAndEntities: (String, [MessageTextEntity])?
private var theme: ChatPresentationThemeData?
@ -92,6 +101,7 @@ final class ChatBotInfoItemNode: ListViewItemNode {
self.backgroundNode = ASImageNode()
self.backgroundNode.displaysAsynchronously = false
self.backgroundNode.displayWithoutProcessing = true
self.imageNode = TransformImageNode()
self.textNode = TextNode()
self.titleNode = TextNode()
@ -101,11 +111,16 @@ final class ChatBotInfoItemNode: ListViewItemNode {
self.addSubnode(self.offsetContainer)
self.offsetContainer.addSubnode(self.backgroundNode)
self.offsetContainer.addSubnode(self.imageNode)
self.offsetContainer.addSubnode(self.titleNode)
self.offsetContainer.addSubnode(self.textNode)
self.wantsTrailingItemSpaceUpdates = true
}
deinit {
self.fetchDisposable.dispose()
}
override func didLoad() {
super.didLoad()
@ -134,10 +149,14 @@ final class ChatBotInfoItemNode: ListViewItemNode {
}
func asyncLayout() -> (_ item: ChatBotInfoItem, _ width: ListViewItemLayoutParams) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation) -> Void) {
let makeImageLayout = self.imageNode.asyncLayout()
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
let makeTextLayout = TextNode.asyncLayout(self.textNode)
let currentTextAndEntities = self.currentTextAndEntities
let currentTheme = self.theme
let currentItem = self.item
return { [weak self] item, params in
self?.item = item
@ -145,7 +164,7 @@ final class ChatBotInfoItemNode: ListViewItemNode {
if currentTheme != item.presentationData.theme {
updatedBackgroundImage = PresentationResourcesChat.chatInfoItemBackgroundImage(item.presentationData.theme.theme, wallpaper: !item.presentationData.theme.wallpaper.isEmpty)
}
var updatedTextAndEntities: (String, [MessageTextEntity])
if let (text, entities) = currentTextAndEntities {
if text == item.text {
@ -171,11 +190,40 @@ final class ChatBotInfoItemNode: ListViewItemNode {
let textSpacing: CGFloat = 1.0
let textSize = CGSize(width: max(titleLayout.size.width, textLayout.size.width), height: (titleLayout.size.height + (titleLayout.size.width.isZero ? 0.0 : textSpacing) + textLayout.size.height))
let backgroundFrame = CGRect(origin: CGPoint(x: floor((params.width - textSize.width - horizontalContentInset * 2.0) / 2.0), y: verticalItemInset + 4.0), size: CGSize(width: textSize.width + horizontalContentInset * 2.0, height: textSize.height + verticalContentInset * 2.0))
let titleFrame = CGRect(origin: CGPoint(x: backgroundFrame.origin.x + horizontalContentInset, y: backgroundFrame.origin.y + verticalContentInset), size: titleLayout.size)
let textFrame = CGRect(origin: CGPoint(x: backgroundFrame.origin.x + horizontalContentInset, y: backgroundFrame.origin.y + verticalContentInset + titleLayout.size.height + (titleLayout.size.width.isZero ? 0.0 : textSpacing)), size: textLayout.size)
var mediaUpdated = false
if let media = item.photo {
if let currentMedia = currentItem?.photo {
mediaUpdated = !media.isSemanticallyEqual(to: currentMedia)
} else {
mediaUpdated = true
}
}
let itemLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: textLayout.size.height + verticalItemInset * 2.0 + verticalContentInset * 2.0 + titleLayout.size.height + (titleLayout.size.width.isZero ? 0.0 : textSpacing) - 3.0), insets: UIEdgeInsets())
var updatedImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>?
var imageSize = CGSize()
var imageDimensions = CGSize()
var imageApply: (() -> Void)?
let imageInset: CGFloat = 1.0 + UIScreenPixel
if let image = item.photo, let dimensions = largestImageRepresentation(image.representations)?.dimensions {
imageDimensions = dimensions.cgSize.aspectFitted(CGSize(width: textSize.width + horizontalContentInset * 2.0 - imageInset * 2.0, height: CGFloat.greatestFiniteMagnitude))
imageSize = imageDimensions
imageSize.height += 4.0
let arguments = TransformImageArguments(corners: ImageCorners(topLeft: .Corner(17.0), topRight: .Corner(17.0), bottomLeft: .Corner(0.0), bottomRight: .Corner(0.0)), imageSize: dimensions.cgSize.aspectFilled(imageDimensions), boundingSize: imageDimensions, intrinsicInsets: UIEdgeInsets(), emptyColor: item.presentationData.theme.theme.list.mediaPlaceholderColor)
imageApply = makeImageLayout(arguments)
if mediaUpdated {
updatedImageSignal = chatMessagePhoto(postbox: item.context.account.postbox, photoReference: .standalone(media: image), synchronousLoad: true, highQuality: false)
}
}
let backgroundFrame = CGRect(origin: CGPoint(x: floor((params.width - textSize.width - horizontalContentInset * 2.0) / 2.0), y: verticalItemInset + 4.0), size: CGSize(width: textSize.width + horizontalContentInset * 2.0, height: imageSize.height + textSize.height + verticalContentInset * 2.0))
let titleFrame = CGRect(origin: CGPoint(x: backgroundFrame.origin.x + horizontalContentInset, y: backgroundFrame.origin.y + imageSize.height + verticalContentInset), size: titleLayout.size)
let textFrame = CGRect(origin: CGPoint(x: backgroundFrame.origin.x + horizontalContentInset, y: backgroundFrame.origin.y + imageSize.height + verticalContentInset + titleLayout.size.height + (titleLayout.size.width.isZero ? 0.0 : textSpacing)), size: textLayout.size)
let imageFrame = CGRect(origin: CGPoint(x: backgroundFrame.origin.x + imageInset, y: backgroundFrame.origin.y + imageInset), size: imageDimensions)
let itemLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: imageSize.height + textLayout.size.height + verticalItemInset * 2.0 + verticalContentInset * 2.0 + titleLayout.size.height + (titleLayout.size.width.isZero ? 0.0 : textSpacing) - 3.0), insets: UIEdgeInsets())
return (itemLayout, { _ in
if let strongSelf = self {
strongSelf.theme = item.presentationData.theme
@ -186,6 +234,22 @@ final class ChatBotInfoItemNode: ListViewItemNode {
strongSelf.controllerInteraction = item.controllerInteraction
strongSelf.currentTextAndEntities = updatedTextAndEntities
if let imageApply = imageApply {
let _ = imageApply()
if let updatedImageSignal = updatedImageSignal {
strongSelf.imageNode.setSignal(updatedImageSignal)
if let image = item.photo {
strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(context: item.context, photoReference: .standalone(media: image), displayAtSize: nil, storeToDownloadsPeerType: nil).start())
}
}
strongSelf.imageNode.isHidden = false
} else {
strongSelf.imageNode.isHidden = true
}
strongSelf.imageNode.frame = imageFrame
let _ = titleApply()
let _ = textApply()
strongSelf.offsetContainer.frame = CGRect(origin: CGPoint(), size: itemLayout.contentSize)

View File

@ -255,9 +255,9 @@ func chatHistoryEntriesForView(
}
}
if case let .peer(peerId) = location, peerId.isReplies {
entries.insert(.ChatInfoEntry("", presentationData.strings.RepliesChat_DescriptionText, presentationData), at: 0)
entries.insert(.ChatInfoEntry("", presentationData.strings.RepliesChat_DescriptionText, nil, presentationData), at: 0)
} else if let cachedPeerData = cachedPeerData as? CachedUserData, let botInfo = cachedPeerData.botInfo, !botInfo.description.isEmpty {
entries.insert(.ChatInfoEntry(presentationData.strings.Bot_DescriptionTitle, botInfo.description, presentationData), at: 0)
entries.insert(.ChatInfoEntry(presentationData.strings.Bot_DescriptionTitle, botInfo.description, botInfo.photo, presentationData), at: 0)
} else {
var isEmpty = true
if entries.count <= 3 {

View File

@ -43,7 +43,7 @@ enum ChatHistoryEntry: Identifiable, Comparable {
case MessageGroupEntry(MessageGroupInfo, [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes, MessageHistoryEntryLocation?)], ChatPresentationData)
case UnreadEntry(MessageIndex, ChatPresentationData)
case ReplyCountEntry(MessageIndex, Bool, Int, ChatPresentationData)
case ChatInfoEntry(String, String, ChatPresentationData)
case ChatInfoEntry(String, String, TelegramMediaImage?, ChatPresentationData)
case SearchEntry(PresentationTheme, PresentationStrings)
var stableId: UInt64 {
@ -201,8 +201,8 @@ enum ChatHistoryEntry: Identifiable, Comparable {
} else {
return false
}
case let .ChatInfoEntry(lhsTitle, lhsText, lhsPresentationData):
if case let .ChatInfoEntry(rhsTitle, rhsText, rhsPresentationData) = rhs, lhsTitle == rhsTitle, lhsText == rhsText, lhsPresentationData === rhsPresentationData {
case let .ChatInfoEntry(lhsTitle, lhsText, lhsPhoto, lhsPresentationData):
if case let .ChatInfoEntry(rhsTitle, rhsText, rhsPhoto, rhsPresentationData) = rhs, lhsTitle == rhsTitle, lhsText == rhsText, lhsPhoto == rhsPhoto, lhsPresentationData === rhsPresentationData {
return true
} else {
return false

View File

@ -247,8 +247,8 @@ private func mappedInsertEntries(context: AccountContext, chatLocation: ChatLoca
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatUnreadItem(index: entry.entry.index, presentationData: presentationData, context: context), directionHint: entry.directionHint)
case let .ReplyCountEntry(_, isComments, count, presentationData):
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatReplyCountItem(index: entry.entry.index, isComments: isComments, count: count, presentationData: presentationData, context: context, controllerInteraction: controllerInteraction), directionHint: entry.directionHint)
case let .ChatInfoEntry(title, text, presentationData):
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatBotInfoItem(title: title, text: text, controllerInteraction: controllerInteraction, presentationData: presentationData), directionHint: entry.directionHint)
case let .ChatInfoEntry(title, text, photo, presentationData):
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatBotInfoItem(title: title, text: text, photo: photo, controllerInteraction: controllerInteraction, presentationData: presentationData, context: context), directionHint: entry.directionHint)
case let .SearchEntry(theme, strings):
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListSearchItem(theme: theme, placeholder: strings.Common_Search, activate: {
controllerInteraction.openSearch()
@ -292,8 +292,8 @@ private func mappedUpdateEntries(context: AccountContext, chatLocation: ChatLoca
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatUnreadItem(index: entry.entry.index, presentationData: presentationData, context: context), directionHint: entry.directionHint)
case let .ReplyCountEntry(_, isComments, count, presentationData):
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatReplyCountItem(index: entry.entry.index, isComments: isComments, count: count, presentationData: presentationData, context: context, controllerInteraction: controllerInteraction), directionHint: entry.directionHint)
case let .ChatInfoEntry(title, text, presentationData):
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatBotInfoItem(title: title, text: text, controllerInteraction: controllerInteraction, presentationData: presentationData), directionHint: entry.directionHint)
case let .ChatInfoEntry(title, text, photo, presentationData):
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatBotInfoItem(title: title, text: text, photo: photo, controllerInteraction: controllerInteraction, presentationData: presentationData, context: context), directionHint: entry.directionHint)
case let .SearchEntry(theme, strings):
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListSearchItem(theme: theme, placeholder: strings.Common_Search, activate: {
controllerInteraction.openSearch()

View File

@ -38,6 +38,8 @@ public enum WebEmbedType {
public func webEmbedType(content: TelegramMediaWebpageLoadedContent, forcedTimestamp: Int? = nil) -> WebEmbedType {
if let (videoId, timestamp) = extractYoutubeVideoIdAndTimestamp(url: content.url) {
return .youtube(videoId: videoId, timestamp: forcedTimestamp ?? timestamp)
} else if let embedUrl = content.embedUrl, let (videoId, timestamp) = extractYoutubeVideoIdAndTimestamp(url: embedUrl) {
return .youtube(videoId: videoId, timestamp: forcedTimestamp ?? timestamp)
} else if let (videoId, timestamp) = extractVimeoVideoIdAndTimestamp(url: content.url) {
return .vimeo(videoId: videoId, timestamp: forcedTimestamp ?? timestamp)
} else if let embedUrl = content.embedUrl, isTwitchVideoUrl(embedUrl) && false {