mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 13:35:19 +00:00
Folder improvements
This commit is contained in:
parent
65bcef3ee2
commit
7b0f6ed7ca
@ -97,7 +97,7 @@ public final class ActivityIndicator: ASDisplayNode {
|
||||
super.init()
|
||||
|
||||
if case let .custom(_, _, _, forceCustom) = self.type, forceCustom {
|
||||
self.isLayerBacked = true
|
||||
//self.isLayerBacked = true
|
||||
}
|
||||
|
||||
switch type {
|
||||
|
@ -2705,6 +2705,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
self?.push(c)
|
||||
}, presentController: { [weak self] c in
|
||||
self?.present(c, in: .window(.root))
|
||||
}, completed: {
|
||||
}, linkUpdated: { _ in
|
||||
})
|
||||
}
|
||||
@ -2816,33 +2817,38 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
return
|
||||
}
|
||||
|
||||
let previewScreen = ChatFolderLinkPreviewScreen(
|
||||
context: self.context,
|
||||
subject: .remove(folderId: id, defaultSelectedPeerIds: defaultSelectedPeerIds),
|
||||
contents: ChatFolderLinkContents(
|
||||
localFilterId: id,
|
||||
title: title,
|
||||
peers: peers.compactMap { $0 }.filter { peer in
|
||||
if case .channel = peer {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
},
|
||||
alreadyMemberPeerIds: Set(),
|
||||
memberCounts: memberCounts
|
||||
),
|
||||
completion: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if self.chatListDisplayNode.mainContainerNode.currentItemNode.chatListFilter?.id == id {
|
||||
self.chatListDisplayNode.mainContainerNode.switchToFilter(id: .all, completion: {
|
||||
})
|
||||
}
|
||||
let filteredPeers = peers.compactMap { $0 }.filter { peer in
|
||||
if case .channel = peer {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
)
|
||||
self.push(previewScreen)
|
||||
}
|
||||
if filteredPeers.isEmpty {
|
||||
apply()
|
||||
} else {
|
||||
let previewScreen = ChatFolderLinkPreviewScreen(
|
||||
context: self.context,
|
||||
subject: .remove(folderId: id, defaultSelectedPeerIds: defaultSelectedPeerIds),
|
||||
contents: ChatFolderLinkContents(
|
||||
localFilterId: id,
|
||||
title: title,
|
||||
peers: filteredPeers,
|
||||
alreadyMemberPeerIds: Set(),
|
||||
memberCounts: memberCounts
|
||||
),
|
||||
completion: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if self.chatListDisplayNode.mainContainerNode.currentItemNode.chatListFilter?.id == id {
|
||||
self.chatListDisplayNode.mainContainerNode.switchToFilter(id: .all, completion: {
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
self.push(previewScreen)
|
||||
}
|
||||
}
|
||||
|
||||
if hasLinks {
|
||||
|
@ -1084,7 +1084,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
var dismissImpl: (() -> Void)?
|
||||
var focusOnNameImpl: (() -> Void)?
|
||||
var clearFocusImpl: (() -> Void)?
|
||||
var applyImpl: ((@escaping () -> Void) -> Void)?
|
||||
var applyImpl: ((Bool, @escaping () -> Void) -> Void)?
|
||||
|
||||
let sharedLinks = Promise<[ExportedChatFolderLink]?>(nil)
|
||||
if let currentPreset {
|
||||
@ -1297,11 +1297,16 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
},
|
||||
createLink: {
|
||||
if currentPreset == nil {
|
||||
//TODO:localize
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let text = "Please finish creating this folder to share it."
|
||||
presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||
} else {
|
||||
applyImpl?({
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let statusController = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
|
||||
presentControllerImpl?(statusController, nil)
|
||||
|
||||
applyImpl?(true, { [weak statusController] in
|
||||
let state = stateValue.with({ $0 })
|
||||
|
||||
if let currentPreset, let data = currentPreset.data {
|
||||
@ -1315,17 +1320,24 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
unavailableText = "You can’t share folders which have chat types or excluded chats."
|
||||
}
|
||||
if let unavailableText {
|
||||
statusController?.dismiss()
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: unavailableText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var statusController = statusController
|
||||
|
||||
var previousLink: ExportedChatFolderLink?
|
||||
openCreateChatListFolderLink(context: context, folderId: currentPreset.id, checkIfExists: false, title: currentPreset.title, peerIds: state.additionallyIncludePeers, pushController: { c in
|
||||
pushControllerImpl?(c)
|
||||
}, presentController: { c in
|
||||
presentControllerImpl?(c, nil)
|
||||
}, completed: {
|
||||
statusController?.dismiss()
|
||||
statusController = nil
|
||||
}, linkUpdated: { updatedLink in
|
||||
let previousLinkValue = previousLink
|
||||
previousLink = updatedLink
|
||||
@ -1347,12 +1359,14 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
sharedLinks.set(.single(links))
|
||||
})
|
||||
})
|
||||
} else {
|
||||
statusController?.dismiss()
|
||||
}
|
||||
})
|
||||
}
|
||||
}, openLink: { link in
|
||||
if let currentPreset, let _ = currentPreset.data {
|
||||
applyImpl?({
|
||||
applyImpl?(false, {
|
||||
let state = stateValue.with({ $0 })
|
||||
pushControllerImpl?(folderInviteLinkListController(context: context, filterId: currentPreset.id, title: currentPreset.title, allPeerIds: state.additionallyIncludePeers, currentInvitation: link, linkUpdated: { updatedLink in
|
||||
if updatedLink != link {
|
||||
@ -1394,14 +1408,13 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
)
|
||||
|
||||
var attemptNavigationImpl: (() -> Bool)?
|
||||
applyImpl = { completed in
|
||||
applyImpl = { waitForSync, completed in
|
||||
let state = stateValue.with { $0 }
|
||||
|
||||
var includePeers = ChatListFilterIncludePeers()
|
||||
includePeers.setPeers(state.additionallyIncludePeers)
|
||||
|
||||
let _ = (context.engine.peers.updateChatListFiltersInteractively { filters in
|
||||
|
||||
var filterId = currentPreset?.id ?? -1
|
||||
if currentPreset == nil {
|
||||
filterId = context.engine.peers.generateNewChatListFilterId(filters: filters)
|
||||
@ -1440,7 +1453,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
|> deliverOnMainQueue).start(next: { filters in
|
||||
updated(filters)
|
||||
|
||||
if let currentPreset {
|
||||
if let currentPreset, waitForSync {
|
||||
let _ = (context.engine.peers.updatedChatListFilters()
|
||||
|> filter { filters -> Bool in
|
||||
for filter in filters {
|
||||
@ -1490,7 +1503,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
}
|
||||
})
|
||||
let rightNavigationButton = ItemListNavigationButton(content: .text(currentPreset == nil ? presentationData.strings.Common_Create : presentationData.strings.Common_Done), style: .bold, enabled: state.isComplete, action: {
|
||||
applyImpl?({
|
||||
applyImpl?(false, {
|
||||
dismissImpl?()
|
||||
})
|
||||
})
|
||||
@ -1559,7 +1572,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
}),
|
||||
//TODO:localize
|
||||
TextAlertAction(type: .defaultAction, title: "Save", action: {
|
||||
applyImpl?({
|
||||
applyImpl?(false, {
|
||||
dismissImpl?()
|
||||
})
|
||||
})]), nil)
|
||||
@ -1594,8 +1607,9 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
return controller
|
||||
}
|
||||
|
||||
func openCreateChatListFolderLink(context: AccountContext, folderId: Int32, checkIfExists: Bool, title: String, peerIds: [EnginePeer.Id], pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController) -> Void, linkUpdated: @escaping (ExportedChatFolderLink?) -> Void) {
|
||||
func openCreateChatListFolderLink(context: AccountContext, folderId: Int32, checkIfExists: Bool, title: String, peerIds: [EnginePeer.Id], pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController) -> Void, completed: @escaping () -> Void, linkUpdated: @escaping (ExportedChatFolderLink?) -> Void) {
|
||||
if peerIds.isEmpty {
|
||||
completed()
|
||||
return
|
||||
}
|
||||
|
||||
@ -1610,6 +1624,9 @@ func openCreateChatListFolderLink(context: AccountContext, folderId: Int32, chec
|
||||
|> map { result, peers -> ExportedChatFolderLink? in
|
||||
var enabledPeerIds: [EnginePeer.Id] = []
|
||||
for peer in peers {
|
||||
if case let .legacyGroup(group) = peer, group.migrationReference != nil {
|
||||
continue
|
||||
}
|
||||
if let peer, canShareLinkToPeer(peer: peer) {
|
||||
enabledPeerIds.append(peer.id)
|
||||
}
|
||||
@ -1634,6 +1651,7 @@ func openCreateChatListFolderLink(context: AccountContext, folderId: Int32, chec
|
||||
let _ = (existingLink
|
||||
|> deliverOnMainQueue).start(next: { existingLink in
|
||||
if let existingLink {
|
||||
completed()
|
||||
pushController(folderInviteLinkListController(context: context, filterId: folderId, title: title, allPeerIds: peerIds, currentInvitation: existingLink, linkUpdated: linkUpdated))
|
||||
|
||||
return
|
||||
@ -1643,9 +1661,18 @@ func openCreateChatListFolderLink(context: AccountContext, folderId: Int32, chec
|
||||
EngineDataList(peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { peers in
|
||||
let peers = peers.compactMap({ $0 })
|
||||
let peers = peers.compactMap({ peer -> EnginePeer? in
|
||||
guard let peer else {
|
||||
return nil
|
||||
}
|
||||
if case let .legacyGroup(group) = peer, group.migrationReference != nil {
|
||||
return nil
|
||||
}
|
||||
return peer
|
||||
})
|
||||
if peers.allSatisfy({ !canShareLinkToPeer(peer: $0) }) {
|
||||
pushController(folderInviteLinkListController(context: context, filterId: folderId, title: title, allPeerIds: peerIds, currentInvitation: nil, linkUpdated: linkUpdated))
|
||||
completed()
|
||||
pushController(folderInviteLinkListController(context: context, filterId: folderId, title: title, allPeerIds: peers.map(\.id), currentInvitation: nil, linkUpdated: linkUpdated))
|
||||
} else {
|
||||
var enabledPeerIds: [EnginePeer.Id] = []
|
||||
for peer in peers {
|
||||
@ -1656,10 +1683,12 @@ func openCreateChatListFolderLink(context: AccountContext, folderId: Int32, chec
|
||||
|
||||
let _ = (context.engine.peers.exportChatFolder(filterId: folderId, title: "", peerIds: enabledPeerIds)
|
||||
|> deliverOnMainQueue).start(next: { link in
|
||||
completed()
|
||||
linkUpdated(link)
|
||||
|
||||
pushController(folderInviteLinkListController(context: context, filterId: folderId, title: title, allPeerIds: peerIds, currentInvitation: link, linkUpdated: linkUpdated))
|
||||
pushController(folderInviteLinkListController(context: context, filterId: folderId, title: title, allPeerIds: peers.map(\.id), currentInvitation: link, linkUpdated: linkUpdated))
|
||||
}, error: { error in
|
||||
completed()
|
||||
//TODO:localize
|
||||
let text: String
|
||||
switch error {
|
||||
|
@ -416,24 +416,37 @@ public func chatListFilterPresetListController(context: AccountContext, mode: Ch
|
||||
}
|
||||
|
||||
let confirmDeleteFolder: () -> Void = {
|
||||
let previewScreen = ChatFolderLinkPreviewScreen(
|
||||
context: context,
|
||||
subject: .remove(folderId: id, defaultSelectedPeerIds: defaultSelectedPeerIds),
|
||||
contents: ChatFolderLinkContents(
|
||||
localFilterId: id,
|
||||
title: title,
|
||||
peers: peers.compactMap { $0 }.filter { peer in
|
||||
if case .channel = peer {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
},
|
||||
alreadyMemberPeerIds: Set(),
|
||||
memberCounts: memberCounts
|
||||
let filteredPeers = peers.compactMap { $0 }.filter { peer in
|
||||
if case .channel = peer {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if filteredPeers.isEmpty {
|
||||
let _ = (context.engine.peers.updateChatListFiltersInteractively { filters in
|
||||
var filters = filters
|
||||
if let index = filters.firstIndex(where: { $0.id == id }) {
|
||||
filters.remove(at: index)
|
||||
}
|
||||
return filters
|
||||
}
|
||||
|> deliverOnMainQueue).start()
|
||||
} else {
|
||||
let previewScreen = ChatFolderLinkPreviewScreen(
|
||||
context: context,
|
||||
subject: .remove(folderId: id, defaultSelectedPeerIds: defaultSelectedPeerIds),
|
||||
contents: ChatFolderLinkContents(
|
||||
localFilterId: id,
|
||||
title: title,
|
||||
peers: filteredPeers,
|
||||
alreadyMemberPeerIds: Set(),
|
||||
memberCounts: memberCounts
|
||||
)
|
||||
)
|
||||
)
|
||||
pushControllerImpl?(previewScreen)
|
||||
pushControllerImpl?(previewScreen)
|
||||
}
|
||||
}
|
||||
|
||||
if hasLinks {
|
||||
|
@ -521,7 +521,15 @@ public func folderInviteLinkListController(context: AccountContext, updatedPrese
|
||||
text = "You can't share private chats"
|
||||
}
|
||||
} else {
|
||||
text = "You don't have the admin rights to share invite links to this group chat."
|
||||
var isGroup = true
|
||||
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||
isGroup = false
|
||||
}
|
||||
if isGroup {
|
||||
text = "You don't have the admin rights to share invite links to this group chat."
|
||||
} else {
|
||||
text = "You don't have the admin rights to share invite links to this channel."
|
||||
}
|
||||
}
|
||||
dismissTooltipsImpl?()
|
||||
displayTooltipImpl?(.peers(context: context, peers: [peer], title: nil, text: text, customUndoText: nil))
|
||||
@ -557,6 +565,17 @@ public func folderInviteLinkListController(context: AccountContext, updatedPrese
|
||||
let allPeers = context.engine.data.subscribe(
|
||||
EngineDataList(combinedPeerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
|
||||
)
|
||||
|> map { peers -> [EnginePeer] in
|
||||
return peers.compactMap({ peer -> EnginePeer? in
|
||||
guard let peer else {
|
||||
return nil
|
||||
}
|
||||
if case let .legacyGroup(group) = peer, group.migrationReference != nil {
|
||||
return nil
|
||||
}
|
||||
return peer
|
||||
})
|
||||
}
|
||||
|
||||
let applyChangesImpl: (() -> Void)? = {
|
||||
let state = stateValue.with({ $0 })
|
||||
@ -608,9 +627,9 @@ public func folderInviteLinkListController(context: AccountContext, updatedPrese
|
||||
state.selectedPeerIds.insert(peerId)
|
||||
}
|
||||
} else {
|
||||
for peerId in allPeerIds {
|
||||
if let peer = peers.first(where: { $0?.id == peerId }), let peerValue = peer {
|
||||
if canShareLinkToPeer(peer: peerValue) {
|
||||
for peerId in peers.map(\.id) {
|
||||
if let peer = peers.first(where: { $0.id == peerId }) {
|
||||
if canShareLinkToPeer(peer: peer) {
|
||||
state.selectedPeerIds.insert(peerId)
|
||||
}
|
||||
}
|
||||
|
@ -366,12 +366,10 @@ func _internal_checkChatFolderLink(account: Account, slug: String) -> Signal<Cha
|
||||
continue
|
||||
}
|
||||
if let peerValue = transaction.getPeer(peerId) {
|
||||
if canShareLinkToPeer(peer: EnginePeer(peerValue)) {
|
||||
resultPeers.append(EnginePeer(peerValue))
|
||||
|
||||
if transaction.getPeerChatListIndex(peerId) != nil {
|
||||
alreadyMemberPeerIds.insert(peerId)
|
||||
}
|
||||
resultPeers.append(EnginePeer(peerValue))
|
||||
|
||||
if transaction.getPeerChatListIndex(peerId) != nil {
|
||||
alreadyMemberPeerIds.insert(peerId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ swift_library(
|
||||
"//submodules/Display",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/TelegramUI/Components/AnimatedTextComponent",
|
||||
"//submodules/ActivityIndicator",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -3,6 +3,7 @@ import UIKit
|
||||
import Display
|
||||
import ComponentFlow
|
||||
import AnimatedTextComponent
|
||||
import ActivityIndicator
|
||||
|
||||
public final class ButtonBadgeComponent: Component {
|
||||
let fillColor: UIColor
|
||||
@ -267,15 +268,18 @@ public final class ButtonTextContentComponent: Component {
|
||||
public final class ButtonComponent: Component {
|
||||
public struct Background: Equatable {
|
||||
public var color: UIColor
|
||||
public var foreground: UIColor
|
||||
public var pressedColor: UIColor
|
||||
public var cornerRadius: CGFloat
|
||||
|
||||
public init(
|
||||
color: UIColor,
|
||||
foreground: UIColor,
|
||||
pressedColor: UIColor,
|
||||
cornerRadius: CGFloat = 10.0
|
||||
) {
|
||||
self.color = color
|
||||
self.foreground = foreground
|
||||
self.pressedColor = pressedColor
|
||||
self.cornerRadius = cornerRadius
|
||||
}
|
||||
@ -284,17 +288,20 @@ public final class ButtonComponent: Component {
|
||||
public let background: Background
|
||||
public let content: AnyComponentWithIdentity<Empty>
|
||||
public let isEnabled: Bool
|
||||
public let displaysProgress: Bool
|
||||
public let action: () -> Void
|
||||
|
||||
public init(
|
||||
background: Background,
|
||||
content: AnyComponentWithIdentity<Empty>,
|
||||
isEnabled: Bool,
|
||||
displaysProgress: Bool,
|
||||
action: @escaping () -> Void
|
||||
) {
|
||||
self.background = background
|
||||
self.content = content
|
||||
self.isEnabled = isEnabled
|
||||
self.displaysProgress = displaysProgress
|
||||
self.action = action
|
||||
}
|
||||
|
||||
@ -308,6 +315,9 @@ public final class ButtonComponent: Component {
|
||||
if lhs.isEnabled != rhs.isEnabled {
|
||||
return false
|
||||
}
|
||||
if lhs.displaysProgress != rhs.displaysProgress {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -326,6 +336,8 @@ public final class ButtonComponent: Component {
|
||||
|
||||
private var contentItem: ContentItem?
|
||||
|
||||
private var activityIndicator: ActivityIndicator?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
@ -363,10 +375,17 @@ public final class ButtonComponent: Component {
|
||||
self.component = component
|
||||
self.componentState = state
|
||||
|
||||
self.isEnabled = component.isEnabled
|
||||
self.isEnabled = component.isEnabled && !component.displaysProgress
|
||||
|
||||
transition.setBackgroundColor(view: self, color: component.background.color)
|
||||
transition.setCornerRadius(layer: self.layer, cornerRadius: component.background.cornerRadius)
|
||||
|
||||
var contentAlpha: CGFloat = 1.0
|
||||
if component.displaysProgress {
|
||||
contentAlpha = 0.0
|
||||
} else if !component.isEnabled {
|
||||
contentAlpha = 0.7
|
||||
}
|
||||
|
||||
var previousContentItem: ContentItem?
|
||||
let contentItem: ContentItem
|
||||
@ -398,11 +417,11 @@ public final class ButtonComponent: Component {
|
||||
let contentFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - contentSize.width) * 0.5), y: floor((availableSize.height - contentSize.height) * 0.5)), size: contentSize)
|
||||
|
||||
contentTransition.setFrame(view: contentView, frame: contentFrame)
|
||||
contentTransition.setAlpha(view: contentView, alpha: component.isEnabled ? 1.0 : 0.7)
|
||||
contentTransition.setAlpha(view: contentView, alpha: contentAlpha)
|
||||
|
||||
if animateIn && previousContentItem != nil && !transition.animation.isImmediate {
|
||||
contentView.layer.animateScale(from: 0.4, to: 1.0, duration: 0.35, timingFunction: kCAMediaTimingFunctionSpring)
|
||||
contentView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
||||
contentView.layer.animateAlpha(from: 0.0, to: contentAlpha, duration: 0.1)
|
||||
contentView.layer.animatePosition(from: CGPoint(x: 0.0, y: -availableSize.height * 0.15), to: CGPoint(), duration: 0.35, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
}
|
||||
}
|
||||
@ -410,7 +429,7 @@ public final class ButtonComponent: Component {
|
||||
if let previousContentItem, let previousContentView = previousContentItem.view.view {
|
||||
if !transition.animation.isImmediate {
|
||||
previousContentView.layer.animateScale(from: 1.0, to: 0.0, duration: 0.35, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
||||
previousContentView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak previousContentView] _ in
|
||||
previousContentView.layer.animateAlpha(from: contentAlpha, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak previousContentView] _ in
|
||||
previousContentView?.removeFromSuperview()
|
||||
})
|
||||
previousContentView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: availableSize.height * 0.35), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true)
|
||||
@ -419,6 +438,30 @@ public final class ButtonComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
if component.displaysProgress {
|
||||
let activityIndicator: ActivityIndicator
|
||||
var activityIndicatorTransition = transition
|
||||
if let current = self.activityIndicator {
|
||||
activityIndicator = current
|
||||
} else {
|
||||
activityIndicatorTransition = .immediate
|
||||
activityIndicator = ActivityIndicator(type: .custom(component.background.foreground, 22.0, 2.0, true))
|
||||
activityIndicator.view.alpha = 0.0
|
||||
self.activityIndicator = activityIndicator
|
||||
self.addSubview(activityIndicator.view)
|
||||
}
|
||||
let indicatorSize = CGSize(width: 22.0, height: 22.0)
|
||||
transition.setAlpha(view: activityIndicator.view, alpha: 1.0)
|
||||
activityIndicatorTransition.setFrame(view: activityIndicator.view, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - indicatorSize.width) / 2.0), y: floor((availableSize.height - indicatorSize.height) / 2.0)), size: indicatorSize))
|
||||
} else {
|
||||
if let activityIndicator = self.activityIndicator {
|
||||
self.activityIndicator = nil
|
||||
transition.setAlpha(view: activityIndicator.view, alpha: 0.0, completion: { [weak activityIndicator] _ in
|
||||
activityIndicator?.view.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return availableSize
|
||||
}
|
||||
}
|
||||
|
@ -716,15 +716,19 @@ private final class ChatFolderLinkPreviewScreenComponent: Component {
|
||||
initialContentHeight += 24.0
|
||||
|
||||
let actionButtonTitle: String
|
||||
var actionButtonBadge: Int = 0
|
||||
if case .remove = component.subject {
|
||||
actionButtonBadge = self.selectedItems.count
|
||||
if self.selectedItems.isEmpty {
|
||||
actionButtonTitle = "Remove Folder"
|
||||
} else {
|
||||
actionButtonTitle = "Remove Folder and Chats"
|
||||
}
|
||||
} else if allChatsAdded {
|
||||
actionButtonBadge = 0
|
||||
actionButtonTitle = "OK"
|
||||
} else if let linkContents = component.linkContents {
|
||||
actionButtonBadge = self.selectedItems.count
|
||||
if linkContents.localFilterId != nil {
|
||||
if self.selectedItems.isEmpty {
|
||||
actionButtonTitle = "Do Not Join Any Chats"
|
||||
@ -743,19 +747,21 @@ private final class ChatFolderLinkPreviewScreenComponent: Component {
|
||||
component: AnyComponent(ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
color: environment.theme.list.itemCheckColors.fillColor,
|
||||
foreground: environment.theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: environment.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.9)
|
||||
),
|
||||
content: AnyComponentWithIdentity(
|
||||
id: actionButtonTitle,
|
||||
component: AnyComponent(ButtonTextContentComponent(
|
||||
text: actionButtonTitle,
|
||||
badge: self.selectedItems.count,
|
||||
badge: actionButtonBadge,
|
||||
textColor: environment.theme.list.itemCheckColors.foregroundColor,
|
||||
badgeBackground: environment.theme.list.itemCheckColors.foregroundColor,
|
||||
badgeForeground: environment.theme.list.itemCheckColors.fillColor
|
||||
))
|
||||
),
|
||||
isEnabled: !self.selectedItems.isEmpty || component.linkContents?.localFilterId != nil,
|
||||
displaysProgress: self.inProgress,
|
||||
action: { [weak self] in
|
||||
guard let self, let component = self.component, let controller = self.environment?.controller() else {
|
||||
return
|
||||
|
@ -321,7 +321,7 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
case "telegram_botapp":
|
||||
title = item.presentationData.strings.Conversation_BotApp
|
||||
actionTitle = item.presentationData.strings.Conversation_OpenBotApp
|
||||
case "telegram_community":
|
||||
case "telegram_chatlist":
|
||||
actionTitle = item.presentationData.strings.Conversation_OpenChatFolder
|
||||
default:
|
||||
break
|
||||
|
Loading…
x
Reference in New Issue
Block a user