Various improvements

This commit is contained in:
Isaac 2024-04-19 17:16:12 +04:00
parent e938cecd37
commit e2a3decea3
10 changed files with 177 additions and 60 deletions

View File

@ -212,6 +212,8 @@ final class ComposePollScreenComponent: Component {
} }
} }
let usedCustomEmojiFiles: [Int64: TelegramMediaFile] = [:]
return ComposedPoll( return ComposedPoll(
publicity: self.isAnonymous ? .anonymous : .public, publicity: self.isAnonymous ? .anonymous : .public,
kind: mappedKind, kind: mappedKind,
@ -226,7 +228,8 @@ final class ComposePollScreenComponent: Component {
return TelegramMediaPollResults.Solution(text: mappedSolution, entities: []) return TelegramMediaPollResults.Solution(text: mappedSolution, entities: [])
} }
), ),
deadlineTimeout: nil deadlineTimeout: nil,
usedCustomEmojiFiles: usedCustomEmojiFiles
) )
} }

View File

@ -506,6 +506,7 @@ public final class ComposedPoll {
public let correctAnswers: [Data]? public let correctAnswers: [Data]?
public let results: TelegramMediaPollResults public let results: TelegramMediaPollResults
public let deadlineTimeout: Int32? public let deadlineTimeout: Int32?
public let usedCustomEmojiFiles: [Int64: TelegramMediaFile]
public init( public init(
publicity: TelegramMediaPollPublicity, publicity: TelegramMediaPollPublicity,
@ -514,7 +515,8 @@ public final class ComposedPoll {
options: [TelegramMediaPollOption], options: [TelegramMediaPollOption],
correctAnswers: [Data]?, correctAnswers: [Data]?,
results: TelegramMediaPollResults, results: TelegramMediaPollResults,
deadlineTimeout: Int32? deadlineTimeout: Int32?,
usedCustomEmojiFiles: [Int64: TelegramMediaFile]
) { ) {
self.publicity = publicity self.publicity = publicity
self.kind = kind self.kind = kind
@ -523,6 +525,7 @@ public final class ComposedPoll {
self.correctAnswers = correctAnswers self.correctAnswers = correctAnswers
self.results = results self.results = results
self.deadlineTimeout = deadlineTimeout self.deadlineTimeout = deadlineTimeout
self.usedCustomEmojiFiles = usedCustomEmojiFiles
} }
} }
@ -974,7 +977,8 @@ public func createPollController(context: AccountContext, updatedPresentationDat
options: options, options: options,
correctAnswers: correctAnswers, correctAnswers: correctAnswers,
results: TelegramMediaPollResults(voters: nil, totalVoters: nil, recentVoters: [], solution: resolvedSolution), results: TelegramMediaPollResults(voters: nil, totalVoters: nil, recentVoters: [], solution: resolvedSolution),
deadlineTimeout: deadlineTimeout deadlineTimeout: deadlineTimeout,
usedCustomEmojiFiles: [:]
)) ))
}) })

View File

@ -93,6 +93,8 @@ final class AccountTaskManager {
tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .emoji).start()) tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .emoji).start())
tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .status).start()) tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .status).start())
tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .avatar).start()) tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .avatar).start())
tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .chatStickers).start())
tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .greetingStickers).start())
tasks.add(managedSynchronizeAttachMenuBots(accountPeerId: self.accountPeerId, postbox: self.stateManager.postbox, network: self.stateManager.network, force: true).start()) tasks.add(managedSynchronizeAttachMenuBots(accountPeerId: self.accountPeerId, postbox: self.stateManager.postbox, network: self.stateManager.network, force: true).start())
tasks.add(managedSynchronizeNotificationSoundList(postbox: self.stateManager.postbox, network: self.stateManager.network).start()) tasks.add(managedSynchronizeNotificationSoundList(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedChatListFilters(postbox: self.stateManager.postbox, network: self.stateManager.network, accountPeerId: self.stateManager.accountPeerId).start()) tasks.add(managedChatListFilters(postbox: self.stateManager.postbox, network: self.stateManager.network, accountPeerId: self.stateManager.accountPeerId).start())

View File

@ -8,6 +8,8 @@ public final class EmojiSearchCategories: Equatable, Codable {
case emoji = 0 case emoji = 0
case status = 1 case status = 1
case avatar = 2 case avatar = 2
case chatStickers = 3
case greetingStickers = 4
} }
public struct Group: Codable, Equatable { public struct Group: Codable, Equatable {
@ -128,6 +130,12 @@ func managedSynchronizeEmojiSearchCategories(postbox: Postbox, network: Network,
|> `catch` { _ -> Signal<Api.messages.EmojiGroups, NoError> in |> `catch` { _ -> Signal<Api.messages.EmojiGroups, NoError> in
return .single(.emojiGroupsNotModified) return .single(.emojiGroupsNotModified)
} }
//TODO:localize
case .chatStickers, .greetingStickers:
signal = network.request(Api.functions.messages.getEmojiGroups(hash: current?.hash ?? 0))
|> `catch` { _ -> Signal<Api.messages.EmojiGroups, NoError> in
return .single(.emojiGroupsNotModified)
}
} }
return signal return signal

View File

@ -966,7 +966,7 @@ private final class AdminUserActionsSheetComponent: Component {
component: AnyComponent(PlainButtonComponent( component: AnyComponent(PlainButtonComponent(
content: AnyComponent(OptionsSectionFooterComponent( content: AnyComponent(OptionsSectionFooterComponent(
theme: environment.theme, theme: environment.theme,
text: self.isConfigurationExpanded ? partiallyRestrictTitle : fullyBanTitle, text: self.isConfigurationExpanded ? fullyBanTitle : partiallyRestrictTitle,
fontSize: presentationData.listsFontSize.itemListBaseHeaderFontSize, fontSize: presentationData.listsFontSize.itemListBaseHeaderFontSize,
isExpanded: self.isConfigurationExpanded isExpanded: self.isConfigurationExpanded
)), )),

View File

@ -1542,8 +1542,7 @@ public final class AvatarEditorScreen: ViewControllerComponentContainer {
hasTrending: false, hasTrending: false,
forceHasPremium: true, forceHasPremium: true,
searchIsPlaceholderOnly: false, searchIsPlaceholderOnly: false,
isProfilePhotoEmojiSelection: !isGroup, subject: isGroup ? .groupPhotoEmojiSelection : .profilePhotoEmojiSelection
isGroupPhotoEmojiSelection: isGroup
) )
let signal = combineLatest(queue: .mainQueue(), let signal = combineLatest(queue: .mainQueue(),

View File

@ -197,7 +197,20 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
let stickerItems: Signal<EmojiPagerContentComponent?, NoError> let stickerItems: Signal<EmojiPagerContentComponent?, NoError>
if hasStickers { if hasStickers {
stickerItems = EmojiPagerContentComponent.stickerInputData(context: context, animationCache: animationCache, animationRenderer: animationRenderer, stickerNamespaces: stickerNamespaces, stickerOrderedItemListCollectionIds: stickerOrderedItemListCollectionIds, chatPeerId: chatPeerId, hasSearch: hasSearch, hasTrending: hasTrending, forceHasPremium: false, hasEdit: hasEdit, hideBackground: hideBackground) stickerItems = EmojiPagerContentComponent.stickerInputData(
context: context,
animationCache: animationCache,
animationRenderer: animationRenderer,
stickerNamespaces: stickerNamespaces,
stickerOrderedItemListCollectionIds: stickerOrderedItemListCollectionIds,
chatPeerId: chatPeerId,
hasSearch: hasSearch,
hasTrending: hasTrending,
forceHasPremium: false,
hasEdit: hasEdit,
subject: .chatStickers,
hideBackground: hideBackground
)
|> map(Optional.init) |> map(Optional.init)
} else { } else {
stickerItems = .single(nil) stickerItems = .single(nil)

View File

@ -1589,6 +1589,13 @@ public extension EmojiPagerContentComponent {
return emojiItems return emojiItems
} }
enum StickersSubject {
case profilePhotoEmojiSelection
case groupPhotoEmojiSelection
case chatStickers
case greetingStickers
}
static func stickerInputData( static func stickerInputData(
context: AccountContext, context: AccountContext,
animationCache: AnimationCache, animationCache: AnimationCache,
@ -1601,8 +1608,7 @@ public extension EmojiPagerContentComponent {
forceHasPremium: Bool, forceHasPremium: Bool,
hasEdit: Bool = false, hasEdit: Bool = false,
searchIsPlaceholderOnly: Bool = true, searchIsPlaceholderOnly: Bool = true,
isProfilePhotoEmojiSelection: Bool = false, subject: StickersSubject = .chatStickers,
isGroupPhotoEmojiSelection: Bool = false,
hideBackground: Bool = false hideBackground: Bool = false
) -> Signal<EmojiPagerContentComponent, NoError> { ) -> Signal<EmojiPagerContentComponent, NoError> {
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
@ -1652,12 +1658,17 @@ public extension EmojiPagerContentComponent {
let strings = context.sharedContext.currentPresentationData.with({ $0 }).strings let strings = context.sharedContext.currentPresentationData.with({ $0 }).strings
//TODO:localize
let searchCategories: Signal<EmojiSearchCategories?, NoError> let searchCategories: Signal<EmojiSearchCategories?, NoError>
if isProfilePhotoEmojiSelection || isGroupPhotoEmojiSelection { switch subject {
case .groupPhotoEmojiSelection, .profilePhotoEmojiSelection:
searchCategories = context.engine.stickers.emojiSearchCategories(kind: .avatar) searchCategories = context.engine.stickers.emojiSearchCategories(kind: .avatar)
} else { case .chatStickers:
searchCategories = context.engine.stickers.emojiSearchCategories(kind: .emoji) searchCategories = context.engine.stickers.emojiSearchCategories(kind: .chatStickers)
case .greetingStickers:
searchCategories = context.engine.stickers.emojiSearchCategories(kind: .greetingStickers)
} }
return combineLatest( return combineLatest(
context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: stickerOrderedItemListCollectionIds, namespaces: stickerNamespaces, aroundIndex: nil, count: 10000000), context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: stickerOrderedItemListCollectionIds, namespaces: stickerNamespaces, aroundIndex: nil, count: 10000000),
hasPremium(context: context, chatPeerId: chatPeerId, premiumIfSavedMessages: false), hasPremium(context: context, chatPeerId: chatPeerId, premiumIfSavedMessages: false),
@ -2091,6 +2102,14 @@ public extension EmojiPagerContentComponent {
) )
} }
let warpContentsOnEdges: Bool
switch subject {
case .profilePhotoEmojiSelection, .groupPhotoEmojiSelection:
warpContentsOnEdges = true
default:
warpContentsOnEdges = false
}
return EmojiPagerContentComponent( return EmojiPagerContentComponent(
id: isMasks ? "masks" : "stickers", id: isMasks ? "masks" : "stickers",
context: context, context: context,
@ -2103,7 +2122,7 @@ public extension EmojiPagerContentComponent {
itemLayoutType: .detailed, itemLayoutType: .detailed,
itemContentUniqueId: nil, itemContentUniqueId: nil,
searchState: .empty(hasResults: false), searchState: .empty(hasResults: false),
warpContentsOnEdges: isProfilePhotoEmojiSelection || isGroupPhotoEmojiSelection, warpContentsOnEdges: warpContentsOnEdges,
hideBackground: hideBackground, hideBackground: hideBackground,
displaySearchWithPlaceholder: hasSearch ? strings.StickersSearch_SearchStickersPlaceholder : nil, displaySearchWithPlaceholder: hasSearch ? strings.StickersSearch_SearchStickersPlaceholder : nil,
searchCategories: searchCategories, searchCategories: searchCategories,

View File

@ -229,7 +229,8 @@ final class BusinessIntroSetupScreenComponent: Component {
hasSearch: true, hasSearch: true,
hasTrending: false, hasTrending: false,
forceHasPremium: true, forceHasPremium: true,
searchIsPlaceholderOnly: false searchIsPlaceholderOnly: false,
subject: .greetingStickers
) )
self.stickerContentDisposable = (stickerContent self.stickerContentDisposable = (stickerContent
|> deliverOnMainQueue).start(next: { [weak self] stickerContent in |> deliverOnMainQueue).start(next: { [weak self] stickerContent in

View File

@ -14,6 +14,7 @@ import TelegramStringFormatting
import StorageUsageScreen import StorageUsageScreen
import SettingsUI import SettingsUI
import DeleteChatPeerActionSheetItem import DeleteChatPeerActionSheetItem
import OverlayStatusController
fileprivate struct InitialBannedRights { fileprivate struct InitialBannedRights {
var value: TelegramChatBannedRights? var value: TelegramChatBannedRights?
@ -131,9 +132,40 @@ extension ChatControllerImpl {
return return
} }
self.navigationActionDisposable.set((combineLatest(authors.map { author in var signal = combineLatest(authors.map { author in
self.context.engine.peers.fetchChannelParticipant(peerId: peerId, participantId: author.id) self.context.engine.peers.fetchChannelParticipant(peerId: peerId, participantId: author.id)
}) })
let disposables = MetaDisposable()
self.navigationActionDisposable.set(disposables)
var cancelImpl: (() -> Void)?
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
let progressSignal = Signal<Never, NoError> { [weak self] subscriber in
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: {
cancelImpl?()
}))
self?.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
return ActionDisposable { [weak controller] in
Queue.mainQueue().async() {
controller?.dismiss()
}
}
}
|> runOn(Queue.mainQueue())
|> delay(0.3, queue: Queue.mainQueue())
let progressDisposable = progressSignal.startStrict()
signal = signal
|> afterDisposed {
Queue.mainQueue().async {
progressDisposable.dispose()
}
}
cancelImpl = {
disposables.set(nil)
}
disposables.set((signal
|> deliverOnMainQueue).startStrict(next: { [weak self] participants in |> deliverOnMainQueue).startStrict(next: { [weak self] participants in
guard let self else { guard let self else {
return return
@ -190,52 +222,88 @@ extension ChatControllerImpl {
return return
} }
do { var signal = self.context.engine.peers.fetchChannelParticipant(peerId: peerId, participantId: author.id)
self.navigationActionDisposable.set((self.context.engine.peers.fetchChannelParticipant(peerId: peerId, participantId: author.id) let disposables = MetaDisposable()
|> deliverOnMainQueue).startStrict(next: { [weak self] participant in self.navigationActionDisposable.set(disposables)
if let strongSelf = self {
if "".isEmpty { var cancelImpl: (() -> Void)?
guard let participant else { let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
let progressSignal = Signal<Never, NoError> { [weak self] subscriber in
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: {
cancelImpl?()
}))
self?.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
return ActionDisposable { [weak controller] in
Queue.mainQueue().async() {
controller?.dismiss()
}
}
}
|> runOn(Queue.mainQueue())
|> delay(0.3, queue: Queue.mainQueue())
let progressDisposable = progressSignal.startStrict()
signal = signal
|> afterDisposed {
Queue.mainQueue().async {
progressDisposable.dispose()
}
}
cancelImpl = {
disposables.set(nil)
}
disposables.set((signal
|> deliverOnMainQueue).startStrict(next: { [weak self] participant in
guard let self, let participant else {
return
}
let _ = (self.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.Peer(id: author.id)
)
|> deliverOnMainQueue).startStandalone(next: { [weak self] chatPeer, authorPeer in
guard let self, let chatPeer else {
return
}
guard let authorPeer else {
return
}
var initialUserBannedRights: [EnginePeer.Id: InitialBannedRights] = [:]
switch participant {
case .creator:
break
case let .member(_, _, _, banInfo, _):
if let banInfo {
initialUserBannedRights[participant.peerId] = InitialBannedRights(value: banInfo.rights)
} else {
initialUserBannedRights[participant.peerId] = InitialBannedRights(value: nil)
}
}
self.push(AdminUserActionsSheet(
context: self.context,
chatPeer: chatPeer,
peers: [RenderedChannelParticipant(
participant: participant,
peer: authorPeer._asPeer()
)],
messageCount: messageIds.count,
completion: { [weak self] result in
guard let self else {
return return
} }
let _ = (strongSelf.context.engine.data.get( self.applyAdminUserActionsResult(messageIds: messageIds, result: result, initialUserBannedRights: initialUserBannedRights)
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId), }
TelegramEngine.EngineData.Item.Peer.Peer(id: author.id) ))
) })
|> deliverOnMainQueue).startStandalone(next: { chatPeer, authorPeer in }))
guard let self, let chatPeer else {
return /*do {
} self.navigationActionDisposable.set((self.context.engine.peers.fetchChannelParticipant(peerId: peerId, participantId: author.id)
guard let authorPeer else { |> deliverOnMainQueue).startStrict(next: {
return if let strongSelf = self {
} if "".isEmpty {
var initialUserBannedRights: [EnginePeer.Id: InitialBannedRights] = [:]
switch participant {
case .creator:
break
case let .member(_, _, _, banInfo, _):
if let banInfo {
initialUserBannedRights[participant.peerId] = InitialBannedRights(value: banInfo.rights)
} else {
initialUserBannedRights[participant.peerId] = InitialBannedRights(value: nil)
}
}
self.push(AdminUserActionsSheet(
context: self.context,
chatPeer: chatPeer,
peers: [RenderedChannelParticipant(
participant: participant,
peer: authorPeer._asPeer()
)],
messageCount: messageIds.count,
completion: { [weak self] result in
guard let self else {
return
}
self.applyAdminUserActionsResult(messageIds: messageIds, result: result, initialUserBannedRights: initialUserBannedRights)
}
))
})
return return
} }
@ -310,7 +378,7 @@ extension ChatControllerImpl {
strongSelf.present(actionSheet, in: .window(.root)) strongSelf.present(actionSheet, in: .window(.root))
} }
})) }))
} }*/
} }
func presentDeleteMessageOptions(messageIds: Set<MessageId>, options: ChatAvailableMessageActionOptions, contextController: ContextControllerProtocol?, completion: @escaping (ContextMenuActionResult) -> Void) { func presentDeleteMessageOptions(messageIds: Set<MessageId>, options: ChatAvailableMessageActionOptions, contextController: ContextControllerProtocol?, completion: @escaping (ContextMenuActionResult) -> Void) {