Various improvements

This commit is contained in:
Isaac 2024-03-27 19:54:56 +04:00
parent 0d4fd4f934
commit 9554305a33
10 changed files with 234 additions and 13 deletions

View File

@ -97,13 +97,15 @@ public enum ChatListItemContent {
public var messageCount: Int?
public var hideSeparator: Bool
public var hideDate: Bool
public var hidePeerStatus: Bool
public init(commandPrefix: String?, searchQuery: String?, messageCount: Int?, hideSeparator: Bool, hideDate: Bool) {
public init(commandPrefix: String?, searchQuery: String?, messageCount: Int?, hideSeparator: Bool, hideDate: Bool, hidePeerStatus: Bool) {
self.commandPrefix = commandPrefix
self.searchQuery = searchQuery
self.messageCount = messageCount
self.hideSeparator = hideSeparator
self.hideDate = hideDate
self.hidePeerStatus = hidePeerStatus
}
}
@ -2340,7 +2342,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
attributedText = foldLineBreaks(draftText)
}
} else if let message = messages.first {
} else if let message = messages.last {
var composedString: NSMutableAttributedString
if let peerText = peerText {
@ -2942,7 +2944,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
break
}
} else if case let .chat(itemPeer) = contentPeer, let peer = itemPeer.chatMainPeer {
if case let .peer(peerData) = item.content, peerData.customMessageListData != nil {
if case let .peer(peerData) = item.content, peerData.customMessageListData?.hidePeerStatus == true {
currentCredibilityIconContent = nil
} else if case .savedMessagesChats = item.chatListLocation, peer.id == item.context.account.peerId {
currentCredibilityIconContent = nil

View File

@ -1243,7 +1243,7 @@ public func selectivePrivacySettingsController(
break
}
let controller = selectivePrivacyPeersController(context: context, title: title, initialPeers: peerIds, initialEnableForPremium: stateValue.with({ $0 }).enableForPremium, displayPremiumCategory: displayPremiumCategory, updated: { updatedPeerIds, enableForPremium in
let controller = selectivePrivacyPeersController(context: context, title: title, initialPeers: peerIds, initialEnableForPremium: displayPremiumCategory && stateValue.with({ $0 }).enableForPremium, displayPremiumCategory: displayPremiumCategory, updated: { updatedPeerIds, enableForPremium in
updateState { state in
if enable {
switch target {

View File

@ -180,7 +180,7 @@ public final class ChatEmptyNodeGreetingChatContent: ASDisplayNode, ChatEmptyNod
let previousCustomStickerFile = self.currentCustomStickerFile
self.currentCustomStickerFile = customStickerFile
let stickerSize: CGSize
var stickerSize: CGSize
let inset: CGFloat
if size.width == 320.0 {
stickerSize = CGSize(width: 106.0, height: 106.0)
@ -189,6 +189,11 @@ public final class ChatEmptyNodeGreetingChatContent: ASDisplayNode, ChatEmptyNod
stickerSize = CGSize(width: 160.0, height: 160.0)
inset = 15.0
}
if let customStickerFile, let dimensions = customStickerFile.dimensions?.cgSize {
stickerSize = dimensions.aspectFitted(stickerSize)
}
if let item = self.stickerItem, previousCustomStickerFile == customStickerFile {
self.stickerNode.updateLayout(item: item, size: stickerSize, isVisible: true, synchronousLoads: true)
} else if !self.didSetupSticker || previousCustomStickerFile != customStickerFile {

View File

@ -588,7 +588,8 @@ private final class PeerInfoScreenPersonalChannelItemNode: PeerInfoScreenItemNod
searchQuery: nil,
messageCount: nil,
hideSeparator: true,
hideDate: isLoading
hideDate: isLoading,
hidePeerStatus: false
)
)),
editing: false,

View File

@ -242,7 +242,8 @@ final class GreetingMessageListItemComponent: Component {
searchQuery: nil,
messageCount: component.count,
hideSeparator: true,
hideDate: true
hideDate: true,
hidePeerStatus: true
)
)),
editing: false,

View File

@ -272,7 +272,8 @@ final class QuickReplySetupScreenComponent: Component {
searchQuery: nil,
messageCount: item.totalCount,
hideSeparator: false,
hideDate: true
hideDate: true,
hidePeerStatus: true
)
)),
editing: isEditing,

View File

@ -294,7 +294,7 @@ final class BusinessIntroSetupScreenComponent: Component {
if !self.isUpdating {
self.state?.updated(transition: .immediate)
}
case let .text(rawQuery, _):
case let .text(rawQuery, languageCode):
let query = rawQuery.trimmingCharacters(in: .whitespacesAndNewlines)
if query.isEmpty {
@ -304,7 +304,7 @@ final class BusinessIntroSetupScreenComponent: Component {
} else {
let context = component.context
let localSets = context.engine.stickers.searchStickerSets(query: query)
/*let localSets = context.engine.stickers.searchStickerSets(query: query)
let remoteSets: Signal<FoundStickerSets?, NoError> = .single(nil) |> then(
context.engine.stickers.searchStickerSetsRemotely(query: query)
|> map(Optional.init)
@ -349,6 +349,199 @@ final class BusinessIntroSetupScreenComponent: Component {
items.append(item)
}
return .single([EmojiPagerContentComponent.ItemGroup(
supergroupId: "search",
groupId: "search",
title: nil,
subtitle: nil,
badge: nil,
actionButtonTitle: nil,
isFeatured: false,
isPremiumLocked: false,
isEmbedded: false,
hasClear: false,
hasEdit: false,
collapsedLineCount: nil,
displayPremiumBadges: false,
headerItem: nil,
fillWithLoadingPlaceholders: false,
items: items
)])
}*/
let stickers: Signal<[(String?, FoundStickerItem)], NoError> = Signal { subscriber in
var signals: Signal<[Signal<(String?, [FoundStickerItem]), NoError>], NoError> = .single([])
if query.isSingleEmoji {
signals = .single([context.engine.stickers.searchStickers(query: [query.basicEmoji.0])
|> map { (nil, $0.items) }])
} else if query.count > 1, !languageCode.isEmpty && languageCode != "emoji" {
var signal = context.engine.stickers.searchEmojiKeywords(inputLanguageCode: languageCode, query: query.lowercased(), completeMatch: query.count < 3)
if !languageCode.lowercased().hasPrefix("en") {
signal = signal
|> mapToSignal { keywords in
return .single(keywords)
|> then(
context.engine.stickers.searchEmojiKeywords(inputLanguageCode: "en-US", query: query.lowercased(), completeMatch: query.count < 3)
|> map { englishKeywords in
return keywords + englishKeywords
}
)
}
}
signals = signal
|> map { keywords -> [Signal<(String?, [FoundStickerItem]), NoError>] in
var signals: [Signal<(String?, [FoundStickerItem]), NoError>] = []
let emoticons = keywords.flatMap { $0.emoticons }
for emoji in emoticons {
signals.append(context.engine.stickers.searchStickers(query: [emoji.basicEmoji.0])
|> take(1)
|> map { (emoji, $0.items) })
}
return signals
}
}
return (signals
|> mapToSignal { signals in
return combineLatest(signals)
}).start(next: { results in
var result: [(String?, FoundStickerItem)] = []
for (emoji, stickers) in results {
for sticker in stickers {
result.append((emoji, sticker))
}
}
subscriber.putNext(result)
}, completed: {
subscriber.putCompletion()
})
}
let currentRemotePacks = Atomic<FoundStickerSets?>(value: nil)
let local = context.engine.stickers.searchStickerSets(query: query)
let remote = context.engine.stickers.searchStickerSetsRemotely(query: query)
|> delay(0.2, queue: Queue.mainQueue())
let rawPacks = local
|> mapToSignal { result -> Signal<(FoundStickerSets, Bool, FoundStickerSets?), NoError> in
var localResult = result
if let currentRemote = currentRemotePacks.with ({ $0 }) {
localResult = localResult.merge(with: currentRemote)
}
return .single((localResult, false, nil))
|> then(
remote
|> map { remote -> (FoundStickerSets, Bool, FoundStickerSets?) in
return (result.merge(with: remote), true, remote)
}
)
}
let installedPackIds = context.account.postbox.combinedView(keys: [.itemCollectionInfos(namespaces: [Namespaces.ItemCollection.CloudStickerPacks])])
|> map { view -> Set<ItemCollectionId> in
var installedPacks = Set<ItemCollectionId>()
if let stickerPacksView = view.views[.itemCollectionInfos(namespaces: [Namespaces.ItemCollection.CloudStickerPacks])] as? ItemCollectionInfosView {
if let packsEntries = stickerPacksView.entriesByNamespace[Namespaces.ItemCollection.CloudStickerPacks] {
for entry in packsEntries {
installedPacks.insert(entry.id)
}
}
}
return installedPacks
}
|> distinctUntilChanged
let packs = combineLatest(rawPacks, installedPackIds)
|> map { packs, installedPackIds -> (FoundStickerSets, Bool, FoundStickerSets?) in
var (localPacks, completed, remotePacks) = packs
for i in 0 ..< localPacks.infos.count {
let installed = installedPackIds.contains(localPacks.infos[i].0)
if installed != localPacks.infos[i].3 {
localPacks.infos[i].3 = installed
}
}
if remotePacks != nil {
for i in 0 ..< remotePacks!.infos.count {
let installed = installedPackIds.contains(remotePacks!.infos[i].0)
if installed != remotePacks!.infos[i].3 {
remotePacks!.infos[i].3 = installed
}
}
}
return (localPacks, completed, remotePacks)
}
let signal = combineLatest(stickers, packs)
|> map { stickers, packs -> ([(String?, FoundStickerItem)], FoundStickerSets, Bool, FoundStickerSets?)? in
return (stickers, packs.0, packs.1, packs.2)
}
let resultSignal: Signal<[EmojiPagerContentComponent.ItemGroup], NoError> = signal
|> mapToSignal { result in
guard let result else {
return .complete()
}
let (foundItems, localSets, complete, remoteSets) = result
var items: [EmojiPagerContentComponent.Item] = []
var existingIds = Set<MediaId>()
for (_, entry) in foundItems {
let itemFile = entry.file
if existingIds.contains(itemFile.fileId) {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile,
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
items.append(item)
}
var mergedSets = localSets
if let remoteSets {
mergedSets = mergedSets.merge(with: remoteSets)
}
for entry in mergedSets.entries {
guard let stickerPackItem = entry.item as? StickerPackItem else {
continue
}
let itemFile = stickerPackItem.file
if existingIds.contains(itemFile.fileId) {
continue
}
existingIds.insert(itemFile.fileId)
let animationData = EntityKeyboardAnimationData(file: itemFile)
let item = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile,
subgroupId: nil,
icon: .none,
tintMode: animationData.isTemplate ? .primary : .none
)
items.append(item)
}
if items.isEmpty && !complete {
return .complete()
}
return .single([EmojiPagerContentComponent.ItemGroup(
supergroupId: "search",
groupId: "search",
@ -825,7 +1018,7 @@ final class BusinessIntroSetupScreenComponent: Component {
var stickerSearchResults: EmojiPagerContentComponent.EmptySearchResults?
if !stickerSearchResult.groups.contains(where: { !$0.items.isEmpty || $0.fillWithLoadingPlaceholders }) {
stickerSearchResults = EmojiPagerContentComponent.EmptySearchResults(
text: environment.strings.EmojiSearch_SearchStickersEmptyResult,
text: "No stickers found",
iconFile: nil
)
}

View File

@ -8459,6 +8459,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
customChatContents.enqueueMessages(messages: messages)
strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory()
case let .businessLinkSetup(link):
if messages.count > 1 {
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: nil, text: "The message text limit is 4096 characters", actions: [
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})
]), in: .window(.root))
return
}
var text: String = ""
var entities: [MessageTextEntity] = []
if let message = messages.first {

View File

@ -3321,7 +3321,16 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
}
private func updateCounterTextNode(transition: ContainedViewLayoutTransition) {
if let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState, let editMessage = presentationInterfaceState.interfaceState.editMessage, let inputTextMaxLength = editMessage.inputTextMaxLength {
var inputTextMaxLength: Int32?
if let presentationInterfaceState = self.presentationInterfaceState {
if let editMessage = presentationInterfaceState.interfaceState.editMessage, let inputTextMaxLengthValue = editMessage.inputTextMaxLength {
inputTextMaxLength = inputTextMaxLengthValue
} else if case let .customChatContents(customChatContents) = presentationInterfaceState.subject, case .businessLinkSetup = customChatContents.kind {
inputTextMaxLength = 4096
}
}
if let presentationInterfaceState = self.presentationInterfaceState, let textInputNode = self.textInputNode, let inputTextMaxLength {
let textCount = Int32(textInputNode.textView.text.count)
let counterColor: UIColor = textCount > inputTextMaxLength ? presentationInterfaceState.theme.chat.inputPanel.panelControlDestructiveColor : presentationInterfaceState.theme.chat.inputPanel.panelControlColor

View File

@ -227,7 +227,8 @@ private struct CommandChatInputContextPanelEntry: Comparable, Identifiable {
searchQuery: command.searchQuery.flatMap { "/\($0)"},
messageCount: shortcut.totalCount,
hideSeparator: false,
hideDate: true
hideDate: true,
hidePeerStatus: true
)
)),
editing: false,