mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
bb536aec28
@ -299,7 +299,7 @@ public struct Transition {
|
||||
}
|
||||
}
|
||||
|
||||
public func attachAnimation(view: UIView, completion: @escaping (Bool) -> Void) {
|
||||
public func attachAnimation(view: UIView, id: String, completion: @escaping (Bool) -> Void) {
|
||||
switch self.animation {
|
||||
case .none:
|
||||
completion(true)
|
||||
@ -307,7 +307,7 @@ public struct Transition {
|
||||
view.layer.animate(
|
||||
from: 0.0 as NSNumber,
|
||||
to: 1.0 as NSNumber,
|
||||
keyPath: "attached\(UInt32.random(in: 0 ... UInt32.max))",
|
||||
keyPath: id,
|
||||
duration: duration,
|
||||
delay: 0.0,
|
||||
curve: curve,
|
||||
|
@ -1205,7 +1205,7 @@ private final class FeaturedPaneSearchContentNode: ASDisplayNode {
|
||||
let query = text.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if query.isSingleEmoji {
|
||||
signals = .single([context.engine.stickers.searchStickers(query: text.basicEmoji.0)
|
||||
|> map { (nil, $0) }])
|
||||
|> map { (nil, $0.items) }])
|
||||
} else if query.count > 1, let languageCode = languageCode, !languageCode.isEmpty && languageCode != "emoji" {
|
||||
var signal = context.engine.stickers.searchEmojiKeywords(inputLanguageCode: languageCode, query: query.lowercased(), completeMatch: query.count < 3)
|
||||
if !languageCode.lowercased().hasPrefix("en") {
|
||||
@ -1228,7 +1228,7 @@ private final class FeaturedPaneSearchContentNode: ASDisplayNode {
|
||||
for emoji in emoticons {
|
||||
signals.append(context.engine.stickers.searchStickers(query: emoji.basicEmoji.0)
|
||||
|> take(1)
|
||||
|> map { (emoji, $0) })
|
||||
|> map { (emoji, $0.items) })
|
||||
}
|
||||
return signals
|
||||
}
|
||||
|
@ -523,12 +523,12 @@ let publicGroupRestrictedPermissions: TelegramChatBannedRightsFlags = [
|
||||
]
|
||||
|
||||
func groupPermissionDependencies(_ right: TelegramChatBannedRightsFlags) -> TelegramChatBannedRightsFlags {
|
||||
if right.contains(.banSendMedia) || banSendMediaSubList().contains(where: { $0.0 == right }) {
|
||||
if right.contains(.banEmbedLinks) {
|
||||
return [.banSendText]
|
||||
} else if right.contains(.banSendMedia) || banSendMediaSubList().contains(where: { $0.0 == right }) {
|
||||
return []
|
||||
} else if right.contains(.banSendGifs) {
|
||||
return []
|
||||
} else if right.contains(.banEmbedLinks) {
|
||||
return []
|
||||
} else if right.contains(.banSendPolls) {
|
||||
return []
|
||||
} else if right.contains(.banChangeInfo) {
|
||||
@ -762,6 +762,11 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
||||
effectiveRightsFlags.insert(right)
|
||||
}
|
||||
}
|
||||
for (right, _) in banSendMediaSubList() {
|
||||
if groupPermissionDependencies(right).contains(rights) {
|
||||
effectiveRightsFlags.insert(right)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if banSendMediaSubList().allSatisfy({ !effectiveRightsFlags.contains($0.0) }) {
|
||||
|
@ -7,16 +7,42 @@ private final class LinkHelperClass: NSObject {
|
||||
}
|
||||
|
||||
public extension TelegramGroup {
|
||||
enum Permission {
|
||||
case sendSomething
|
||||
}
|
||||
|
||||
func hasPermission(_ permission: Permission) -> Bool {
|
||||
switch permission {
|
||||
case .sendSomething:
|
||||
let flags: TelegramChatBannedRightsFlags = [
|
||||
.banSendText,
|
||||
.banSendInstantVideos,
|
||||
.banSendVoice,
|
||||
.banSendPhotos,
|
||||
.banSendVideos,
|
||||
.banSendStickers,
|
||||
.banSendPolls,
|
||||
.banSendFiles,
|
||||
.banSendInline
|
||||
]
|
||||
|
||||
if let defaultBannedRights = self.defaultBannedRights, defaultBannedRights.flags.intersection(flags) == flags {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func hasBannedPermission(_ rights: TelegramChatBannedRightsFlags) -> Bool {
|
||||
switch self.role {
|
||||
case .creator, .admin:
|
||||
case .creator, .admin:
|
||||
return false
|
||||
default:
|
||||
if let bannedRights = self.defaultBannedRights {
|
||||
return bannedRights.flags.contains(rights)
|
||||
} else {
|
||||
return false
|
||||
default:
|
||||
if let bannedRights = self.defaultBannedRights {
|
||||
return bannedRights.flags.contains(rights)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,9 +81,9 @@ func _internal_randomGreetingSticker(account: Account) -> Signal<FoundStickerIte
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_searchStickers(account: Account, query: String, scope: SearchStickersScope = [.installed, .remote]) -> Signal<[FoundStickerItem], NoError> {
|
||||
func _internal_searchStickers(account: Account, query: String, scope: SearchStickersScope = [.installed, .remote]) -> Signal<(items: [FoundStickerItem], isFinalResult: Bool), NoError> {
|
||||
if scope.isEmpty {
|
||||
return .single([])
|
||||
return .single(([], true))
|
||||
}
|
||||
var query = query
|
||||
if query == "\u{2764}" {
|
||||
@ -203,9 +203,10 @@ func _internal_searchStickers(account: Account, query: String, scope: SearchStic
|
||||
}
|
||||
|
||||
return (result, cached, isPremium, searchStickersConfiguration)
|
||||
} |> mapToSignal { localItems, cached, isPremium, searchStickersConfiguration -> Signal<[FoundStickerItem], NoError> in
|
||||
}
|
||||
|> mapToSignal { localItems, cached, isPremium, searchStickersConfiguration -> Signal<(items: [FoundStickerItem], isFinalResult: Bool), NoError> in
|
||||
if !scope.contains(.remote) {
|
||||
return .single(localItems)
|
||||
return .single((localItems, true))
|
||||
}
|
||||
|
||||
var tempResult: [FoundStickerItem] = []
|
||||
@ -281,8 +282,8 @@ func _internal_searchStickers(account: Account, query: String, scope: SearchStic
|
||||
|> `catch` { _ -> Signal<Api.messages.Stickers, NoError> in
|
||||
return .single(.stickersNotModified)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<[FoundStickerItem], NoError> in
|
||||
return account.postbox.transaction { transaction -> [FoundStickerItem] in
|
||||
|> mapToSignal { result -> Signal<(items: [FoundStickerItem], isFinalResult: Bool), NoError> in
|
||||
return account.postbox.transaction { transaction -> (items: [FoundStickerItem], isFinalResult: Bool) in
|
||||
switch result {
|
||||
case let .stickers(hash, stickers):
|
||||
var result: [FoundStickerItem] = []
|
||||
@ -358,14 +359,14 @@ func _internal_searchStickers(account: Account, query: String, scope: SearchStic
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerQueryResults, key: CachedStickerQueryResult.cacheKey(query)), entry: entry)
|
||||
}
|
||||
|
||||
return result
|
||||
return (result, true)
|
||||
case .stickersNotModified:
|
||||
break
|
||||
}
|
||||
return tempResult
|
||||
return (tempResult, true)
|
||||
}
|
||||
}
|
||||
return .single(tempResult)
|
||||
return .single((tempResult, false))
|
||||
|> then(remote)
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public extension TelegramEngine {
|
||||
return _internal_randomGreetingSticker(account: self.account)
|
||||
}
|
||||
|
||||
public func searchStickers(query: String, scope: SearchStickersScope = [.installed, .remote]) -> Signal<[FoundStickerItem], NoError> {
|
||||
public func searchStickers(query: String, scope: SearchStickersScope = [.installed, .remote]) -> Signal<(items: [FoundStickerItem], isFinalResult: Bool), NoError> {
|
||||
return _internal_searchStickers(account: self.account, query: query, scope: scope)
|
||||
}
|
||||
|
||||
|
@ -281,7 +281,11 @@ final class AvatarEditorScreenComponent: Component {
|
||||
|> mapToSignal { keywords -> Signal<[EmojiPagerContentComponent.ItemGroup], NoError> in
|
||||
return combineLatest(
|
||||
context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: [], namespaces: [Namespaces.ItemCollection.CloudEmojiPacks], aroundIndex: nil, count: 10000000) |> take(1),
|
||||
combineLatest(keywords.map { context.engine.stickers.searchStickers(query: $0.emoticons.first!) })
|
||||
combineLatest(keywords.map { context.engine.stickers.searchStickers(query: $0.emoticons.first!)
|
||||
|> map { items -> [FoundStickerItem] in
|
||||
return items.items
|
||||
}
|
||||
})
|
||||
)
|
||||
|> map { view, stickers -> [EmojiPagerContentComponent.ItemGroup] in
|
||||
let hasPremium = true
|
||||
|
@ -1300,11 +1300,11 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
strongSelf.stickerSearchResult.set(.single(nil))
|
||||
case let .category(value):
|
||||
let resultSignal = strongSelf.context.engine.stickers.searchStickers(query: value, scope: [.installed, .remote])
|
||||
|> mapToSignal { files -> Signal<[EmojiPagerContentComponent.ItemGroup], NoError> in
|
||||
|> mapToSignal { files -> Signal<(items: [EmojiPagerContentComponent.ItemGroup], isFinalResult: Bool), NoError> in
|
||||
var items: [EmojiPagerContentComponent.Item] = []
|
||||
|
||||
var existingIds = Set<MediaId>()
|
||||
for item in files {
|
||||
for item in files.items {
|
||||
let itemFile = item.file
|
||||
if existingIds.contains(itemFile.fileId) {
|
||||
continue
|
||||
@ -1321,7 +1321,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
items.append(item)
|
||||
}
|
||||
|
||||
return .single([EmojiPagerContentComponent.ItemGroup(
|
||||
return .single(([EmojiPagerContentComponent.ItemGroup(
|
||||
supergroupId: "search",
|
||||
groupId: "search",
|
||||
title: nil,
|
||||
@ -1335,7 +1335,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
displayPremiumBadges: false,
|
||||
headerItem: nil,
|
||||
items: items
|
||||
)])
|
||||
)], files.isFinalResult))
|
||||
}
|
||||
|
||||
strongSelf.stickerSearchDisposable.set((resultSignal
|
||||
@ -1343,7 +1343,13 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.stickerSearchResult.set(.single((result, AnyHashable(value))))
|
||||
guard let group = result.items.first else {
|
||||
return
|
||||
}
|
||||
if group.items.isEmpty && !result.isFinalResult {
|
||||
return
|
||||
}
|
||||
strongSelf.stickerSearchResult.set(.single((result.items, AnyHashable(value))))
|
||||
}))
|
||||
}
|
||||
},
|
||||
|
@ -339,7 +339,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
|
||||
let query = text.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if query.isSingleEmoji {
|
||||
signals = .single([context.engine.stickers.searchStickers(query: text.basicEmoji.0)
|
||||
|> map { (nil, $0) }])
|
||||
|> map { (nil, $0.items) }])
|
||||
} else if query.count > 1, let languageCode = languageCode, !languageCode.isEmpty && languageCode != "emoji" {
|
||||
var signal = context.engine.stickers.searchEmojiKeywords(inputLanguageCode: languageCode, query: query.lowercased(), completeMatch: query.count < 3)
|
||||
if !languageCode.lowercased().hasPrefix("en") {
|
||||
@ -362,7 +362,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
|
||||
for emoji in emoticons {
|
||||
signals.append(context.engine.stickers.searchStickers(query: emoji.basicEmoji.0)
|
||||
// |> take(1)
|
||||
|> map { (emoji, $0) })
|
||||
|> map { (emoji, $0.items) })
|
||||
}
|
||||
return signals
|
||||
}
|
||||
|
@ -5008,6 +5008,15 @@ public final class EmojiPagerContentComponent: Component {
|
||||
scrollView.bounds = presentation.bounds
|
||||
scrollView.layer.removeAllAnimations()
|
||||
}
|
||||
|
||||
if self.isSearchActivated, let visibleSearchHeader = self.visibleSearchHeader, visibleSearchHeader.currentPresetSearchTerm == nil {
|
||||
scrollView.isScrollEnabled = false
|
||||
DispatchQueue.main.async {
|
||||
scrollView.isScrollEnabled = true
|
||||
}
|
||||
self.visibleSearchHeader?.deactivate()
|
||||
}
|
||||
self.component?.inputInteractionHolder.inputInteraction?.onScroll()
|
||||
}
|
||||
|
||||
public func ensureSearchUnfocused() {
|
||||
@ -5026,11 +5035,6 @@ public final class EmojiPagerContentComponent: Component {
|
||||
self.updateVisibleItems(transition: .immediate, attemptSynchronousLoads: false, previousItemPositions: nil, updatedItemPositions: nil)
|
||||
|
||||
self.updateScrollingOffset(isReset: false, transition: .immediate)
|
||||
|
||||
if self.isSearchActivated, let visibleSearchHeader = self.visibleSearchHeader, visibleSearchHeader.currentPresetSearchTerm == nil {
|
||||
self.visibleSearchHeader?.deactivate()
|
||||
}
|
||||
self.component?.inputInteractionHolder.inputInteraction?.onScroll()
|
||||
}
|
||||
|
||||
public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
|
||||
@ -6375,7 +6379,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*if component.inputInteractionHolder.inputInteraction?.externalBackground == nil {
|
||||
/*if useOpaqueTheme {
|
||||
if visibleSearchHeader.superview != self.scrollView {
|
||||
self.scrollView.addSubview(visibleSearchHeader)
|
||||
self.mirrorContentScrollView.addSubview(visibleSearchHeader.tintContainerView)
|
||||
@ -6431,7 +6435,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
|
||||
let searchHeaderFrame = CGRect(origin: CGPoint(x: itemLayout.searchInsets.left, y: itemLayout.searchInsets.top), size: CGSize(width: itemLayout.width - itemLayout.searchInsets.left - itemLayout.searchInsets.right, height: itemLayout.searchHeight))
|
||||
visibleSearchHeader.update(context: component.context, theme: keyboardChildEnvironment.theme, strings: keyboardChildEnvironment.strings, text: displaySearchWithPlaceholder, useOpaqueTheme: useOpaqueTheme, isActive: self.isSearchActivated, size: searchHeaderFrame.size, canFocus: !component.searchIsPlaceholderOnly, searchCategories: component.searchCategories, transition: transition)
|
||||
transition.attachAnimation(view: visibleSearchHeader, completion: { [weak self] completed in
|
||||
/*transition.attachAnimation(view: visibleSearchHeader, id: "search_transition", completion: { [weak self] completed in
|
||||
guard let strongSelf = self, completed, let visibleSearchHeader = strongSelf.visibleSearchHeader else {
|
||||
return
|
||||
}
|
||||
@ -6440,8 +6444,41 @@ public final class EmojiPagerContentComponent: Component {
|
||||
strongSelf.scrollView.addSubview(visibleSearchHeader)
|
||||
strongSelf.mirrorContentScrollView.addSubview(visibleSearchHeader.tintContainerView)
|
||||
}
|
||||
})
|
||||
transition.setFrame(view: visibleSearchHeader, frame: searchHeaderFrame)
|
||||
})*/
|
||||
if visibleSearchHeader.frame != searchHeaderFrame {
|
||||
transition.setFrame(view: visibleSearchHeader, frame: searchHeaderFrame, completion: { [weak self] completed in
|
||||
if !useOpaqueTheme {
|
||||
guard let strongSelf = self, completed, let visibleSearchHeader = strongSelf.visibleSearchHeader else {
|
||||
return
|
||||
}
|
||||
|
||||
if !strongSelf.isSearchActivated && visibleSearchHeader.superview != strongSelf.scrollView {
|
||||
strongSelf.scrollView.addSubview(visibleSearchHeader)
|
||||
strongSelf.mirrorContentScrollView.addSubview(visibleSearchHeader.tintContainerView)
|
||||
}
|
||||
}
|
||||
})
|
||||
// Temporary workaround for status selection; use a separate search container (see GIF)
|
||||
if useOpaqueTheme {
|
||||
if case let .curve(duration, _) = transition.animation, duration != 0.0 {
|
||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + duration, execute: { [weak self] in
|
||||
guard let strongSelf = self, let visibleSearchHeader = strongSelf.visibleSearchHeader else {
|
||||
return
|
||||
}
|
||||
|
||||
if !strongSelf.isSearchActivated && visibleSearchHeader.superview != strongSelf.scrollView {
|
||||
strongSelf.scrollView.addSubview(visibleSearchHeader)
|
||||
strongSelf.mirrorContentScrollView.addSubview(visibleSearchHeader.tintContainerView)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if !self.isSearchActivated && visibleSearchHeader.superview != self.scrollView {
|
||||
self.scrollView.addSubview(visibleSearchHeader)
|
||||
self.mirrorContentScrollView.addSubview(visibleSearchHeader.tintContainerView)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let visibleSearchHeader = self.visibleSearchHeader {
|
||||
self.visibleSearchHeader = nil
|
||||
|
@ -288,6 +288,7 @@ final class EmojiSearchSearchBarComponent: Component {
|
||||
component.searchTermUpdated(group.identifiers.joined(separator: ""))
|
||||
} else {
|
||||
component.searchTermUpdated(nil)
|
||||
self.scrollView.setContentOffset(CGPoint(), animated: true)
|
||||
}
|
||||
|
||||
break
|
||||
@ -301,6 +302,7 @@ final class EmojiSearchSearchBarComponent: Component {
|
||||
if self.selectedItem != nil {
|
||||
self.selectedItem = nil
|
||||
self.state?.updated(transition: .immediate)
|
||||
self.scrollView.setContentOffset(CGPoint(), animated: true)
|
||||
if dispatchEvent {
|
||||
self.component?.searchTermUpdated(nil)
|
||||
}
|
||||
|
@ -447,10 +447,10 @@ final class DataUsageScreenComponent: Component {
|
||||
|
||||
headerOffset = min(headerOffset, minOffset)
|
||||
|
||||
let animatedTransition = Transition(animation: .curve(duration: 0.18, curve: .easeInOut))
|
||||
let animatedTransition = Transition(animation: .curve(duration: 0.2, curve: .easeInOut))
|
||||
let navigationBackgroundAlpha: CGFloat = abs(headerOffset - minOffset) < 4.0 ? 1.0 : 0.0
|
||||
|
||||
let navigationButtonAlpha: CGFloat = abs(headerOffset - minOffset) < 62.0 ? 0.0 : 1.0
|
||||
let navigationButtonAlpha: CGFloat = scrollBounds.minY >= navigationMetrics.navigationHeight ? 0.0 : 1.0
|
||||
|
||||
animatedTransition.setAlpha(view: self.navigationBackgroundView, alpha: navigationBackgroundAlpha)
|
||||
animatedTransition.setAlpha(layer: self.navigationSeparatorLayerContainer, alpha: navigationBackgroundAlpha)
|
||||
@ -468,17 +468,19 @@ final class DataUsageScreenComponent: Component {
|
||||
transition.setBounds(view: self.headerOffsetContainer, bounds: CGRect(origin: CGPoint(x: 0.0, y: headerOffset), size: self.headerOffsetContainer.bounds.size))
|
||||
|
||||
if let controller = self.controller?(), let backButtonNode = controller.navigationBar?.backButtonNode {
|
||||
if backButtonNode.isHidden {
|
||||
backButtonNode.alpha = 0.0
|
||||
backButtonNode.isHidden = false
|
||||
}
|
||||
animatedTransition.setAlpha(layer: backButtonNode.layer, alpha: navigationButtonAlpha, completion: { [weak backButtonNode] completed in
|
||||
if let backButtonNode, completed {
|
||||
if navigationButtonAlpha.isZero {
|
||||
backButtonNode.isHidden = true
|
||||
}
|
||||
if backButtonNode.alpha != navigationButtonAlpha {
|
||||
if backButtonNode.isHidden {
|
||||
backButtonNode.alpha = 0.0
|
||||
backButtonNode.isHidden = false
|
||||
}
|
||||
})
|
||||
animatedTransition.setAlpha(layer: backButtonNode.layer, alpha: navigationButtonAlpha, completion: { [weak backButtonNode] completed in
|
||||
if let backButtonNode, completed {
|
||||
if navigationButtonAlpha.isZero {
|
||||
backButtonNode.isHidden = true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18184,17 +18184,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
var itemList: [String] = []
|
||||
|
||||
var flags: TelegramChatBannedRightsFlags = []
|
||||
if let channel = peer as? TelegramChannel {
|
||||
if let bannedRights = channel.bannedRights {
|
||||
flags = bannedRights.flags
|
||||
}
|
||||
} else if let group = peer as? TelegramGroup {
|
||||
if let bannedRights = group.defaultBannedRights {
|
||||
flags = bannedRights.flags
|
||||
}
|
||||
}
|
||||
|
||||
let order: [TelegramChatBannedRightsFlags] = [
|
||||
.banSendText,
|
||||
.banSendPhotos,
|
||||
@ -18207,32 +18196,40 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
]
|
||||
|
||||
for right in order {
|
||||
if !flags.contains(right) {
|
||||
var title: String?
|
||||
switch right {
|
||||
case .banSendText:
|
||||
title = "text messages"
|
||||
case .banSendPhotos:
|
||||
title = "photos"
|
||||
case .banSendVideos:
|
||||
title = "videos"
|
||||
case .banSendVoice:
|
||||
title = "voice messages"
|
||||
case .banSendInstantVideos:
|
||||
title = "video messages"
|
||||
case .banSendFiles:
|
||||
title = "files"
|
||||
case .banSendMusic:
|
||||
title = "music"
|
||||
case .banSendStickers:
|
||||
title = "Stickers & GIFs"
|
||||
default:
|
||||
break
|
||||
if let channel = peer as? TelegramChannel {
|
||||
if channel.hasBannedPermission(right) != nil {
|
||||
continue
|
||||
}
|
||||
if let title {
|
||||
itemList.append(title)
|
||||
} else if let group = peer as? TelegramGroup {
|
||||
if group.hasBannedPermission(right) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
var title: String?
|
||||
switch right {
|
||||
case .banSendText:
|
||||
title = "text messages"
|
||||
case .banSendPhotos:
|
||||
title = "photos"
|
||||
case .banSendVideos:
|
||||
title = "videos"
|
||||
case .banSendVoice:
|
||||
title = "voice messages"
|
||||
case .banSendInstantVideos:
|
||||
title = "video messages"
|
||||
case .banSendFiles:
|
||||
title = "files"
|
||||
case .banSendMusic:
|
||||
title = "music"
|
||||
case .banSendStickers:
|
||||
title = "Stickers & GIFs"
|
||||
default:
|
||||
break
|
||||
}
|
||||
if let title {
|
||||
itemList.append(title)
|
||||
}
|
||||
}
|
||||
|
||||
if itemList.isEmpty {
|
||||
|
@ -128,6 +128,9 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
|
||||
scope = [.installed]
|
||||
}
|
||||
return context.engine.stickers.searchStickers(query: query.basicEmoji.0, scope: scope)
|
||||
|> map { items -> [FoundStickerItem] in
|
||||
return items.items
|
||||
}
|
||||
|> castError(ChatContextQueryError.self)
|
||||
}
|
||||
|> map { stickers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
|
||||
|
@ -196,15 +196,15 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState
|
||||
}
|
||||
}
|
||||
|
||||
if isMember && channel.hasBannedPermission(.banSendText) != nil && !channel.flags.contains(.isGigagroup) {
|
||||
/*if let currentPanel = (currentPanel as? ChatRestrictedInputPanelNode) ?? (currentSecondaryPanel as? ChatRestrictedInputPanelNode) {
|
||||
if isMember && !channel.hasPermission(.sendSomething) && !channel.flags.contains(.isGigagroup) {
|
||||
if let currentPanel = (currentPanel as? ChatRestrictedInputPanelNode) ?? (currentSecondaryPanel as? ChatRestrictedInputPanelNode) {
|
||||
return (currentPanel, nil)
|
||||
} else {
|
||||
let panel = ChatRestrictedInputPanelNode()
|
||||
panel.context = context
|
||||
panel.interfaceInteraction = interfaceInteraction
|
||||
return (panel, nil)
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
switch channel.info {
|
||||
@ -280,15 +280,15 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState
|
||||
break
|
||||
}
|
||||
|
||||
if group.hasBannedPermission(.banSendText) {
|
||||
/*if let currentPanel = (currentPanel as? ChatRestrictedInputPanelNode) ?? (currentSecondaryPanel as? ChatRestrictedInputPanelNode) {
|
||||
if !group.hasPermission(.sendSomething) {
|
||||
if let currentPanel = (currentPanel as? ChatRestrictedInputPanelNode) ?? (currentSecondaryPanel as? ChatRestrictedInputPanelNode) {
|
||||
return (currentPanel, nil)
|
||||
} else {
|
||||
let panel = ChatRestrictedInputPanelNode()
|
||||
panel.context = context
|
||||
panel.interfaceInteraction = interfaceInteraction
|
||||
return (panel, nil)
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2126,9 +2126,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
mediaInputDisabled = true
|
||||
} else if interfaceState.hasActiveGroupCall {
|
||||
mediaInputDisabled = true
|
||||
} else if let channel = interfaceState.renderedPeer?.peer as? TelegramChannel, channel.hasBannedPermission(.banSendMedia) != nil {
|
||||
} else if let channel = interfaceState.renderedPeer?.peer as? TelegramChannel, channel.hasBannedPermission(.banSendVoice) != nil, channel.hasBannedPermission(.banSendInstantVideos) != nil {
|
||||
mediaInputDisabled = true
|
||||
} else if let group = interfaceState.renderedPeer?.peer as? TelegramGroup, group.hasBannedPermission(.banSendMedia) {
|
||||
} else if let group = interfaceState.renderedPeer?.peer as? TelegramGroup, group.hasBannedPermission(.banSendVoice), group.hasBannedPermission(.banSendInstantVideos) {
|
||||
mediaInputDisabled = true
|
||||
} else {
|
||||
mediaInputDisabled = false
|
||||
|
@ -191,7 +191,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
return ("URL", contents)
|
||||
}), textAlignment: .natural)
|
||||
self.textNode.attributedText = attributedText
|
||||
self.textNode.maximumNumberOfLines = 2
|
||||
self.textNode.maximumNumberOfLines = 10
|
||||
displayUndo = false
|
||||
self.originalRemainingSeconds = Double(max(5, min(8, text.count / 14)))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user