mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Folder improvements
This commit is contained in:
parent
361fa693d9
commit
55b5918841
@ -9129,3 +9129,7 @@ Sorry for the inconvenience.";
|
|||||||
"Channel.AdminLog.JoinedViaFolderInviteLink" = "%1$@ joined via invite link %2$@ (community)";
|
"Channel.AdminLog.JoinedViaFolderInviteLink" = "%1$@ joined via invite link %2$@ (community)";
|
||||||
|
|
||||||
"Conversation.OpenChatFolder" = "VIEW CHAT LIST";
|
"Conversation.OpenChatFolder" = "VIEW CHAT LIST";
|
||||||
|
|
||||||
|
"Premium.MaxChannelsText" = "You can only join **%1$@** groups and channels. Upgrade to **Telegram Premium** to increase the links limit to **%2$@**.";
|
||||||
|
"Premium.MaxChannelsNoPremiumText" = "You can only join **%1$@** groups and channels. We are working to let you increase this limit in the future.";
|
||||||
|
"Premium.MaxChannelsFinalText" = "Sorry, you can only join **%1$@** groups and channels";
|
||||||
|
@ -898,6 +898,7 @@ public enum PremiumLimitSubject {
|
|||||||
case accounts
|
case accounts
|
||||||
case linksPerSharedFolder
|
case linksPerSharedFolder
|
||||||
case membershipInSharedFolders
|
case membershipInSharedFolders
|
||||||
|
case channels
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol ComposeController: ViewController {
|
public protocol ComposeController: ViewController {
|
||||||
|
@ -1871,6 +1871,18 @@ func openCreateChatListFolderLink(context: AccountContext, folderId: Int32, chec
|
|||||||
})
|
})
|
||||||
pushController(limitController)
|
pushController(limitController)
|
||||||
|
|
||||||
|
return
|
||||||
|
case let .tooManyChannels(limit, _):
|
||||||
|
let limitController = context.sharedContext.makePremiumLimitController(context: context, subject: .linksPerSharedFolder, count: limit, action: {
|
||||||
|
})
|
||||||
|
pushController(limitController)
|
||||||
|
|
||||||
|
return
|
||||||
|
case let .tooManyChannelsInAccount(limit, _):
|
||||||
|
let limitController = context.sharedContext.makePremiumLimitController(context: context, subject: .channels, count: limit, action: {
|
||||||
|
})
|
||||||
|
pushController(limitController)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
@ -392,19 +392,26 @@ public class CheckLayer: CALayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !parameters.theme.filledBorder && !parameters.theme.hasShadow && !parameters.theme.overlayBorder {
|
if !parameters.theme.filledBorder && !parameters.theme.hasShadow && !parameters.theme.overlayBorder {
|
||||||
checkProgress = parameters.animationProgress
|
if parameters.theme.isDottedBorder {
|
||||||
|
checkProgress = 0.0
|
||||||
let fillProgress: CGFloat = parameters.animationProgress
|
let borderInset = borderWidth / 2.0 + inset
|
||||||
|
let borderFrame = CGRect(origin: CGPoint(), size: size).insetBy(dx: borderInset, dy: borderInset)
|
||||||
context.setFillColor(parameters.theme.backgroundColor.mixedWith(parameters.theme.borderColor, alpha: 1.0 - fillProgress).cgColor)
|
context.strokeEllipse(in: borderFrame)
|
||||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
|
} else {
|
||||||
|
checkProgress = parameters.animationProgress
|
||||||
let innerDiameter: CGFloat = (fillProgress * 0.0) + (1.0 - fillProgress) * (size.width - borderWidth * 2.0)
|
|
||||||
|
let fillProgress: CGFloat = parameters.animationProgress
|
||||||
context.setBlendMode(.copy)
|
|
||||||
context.setFillColor(UIColor.clear.cgColor)
|
context.setFillColor(parameters.theme.backgroundColor.mixedWith(parameters.theme.borderColor, alpha: 1.0 - fillProgress).cgColor)
|
||||||
context.fillEllipse(in: CGRect(origin: CGPoint(x: (size.width - innerDiameter) * 0.5, y: (size.height - innerDiameter) * 0.5), size: CGSize(width: innerDiameter, height: innerDiameter)))
|
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||||
context.setBlendMode(.normal)
|
|
||||||
|
let innerDiameter: CGFloat = (fillProgress * 0.0) + (1.0 - fillProgress) * (size.width - borderWidth * 2.0)
|
||||||
|
|
||||||
|
context.setBlendMode(.copy)
|
||||||
|
context.setFillColor(UIColor.clear.cgColor)
|
||||||
|
context.fillEllipse(in: CGRect(origin: CGPoint(x: (size.width - innerDiameter) * 0.5, y: (size.height - innerDiameter) * 0.5), size: CGSize(width: innerDiameter, height: innerDiameter)))
|
||||||
|
context.setBlendMode(.normal)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
checkProgress = parameters.animatingOut ? 1.0 : parameters.animationProgress
|
checkProgress = parameters.animatingOut ? 1.0 : parameters.animationProgress
|
||||||
|
|
||||||
|
@ -800,6 +800,25 @@ private final class LimitSheetContent: CombinedComponent {
|
|||||||
badgeText = "\(limit)"
|
badgeText = "\(limit)"
|
||||||
string = strings.Premium_MaxChatsInFolderNoPremiumText("\(limit)").string
|
string = strings.Premium_MaxChatsInFolderNoPremiumText("\(limit)").string
|
||||||
}
|
}
|
||||||
|
case .channels:
|
||||||
|
let limit = state.limits.maxChannelsCount
|
||||||
|
let premiumLimit = state.premiumLimits.maxChannelsCount
|
||||||
|
iconName = "Premium/Chat"
|
||||||
|
badgeText = "\(component.count)"
|
||||||
|
string = component.count >= premiumLimit ? strings.Premium_MaxChannelsFinalText("\(premiumLimit)").string : strings.Premium_MaxChannelsText("\(limit)", "\(premiumLimit)").string
|
||||||
|
defaultValue = component.count > limit ? "\(limit)" : ""
|
||||||
|
premiumValue = component.count >= premiumLimit ? "" : "\(premiumLimit)"
|
||||||
|
if component.count >= premiumLimit {
|
||||||
|
badgeGraphPosition = max(0.15, CGFloat(limit) / CGFloat(premiumLimit))
|
||||||
|
} else {
|
||||||
|
badgeGraphPosition = max(0.15, CGFloat(component.count) / CGFloat(premiumLimit))
|
||||||
|
}
|
||||||
|
badgePosition = max(0.15, CGFloat(component.count) / CGFloat(premiumLimit))
|
||||||
|
|
||||||
|
if isPremiumDisabled {
|
||||||
|
badgeText = "\(limit)"
|
||||||
|
string = strings.Premium_MaxChannelsNoPremiumText("\(limit)").string
|
||||||
|
}
|
||||||
case .linksPerSharedFolder:
|
case .linksPerSharedFolder:
|
||||||
/*let count: Int32 = 5 + Int32("".count)// component.count
|
/*let count: Int32 = 5 + Int32("".count)// component.count
|
||||||
let limit: Int32 = 5 + Int32("".count)//state.limits.maxSharedFolderInviteLinks
|
let limit: Int32 = 5 + Int32("".count)//state.limits.maxSharedFolderInviteLinks
|
||||||
@ -991,10 +1010,7 @@ private final class LimitSheetContent: CombinedComponent {
|
|||||||
gloss: isIncreaseButton,
|
gloss: isIncreaseButton,
|
||||||
animationName: isIncreaseButton ? buttonAnimationName : nil,
|
animationName: isIncreaseButton ? buttonAnimationName : nil,
|
||||||
iconPosition: .right,
|
iconPosition: .right,
|
||||||
action: { [weak component] in
|
action: {
|
||||||
guard let component = component else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
component.dismiss()
|
component.dismiss()
|
||||||
if isIncreaseButton {
|
if isIncreaseButton {
|
||||||
component.action()
|
component.action()
|
||||||
@ -1133,6 +1149,7 @@ public class PremiumLimitScreen: ViewControllerComponentContainer {
|
|||||||
case accounts
|
case accounts
|
||||||
case linksPerSharedFolder
|
case linksPerSharedFolder
|
||||||
case membershipInSharedFolders
|
case membershipInSharedFolders
|
||||||
|
case channels
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(context: AccountContext, subject: PremiumLimitScreen.Subject, count: Int32, action: @escaping () -> Void) {
|
public init(context: AccountContext, subject: PremiumLimitScreen.Subject, count: Int32, action: @escaping () -> Void) {
|
||||||
|
@ -32,6 +32,8 @@ public enum ExportChatFolderError {
|
|||||||
case generic
|
case generic
|
||||||
case sharedFolderLimitExceeded(limit: Int32, premiumLimit: Int32)
|
case sharedFolderLimitExceeded(limit: Int32, premiumLimit: Int32)
|
||||||
case limitExceeded(limit: Int32, premiumLimit: Int32)
|
case limitExceeded(limit: Int32, premiumLimit: Int32)
|
||||||
|
case tooManyChannels(limit: Int32, premiumLimit: Int32)
|
||||||
|
case tooManyChannelsInAccount(limit: Int32, premiumLimit: Int32)
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ExportedChatFolderLink: Equatable {
|
public struct ExportedChatFolderLink: Equatable {
|
||||||
@ -94,6 +96,21 @@ func _internal_exportChatFolder(account: Account, filterId: Int32, title: String
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if error.errorDescription == "USER_CHANNELS_TOO_MUCH" || error.errorDescription == "CHANNELS_TOO_MUCH" {
|
||||||
|
return account.postbox.transaction { transaction -> (AppConfiguration, Bool) in
|
||||||
|
return (currentAppConfiguration(transaction: transaction), transaction.getPeer(account.peerId)?.isPremium ?? false)
|
||||||
|
}
|
||||||
|
|> castError(ExportChatFolderError.self)
|
||||||
|
|> mapToSignal { appConfiguration, isPremium -> Signal<Api.chatlists.ExportedChatlistInvite, ExportChatFolderError> in
|
||||||
|
let userDefaultLimits = UserLimitsConfiguration(appConfiguration: appConfiguration, isPremium: false)
|
||||||
|
let userPremiumLimits = UserLimitsConfiguration(appConfiguration: appConfiguration, isPremium: true)
|
||||||
|
|
||||||
|
if isPremium {
|
||||||
|
return .fail(.tooManyChannelsInAccount(limit: userPremiumLimits.maxFolderChatsCount, premiumLimit: userPremiumLimits.maxFolderChatsCount))
|
||||||
|
} else {
|
||||||
|
return .fail(.tooManyChannelsInAccount(limit: userDefaultLimits.maxFolderChatsCount, premiumLimit: userPremiumLimits.maxFolderChatsCount))
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
@ -391,6 +408,7 @@ public enum JoinChatFolderLinkError {
|
|||||||
case dialogFilterLimitExceeded(limit: Int32, premiumLimit: Int32)
|
case dialogFilterLimitExceeded(limit: Int32, premiumLimit: Int32)
|
||||||
case sharedFolderLimitExceeded(limit: Int32, premiumLimit: Int32)
|
case sharedFolderLimitExceeded(limit: Int32, premiumLimit: Int32)
|
||||||
case tooManyChannels(limit: Int32, premiumLimit: Int32)
|
case tooManyChannels(limit: Int32, premiumLimit: Int32)
|
||||||
|
case tooManyChannelsInAccount(limit: Int32, premiumLimit: Int32)
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class JoinChatFolderResult {
|
public final class JoinChatFolderResult {
|
||||||
@ -406,6 +424,25 @@ public final class JoinChatFolderResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func _internal_joinChatFolderLink(account: Account, slug: String, peerIds: [EnginePeer.Id]) -> Signal<JoinChatFolderResult, JoinChatFolderLinkError> {
|
func _internal_joinChatFolderLink(account: Account, slug: String, peerIds: [EnginePeer.Id]) -> Signal<JoinChatFolderResult, JoinChatFolderLinkError> {
|
||||||
|
/*#if DEBUG
|
||||||
|
if "".isEmpty {
|
||||||
|
return account.postbox.transaction { transaction -> (AppConfiguration, Bool) in
|
||||||
|
return (currentAppConfiguration(transaction: transaction), transaction.getPeer(account.peerId)?.isPremium ?? false)
|
||||||
|
}
|
||||||
|
|> castError(JoinChatFolderLinkError.self)
|
||||||
|
|> mapToSignal { appConfiguration, isPremium -> Signal<JoinChatFolderResult, JoinChatFolderLinkError> in
|
||||||
|
let userDefaultLimits = UserLimitsConfiguration(appConfiguration: appConfiguration, isPremium: false)
|
||||||
|
let userPremiumLimits = UserLimitsConfiguration(appConfiguration: appConfiguration, isPremium: true)
|
||||||
|
|
||||||
|
if isPremium {
|
||||||
|
return .fail(.tooManyChannelsInAccount(limit: userPremiumLimits.maxFolderChatsCount, premiumLimit: userPremiumLimits.maxFolderChatsCount))
|
||||||
|
} else {
|
||||||
|
return .fail(.tooManyChannelsInAccount(limit: userDefaultLimits.maxFolderChatsCount, premiumLimit: userPremiumLimits.maxFolderChatsCount))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif*/
|
||||||
|
|
||||||
return account.postbox.transaction { transaction -> ([Api.InputPeer], Int) in
|
return account.postbox.transaction { transaction -> ([Api.InputPeer], Int) in
|
||||||
var newChatCount = 0
|
var newChatCount = 0
|
||||||
for peerId in peerIds {
|
for peerId in peerIds {
|
||||||
@ -476,6 +513,21 @@ func _internal_joinChatFolderLink(account: Account, slug: String, peerIds: [Engi
|
|||||||
return .fail(.sharedFolderLimitExceeded(limit: userDefaultLimits.maxSharedFolderJoin, premiumLimit: userPremiumLimits.maxSharedFolderJoin))
|
return .fail(.sharedFolderLimitExceeded(limit: userDefaultLimits.maxSharedFolderJoin, premiumLimit: userPremiumLimits.maxSharedFolderJoin))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if error.errorDescription == "CHANNELS_TOO_MUCH" {
|
||||||
|
return account.postbox.transaction { transaction -> (AppConfiguration, Bool) in
|
||||||
|
return (currentAppConfiguration(transaction: transaction), transaction.getPeer(account.peerId)?.isPremium ?? false)
|
||||||
|
}
|
||||||
|
|> castError(JoinChatFolderLinkError.self)
|
||||||
|
|> mapToSignal { appConfiguration, isPremium -> Signal<Api.Updates, JoinChatFolderLinkError> in
|
||||||
|
let userDefaultLimits = UserLimitsConfiguration(appConfiguration: appConfiguration, isPremium: false)
|
||||||
|
let userPremiumLimits = UserLimitsConfiguration(appConfiguration: appConfiguration, isPremium: true)
|
||||||
|
|
||||||
|
if isPremium {
|
||||||
|
return .fail(.tooManyChannelsInAccount(limit: userPremiumLimits.maxSharedFolderJoin, premiumLimit: userPremiumLimits.maxSharedFolderJoin))
|
||||||
|
} else {
|
||||||
|
return .fail(.tooManyChannelsInAccount(limit: userDefaultLimits.maxSharedFolderJoin, premiumLimit: userPremiumLimits.maxSharedFolderJoin))
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
|
@ -1159,19 +1159,46 @@ private final class ChatFolderLinkPreviewScreenComponent: Component {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let context = component.context
|
||||||
|
let navigationController = controller.navigationController as? NavigationController
|
||||||
|
|
||||||
switch error {
|
switch error {
|
||||||
case .generic:
|
case .generic:
|
||||||
controller.dismiss()
|
controller.dismiss()
|
||||||
case let .dialogFilterLimitExceeded(limit, _):
|
case let .dialogFilterLimitExceeded(limit, _):
|
||||||
let limitController = PremiumLimitScreen(context: component.context, subject: .folders, count: limit, action: {})
|
let limitController = PremiumLimitScreen(context: component.context, subject: .folders, count: limit, action: { [weak navigationController] in
|
||||||
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigationController.pushViewController(PremiumIntroScreen(context: context, source: .folders))
|
||||||
|
})
|
||||||
controller.push(limitController)
|
controller.push(limitController)
|
||||||
controller.dismiss()
|
controller.dismiss()
|
||||||
case let .sharedFolderLimitExceeded(limit, _):
|
case let .sharedFolderLimitExceeded(limit, _):
|
||||||
let limitController = PremiumLimitScreen(context: component.context, subject: .membershipInSharedFolders, count: limit, action: {})
|
let limitController = PremiumLimitScreen(context: component.context, subject: .membershipInSharedFolders, count: limit, action: { [weak navigationController] in
|
||||||
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigationController.pushViewController(PremiumIntroScreen(context: context, source: .membershipInSharedFolders))
|
||||||
|
})
|
||||||
controller.push(limitController)
|
controller.push(limitController)
|
||||||
controller.dismiss()
|
controller.dismiss()
|
||||||
case let .tooManyChannels(limit, _):
|
case let .tooManyChannels(limit, _):
|
||||||
let limitController = PremiumLimitScreen(context: component.context, subject: .chatsPerFolder, count: limit, action: {})
|
let limitController = PremiumLimitScreen(context: component.context, subject: .chatsPerFolder, count: limit, action: { [weak navigationController] in
|
||||||
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigationController.pushViewController(PremiumIntroScreen(context: component.context, source: .chatsPerFolder))
|
||||||
|
})
|
||||||
|
controller.push(limitController)
|
||||||
|
controller.dismiss()
|
||||||
|
case let .tooManyChannelsInAccount(limit, _):
|
||||||
|
let limitController = PremiumLimitScreen(context: component.context, subject: .channels, count: limit, action: { [weak navigationController] in
|
||||||
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigationController.pushViewController(PremiumIntroScreen(context: component.context, source: .groupsAndChannels))
|
||||||
|
})
|
||||||
controller.push(limitController)
|
controller.push(limitController)
|
||||||
controller.dismiss()
|
controller.dismiss()
|
||||||
}
|
}
|
||||||
@ -1391,23 +1418,56 @@ private final class ChatFolderLinkPreviewScreenComponent: Component {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let context = component.context
|
||||||
|
let navigationController = controller.navigationController as? NavigationController
|
||||||
|
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
let text: String
|
let text: String
|
||||||
switch error {
|
switch error {
|
||||||
case .generic:
|
case .generic:
|
||||||
text = "An error occurred"
|
text = "An error occurred"
|
||||||
case let .sharedFolderLimitExceeded(limit, _):
|
case let .sharedFolderLimitExceeded(limit, _):
|
||||||
let limitController = component.context.sharedContext.makePremiumLimitController(context: component.context, subject: .membershipInSharedFolders, count: limit, action: {
|
let limitController = component.context.sharedContext.makePremiumLimitController(context: component.context, subject: .membershipInSharedFolders, count: limit, action: { [weak navigationController] in
|
||||||
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigationController.pushViewController(PremiumIntroScreen(context: context, source: .membershipInSharedFolders))
|
||||||
})
|
})
|
||||||
|
|
||||||
controller.push(limitController)
|
controller.push(limitController)
|
||||||
|
|
||||||
return
|
return
|
||||||
case let .limitExceeded(limit, _):
|
case let .limitExceeded(limit, _):
|
||||||
let limitController = component.context.sharedContext.makePremiumLimitController(context: component.context, subject: .linksPerSharedFolder, count: limit, action: {
|
let limitController = component.context.sharedContext.makePremiumLimitController(context: component.context, subject: .linksPerSharedFolder, count: limit, action: { [weak navigationController] in
|
||||||
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigationController.pushViewController(PremiumIntroScreen(context: component.context, source: .linksPerSharedFolder))
|
||||||
})
|
})
|
||||||
controller.push(limitController)
|
controller.push(limitController)
|
||||||
|
|
||||||
|
return
|
||||||
|
case let .tooManyChannels(limit, _):
|
||||||
|
let limitController = PremiumLimitScreen(context: component.context, subject: .chatsPerFolder, count: limit, action: { [weak navigationController] in
|
||||||
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigationController.pushViewController(PremiumIntroScreen(context: component.context, source: .chatsPerFolder))
|
||||||
|
})
|
||||||
|
controller.push(limitController)
|
||||||
|
controller.dismiss()
|
||||||
|
|
||||||
|
return
|
||||||
|
case let .tooManyChannelsInAccount(limit, _):
|
||||||
|
let limitController = PremiumLimitScreen(context: component.context, subject: .channels, count: limit, action: { [weak navigationController] in
|
||||||
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigationController.pushViewController(PremiumIntroScreen(context: component.context, source: .groupsAndChannels))
|
||||||
|
})
|
||||||
|
controller.push(limitController)
|
||||||
|
controller.dismiss()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
@ -1680,6 +1680,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
mappedSubject = .linksPerSharedFolder
|
mappedSubject = .linksPerSharedFolder
|
||||||
case .membershipInSharedFolders:
|
case .membershipInSharedFolders:
|
||||||
mappedSubject = .membershipInSharedFolders
|
mappedSubject = .membershipInSharedFolders
|
||||||
|
case .channels:
|
||||||
|
mappedSubject = .channels
|
||||||
}
|
}
|
||||||
return PremiumLimitScreen(context: context, subject: mappedSubject, count: count, action: action)
|
return PremiumLimitScreen(context: context, subject: mappedSubject, count: count, action: action)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user