From ef3b593aa60b6f30e7dd1c08ce5d22094a9c53ea Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Fri, 29 Nov 2024 21:46:10 +0400 Subject: [PATCH] Fix ref duration --- .../TelegramEngine/Messages/BotWebView.swift | 12 +++ .../Sources/AffiliateProgramSetupScreen.swift | 94 ++++++++++--------- .../Sources/JoinAffiliateProgramScreen.swift | 4 +- .../Sources/PeerInfoScreen.swift | 10 +- .../Sources/StarsTransactionScreen.swift | 4 +- 5 files changed, 69 insertions(+), 55 deletions(-) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/BotWebView.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/BotWebView.swift index e6b91b533b..d06d6be08e 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/BotWebView.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/BotWebView.swift @@ -589,6 +589,18 @@ func _internal_removeChatManagingBot(account: Account, chatId: EnginePeer.Id) -> } } +public func formatPermille(_ value: Int32) -> String { + return formatPermille(Int(value)) +} + +public func formatPermille(_ value: Int) -> String { + if value % 10 == 0 { + return "\(value / 10)" + } else { + return String(format: "%.1f", Double(value) / 10.0) + } +} + func _internal_updateStarRefProgram(account: Account, id: EnginePeer.Id, program: (commissionPermille: Int32, durationMonths: Int32?)?) -> Signal { return account.postbox.transaction { transaction -> Api.InputUser? in return transaction.getPeer(id).flatMap(apiInputUser) diff --git a/submodules/TelegramUI/Components/PeerInfo/AffiliateProgramSetupScreen/Sources/AffiliateProgramSetupScreen.swift b/submodules/TelegramUI/Components/PeerInfo/AffiliateProgramSetupScreen/Sources/AffiliateProgramSetupScreen.swift index 336edf35e5..706176a9a7 100644 --- a/submodules/TelegramUI/Components/PeerInfo/AffiliateProgramSetupScreen/Sources/AffiliateProgramSetupScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/AffiliateProgramSetupScreen/Sources/AffiliateProgramSetupScreen.swift @@ -176,10 +176,10 @@ final class AffiliateProgramSetupScreenComponent: Component { let programPermille: Int32 = Int32(self.commissionPermille) let programDuration: Int32? = self.durationValue == Int(Int32.max) ? nil : Int32(self.durationValue) - let commissionTitle: String = "\(programPermille / 10)%" + let commissionTitle: String = "\(formatPermille(programPermille))%" let durationTitle: String if let durationMonths = programDuration { - durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (24 * 60 * 60)) + durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (30 * 24 * 60 * 60)) } else { durationTitle = "Lifetime" } @@ -378,7 +378,7 @@ If you end your affiliate program: } UIPasteboard.general.string = bot.url let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }) - self.environment?.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(bot.commissionPermille / 10)%** of what people who use it spend in **\(bot.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + self.environment?.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(formatPermille(bot.commissionPermille))%** of what people who use it spend in **\(bot.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) } )) )) @@ -557,13 +557,15 @@ If you end your affiliate program: self.commissionPermille = 10 self.commissionSliderValue = 0.0 self.commissionMinPermille = 10 - self.durationValue = 10 + self.durationValue = 1 + self.durationMinValue = 0 } } else { self.commissionPermille = 10 self.commissionSliderValue = 0.0 self.commissionMinPermille = 10 - self.durationValue = 10 + self.durationValue = 1 + self.durationMinValue = 0 } case .connectedPrograms: self.connectedStarBotListDisposable = (component.context.engine.peers.requestConnectedStarRefBots( @@ -875,7 +877,7 @@ If you end your affiliate program: minValue: commissionMinSliderValue, lowerBoundTitle: "1%", upperBoundTitle: "90%", - title: "\(self.commissionPermille / 10)%", + title: "\(formatPermille(self.commissionPermille))%", valueUpdated: { [weak self] value in guard let self else { return @@ -1183,11 +1185,11 @@ If you end your affiliate program: for item in connectedStarBotList.items { let durationTitle: String if let durationMonths = item.durationMonths { - durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (24 * 60 * 60)) + durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (30 * 24 * 60 * 60)) } else { durationTitle = "Lifetime" } - let commissionTitle = "\(item.commissionPermille / 10)%" + let commissionTitle = "\(formatPermille(item.commissionPermille))%" let itemContextAction: (EnginePeer, ContextExtractedContentContainingView, ContextGesture?) -> Void = { [weak self] peer, sourceView, gesture in guard let self, let component = self.component, let environment = self.environment else { @@ -1249,7 +1251,7 @@ If you end your affiliate program: let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }) UIPasteboard.general.string = item.url - environment.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(item.commissionPermille / 10)%** of what people who use it spend in **\(item.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + environment.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(formatPermille(item.commissionPermille))%** of what people who use it spend in **\(item.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) }))) itemList.append(.action(ContextMenuActionItem(text: "Leave", textColor: .destructive, icon: { theme in @@ -1364,17 +1366,21 @@ If you end your affiliate program: do { var suggestedSectionItems: [AnyComponentWithIdentity] = [] if suggestedStarBotListItems.isEmpty { - suggestedSectionItems.append(AnyComponentWithIdentity(id: "empty", component: AnyComponent(TransformContents( - content: AnyComponent(), - fixedSize: CGSize(width: 1.0, height: 100.0), - translation: CGPoint() - )))) + suggestedSectionItems.append(AnyComponentWithIdentity(id: "empty", component: AnyComponent(ZStack([ + AnyComponentWithIdentity(id: 0, component: AnyComponent(Rectangle(color: .clear, width: nil, height: 100.0))), + AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString(string: "No available programs yet.\nPlease check the page later.", font: Font.regular(15.0), textColor: environment.theme.list.itemSecondaryTextColor)), + horizontalAlignment: .center, + maximumNumberOfLines: 0, + lineSpacing: 0.2 + ))) + ])))) } for item in suggestedStarBotListItems { - let commissionTitle = "\(item.program.commissionPermille / 10)%" + let commissionTitle = "\(formatPermille(item.program.commissionPermille))%" let durationTitle: String if let durationMonths = item.program.durationMonths { - durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (24 * 60 * 60)) + durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (30 * 24 * 60 * 60)) } else { durationTitle = "Lifetime" } @@ -1467,31 +1473,34 @@ If you end your affiliate program: )))) } + var suggestedHeaderItems: [AnyComponentWithIdentity] = [] + suggestedHeaderItems.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString( + string: "PROGRAMS", + font: Font.regular(13.0), + textColor: environment.theme.list.freeTextColor + )), + maximumNumberOfLines: 0 + )))) + if suggestedStarBotListItems.count > 1 { + suggestedHeaderItems.append(AnyComponentWithIdentity(id: 1, component: AnyComponent(BotSectionSortButtonComponent( + theme: environment.theme, + strings: environment.strings, + sortMode: self.suggestedSortMode, + action: { [weak self] sourceView in + guard let self else { + return + } + self.openSortModeMenu(sourceView: sourceView) + } + )))) + } + let suggestedProgramsSectionSize = self.suggestedProgramsSection.update( transition: transition, component: AnyComponent(ListSectionComponent( theme: environment.theme, - header: AnyComponent(HStack([ - AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString( - string: "PROGRAMS", - font: Font.regular(13.0), - textColor: environment.theme.list.freeTextColor - )), - maximumNumberOfLines: 0 - ))), - AnyComponentWithIdentity(id: 1, component: AnyComponent(BotSectionSortButtonComponent( - theme: environment.theme, - strings: environment.strings, - sortMode: self.suggestedSortMode, - action: { [weak self] sourceView in - guard let self else { - return - } - self.openSortModeMenu(sourceView: sourceView) - } - ))) - ], spacing: 4.0, alignment: .alternatingLeftRight)), + header: AnyComponent(HStack(suggestedHeaderItems, spacing: 4.0, alignment: .alternatingLeftRight)), footer: nil, items: suggestedSectionItems, displaySeparators: true @@ -1506,19 +1515,12 @@ If you end your affiliate program: self.scrollView.addSubview(suggestedProgramsSectionView) } transition.setFrame(view: suggestedProgramsSectionView, frame: suggestedProgramsSectionFrame) - if !suggestedStarBotListItems.isEmpty { - suggestedProgramsSectionView.isHidden = false - } else { - suggestedProgramsSectionView.isHidden = true - } suggestedProgramsSectionView.contentViewImpl.alpha = self.isSuggestedSortModeUpdating ? 0.6 : 1.0 suggestedProgramsSectionView.contentViewImpl.isUserInteractionEnabled = !self.isSuggestedSortModeUpdating } - if !suggestedStarBotListItems.isEmpty { - contentHeight += suggestedProgramsSectionSize.height - contentHeight += sectionSpacing - } + contentHeight += suggestedProgramsSectionSize.height + contentHeight += sectionSpacing } } } diff --git a/submodules/TelegramUI/Components/PeerInfo/AffiliateProgramSetupScreen/Sources/JoinAffiliateProgramScreen.swift b/submodules/TelegramUI/Components/PeerInfo/AffiliateProgramSetupScreen/Sources/JoinAffiliateProgramScreen.swift index f4d73d1ec1..d1cd6b84fe 100644 --- a/submodules/TelegramUI/Components/PeerInfo/AffiliateProgramSetupScreen/Sources/JoinAffiliateProgramScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/AffiliateProgramSetupScreen/Sources/JoinAffiliateProgramScreen.swift @@ -637,7 +637,7 @@ private final class JoinAffiliateProgramScreenComponent: Component { )) ), AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: "\(component.commissionPermille / 10)%", font: Font.regular(13.0), textColor: environment.theme.list.itemCheckColors.foregroundColor)) + text: .plain(NSAttributedString(string: "\(formatPermille(component.commissionPermille))%", font: Font.regular(13.0), textColor: environment.theme.list.itemCheckColors.foregroundColor)) ))) ], spacing: 2.0)), insets: UIEdgeInsets(top: 3.0, left: 6.0, bottom: 3.0, right: 6.0), @@ -766,7 +766,7 @@ private final class JoinAffiliateProgramScreenComponent: Component { contentHeight += linkIconBackgroundSize.height + 21.0 } - let commissionTitle = "\(component.commissionPermille / 10)%" + let commissionTitle = "\(formatPermille(component.commissionPermille))%" let durationTitle: String if let durationMonths = component.programDuration { durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (24 * 60 * 60)) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index e52670617e..c43f77025f 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -1445,12 +1445,12 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese } //TODO:localize let programTitleValue: String - programTitleValue = "\(starRefProgram.commissionPermille / 10)%" + programTitleValue = "\(formatPermille(starRefProgram.commissionPermille))%" //TODO:localize items[.botAffiliateProgram]!.append(PeerInfoScreenDisclosureItem(id: 0, label: .labelBadge(programTitleValue), additionalBadgeLabel: nil, text: "Affiliate Program", icon: PresentationResourcesSettings.affiliateProgram, action: { interaction.editingOpenAffiliateProgram() })) - items[.botAffiliateProgram]!.append(PeerInfoScreenCommentItem(id: 1, text: "Share a link to \(EnginePeer.user(user).compactDisplayTitle) with your friends and and earn \(starRefProgram.commissionPermille / 10)% of their spending there.")) + items[.botAffiliateProgram]!.append(PeerInfoScreenCommentItem(id: 1, text: "Share a link to \(EnginePeer.user(user).compactDisplayTitle) with your friends and and earn \(formatPermille(starRefProgram.commissionPermille))% of their spending there.")) } } } @@ -1963,7 +1963,7 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL //TODO:localize let programTitleValue: PeerInfoScreenDisclosureItem.Label if let cachedData = data.cachedData as? CachedUserData, let starRefProgram = cachedData.starRefProgram, starRefProgram.endDate == nil { - programTitleValue = .labelBadge("\(starRefProgram.commissionPermille / 10)%") + programTitleValue = .labelBadge("\(formatPermille(starRefProgram.commissionPermille))%") } else { programTitleValue = .text("Off") } @@ -8662,7 +8662,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro //TODO:localize UIPasteboard.general.string = result.url let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 }) - self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(result.commissionPermille / 10)%** of what people who use it spend in **\(result.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(formatPermille(result.commissionPermille))%** of what people who use it spend in **\(result.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) } )) } else { @@ -8695,7 +8695,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } UIPasteboard.general.string = result.url let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 }) - self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(result.commissionPermille / 10)%** of what people who use it spend in **\(result.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(formatPermille(result.commissionPermille))%** of what people who use it spend in **\(result.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) } )) )) diff --git a/submodules/TelegramUI/Components/Stars/StarsTransactionScreen/Sources/StarsTransactionScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransactionScreen/Sources/StarsTransactionScreen.swift index 521978c68f..a37898c4ed 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransactionScreen/Sources/StarsTransactionScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransactionScreen/Sources/StarsTransactionScreen.swift @@ -407,7 +407,7 @@ private final class StarsTransactionSheetContent: CombinedComponent { //TODO:localize isRefProgram = true if transaction.starrefPeerId == nil { - titleText = "\(starrefCommissionPermille / 10)% Commission" + titleText = "\(formatPermille(starrefCommissionPermille))% Commission" } else { titleText = transaction.title ?? "Product" } @@ -987,7 +987,7 @@ private final class StarsTransactionSheetContent: CombinedComponent { tableItems.append(.init( id: "commission", title: "Commission", - component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "\(starrefCommissionPermille / 10)%", font: tableFont, textColor: tableTextColor)) + component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "\(formatPermille(starrefCommissionPermille))%", font: tableFont, textColor: tableTextColor)) )), insets: UIEdgeInsets(top: 0.0, left: 12.0, bottom: 0.0, right: 5.0) ))