mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-04 10:30:42 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
b8b0836d75
@ -13312,3 +13312,131 @@ Sorry for the inconvenience.";
|
||||
"MediaPicker.InvertCaption.Updated.Up.Text" = "Text will be shown above the media.";
|
||||
"MediaPicker.InvertCaption.Updated.Down.Title" = "Caption moved down";
|
||||
"MediaPicker.InvertCaption.Updated.Down.Text" = "Text will be shown below the media.";
|
||||
|
||||
"AffiliateSetup.AlertTerminate.Title" = "Warning";
|
||||
"AffiliateSetup.AlertTerminate.Text" = "If you end your affiliate program:\n\n• Any referral links already shared will be disabled in 24 hours.\n\n• All participating affiliates will be notified.\n\n• You will be able to start a new affiliate program only in 24 hours.";
|
||||
"AffiliateSetup.AlertTerminate.Action" = "End Anyway";
|
||||
"AffiliateSetup.AlertApply.Title" = "Warning";
|
||||
"AffiliateSetup.AlertApply.Text" = "Once you start the affiliate program, you won't be able to decrease its commission or duration. You can only increase these parameters or end the program, whuch will disable all previously distributed referral links.";
|
||||
"AffiliateSetup.AlertApply.SectionCommission" = "Commission";
|
||||
"AffiliateSetup.AlertApply.SectionDuration" = "Duration";
|
||||
"AffiliateSetup.AlertApply.Action" = "Start";
|
||||
|
||||
"AffiliateSetup.ToastTerminated.Title" = "Affiliate Program Ended";
|
||||
"AffiliateSetup.ToastTerminated.Text" = "Participating affiliates have been notified. All referral links will be disabled in 24 hours.";
|
||||
|
||||
"AffiliateSetup.SectionDuration" = "DURATION";
|
||||
"AffiliateSetup.SectionDurationFooter" = "Set the duration for which affiliates will earn commissions from referred users.";
|
||||
|
||||
"AffiliateSetup.SectionCommission" = "COMMISSION";
|
||||
"AffiliateSetup.SectionCommissionFooter" = "Define the percentage of star revenue your affiliates earn for referring users to your bot.";
|
||||
|
||||
"AffiliateSetup.ExistingPrograms.Action" = "View Existing Programs";
|
||||
"AffiliateSetup.ExistingPrograms.Footer" = "Explore what other mini apps offer.";
|
||||
|
||||
"AffiliateSetup.EndAction" = "End Affiliate Program";
|
||||
|
||||
"AffiliateSetup.StartTitle" = "Start Affiliate Program";
|
||||
"AffiliateSetup.UpdateTitle" = "Update Affiliate Program";
|
||||
|
||||
"AffiliateSetup.TermsFooter" = "By creating an affiliate program, you afree to the [terms and conditions](https://telegram.org/terms) of Affiliate Programs.";
|
||||
|
||||
"AffiliateSetup.ProgramMenu.OpenBot" = "Open Bot";
|
||||
"AffiliateSetup.ProgramMenu.OpenApp" = "Open App";
|
||||
"AffiliateSetup.ProgramMenu.CopyLink" = "Copy Link";
|
||||
"AffiliateSetup.ProgramMenu.Leave" = "Leave";
|
||||
"AffiliateSetup.ProgramLeave" = "Leave";
|
||||
|
||||
"AffiliateSetup.ConnectedSectionTitle" = "MY PROGRAMS";
|
||||
"AffiliateSetup.SuggestedSectionTitle" = "PROGRAMS";
|
||||
"AffiliateSetup.SuggestedSectionEmpty" = "No available programs yet.\nPlease check the page later.";
|
||||
|
||||
"AffiliateSetup.TitleNew" = "Affiliate Program";
|
||||
"AffiliateSetup.TextNew" = "Affiliate Program";
|
||||
"AffiliateSetup.TitleJoin" = "Affiliate Programs";
|
||||
"AffiliateSetup.TextJoin" = "Earn a commission each time a user who first accessed a mini app through your referral link spends **Stars** within it.";
|
||||
|
||||
"AffiliateSetup.IntroNew.Title1" = "Share revenue with affiliates";
|
||||
"AffiliateSetup.IntroNew.Text1" = "Set the commission for revenue generated by users referred to you.";
|
||||
"AffiliateSetup.IntroNew.Title2" = "Launch your affiliate program";
|
||||
"AffiliateSetup.IntroNew.Text2" = "Telegram will feature your program for millions of potential affiliates.";
|
||||
"AffiliateSetup.IntroNew.Title3" = "Let affiliates promote you";
|
||||
"AffiliateSetup.IntroNew.Text3" = "Affiliates will share your referral link with their audience.";
|
||||
|
||||
"AffiliateSetup.IntroJoin.Title1" = "Reliable";
|
||||
"AffiliateSetup.IntroJoin.Text1" = "Receive guaranteed commissions for spending by users you refer.";
|
||||
"AffiliateSetup.IntroJoin.Title2" = "Transparent";
|
||||
"AffiliateSetup.IntroJoin.Text2" = "Track your commissions from referred users in real time.";
|
||||
"AffiliateSetup.IntroJoin.Title3" = "Simple";
|
||||
"AffiliateSetup.IntroJoin.Text3" = "Choose a mini app below, get your referral link, and start earning Stars.";
|
||||
|
||||
"AffiliateProgram.ToastLinkCopied.Title" = "Link copied to clipboard";
|
||||
"AffiliateProgram.ToastLinkCopied.Text" = "Share this link and earn **%1$@** of what people who use it spend in **%2$@!";
|
||||
|
||||
"AffiliateProgram.DurationLifetime" = "Lifetime";
|
||||
|
||||
"AffiliateProgram.SortSelectorProfitability" = "Profitability";
|
||||
"AffiliateProgram.SortSelectorRevenue" = "Revenue";
|
||||
"AffiliateProgram.SortSelectorDate" = "Date";
|
||||
|
||||
"AffiliateProgram.ValueShortMonths_1" = "%@m";
|
||||
"AffiliateProgram.ValueShortMonths_any" = "%@m";
|
||||
"AffiliateProgram.ValueShortYears_1" = "%@y";
|
||||
"AffiliateProgram.ValueShortYears_any" = "%@y";
|
||||
|
||||
"AffiliateProgram.ValueLongMonths_1" = "%@ MONTH";
|
||||
"AffiliateProgram.ValueLongMonths_any" = "%@ MONTHS";
|
||||
"AffiliateProgram.ValueLongYears_1" = "%@ YEAR";
|
||||
"AffiliateProgram.ValueLongYears_any" = "%@ YEARS";
|
||||
|
||||
"AffiliateProgram.PeerTypeSelf" = "personal account";
|
||||
|
||||
"AffiliateProgram.JoinTitle" = "Affiliate Program";
|
||||
"AffiliateProgram.JoinTerms" = "By joining this program, you afree to the [terms and conditions](https://telegram.org/terms) of Affiliate Programs.";
|
||||
"AffiliateProgram.DailyRevenueText" = "The average daily revenue per user: #**%@**";
|
||||
|
||||
"AffiliateProgram.LinkTitle" = "Referral Link";
|
||||
"AffiliateProgram.LinkSubtitleLifetime" = "Share this link with your users to earn a **{commission}** commission on their spending in **{bot}** **forever** after they follow your link.";
|
||||
"AffiliateProgram.LinkSubtitleMonths_1" = "Share this link with your users to earn a **{commission}** commission on their spending in **{bot}** for **1 month** after they follow your link.";
|
||||
"AffiliateProgram.LinkSubtitleMonths_any" = "Share this link with your users to earn a **{commission}** commission on their spending in **{bot}** for **%d months** after they follow your link.";
|
||||
"AffiliateProgram.LinkSubtitleYears_1" = "Share this link with your users to earn a **{commission}** commission on their spending in **{bot}** for **1 year** after they follow your link.";
|
||||
"AffiliateProgram.LinkSubtitleYears_any" = "Share this link with your users to earn a **{commission}** commission on their spending in **{bot}** for **%d years** after they follow your link.";
|
||||
|
||||
"AffiliateProgram.JoinSubtitleLifetime" = "**{bot}** will share **{commission}** of the revenue from each user you refer to it **forever**.";
|
||||
"AffiliateProgram.JoinSubtitleMonths_1" = "**{bot}** will share **{commission}** of the revenue from each user you refer to it for **1 month.**";
|
||||
"AffiliateProgram.JoinSubtitleMonths_any" = "**{bot}** will share **{commission}** of the revenue from each user you refer to it for **%d months.**";
|
||||
"AffiliateProgram.JoinSubtitleYears_1" = "**{bot}** will share **{commission}** of the revenue from each user you refer to it for **1 month.**";
|
||||
"AffiliateProgram.JoinSubtitleYears_any" = "**{bot}** will share **{commission}** of the revenue from each user you refer to it for **%d months.**";
|
||||
|
||||
"AffiliateProgram.CommistionDestinationText" = "Commission will be sent to:";
|
||||
|
||||
"AffiliateProgram.ActionJoin" = "Join Program";
|
||||
"AffiliateProgram.ActionCopyLink" = "Copy Link";
|
||||
|
||||
"AffiliateProgram.ToastJoined.Title" = "Program joined";
|
||||
"AffiliateProgram.ToastJoined.Text" = "You can now copy the referral link.";
|
||||
|
||||
"AffiliateSetup.SortSectionHeader.Date" = "SORT BY [DATE]()";
|
||||
"AffiliateSetup.SortSectionHeader.Profitability" = "SORT BY [PROFITABILITY]()";
|
||||
"AffiliateSetup.SortSectionHeader.Revenue" = "SORT BY [REVENUE]()";
|
||||
|
||||
"AffiliateProgram.UserCountFooter_0" = "No one opened {bot} through this link yet.";
|
||||
"AffiliateProgram.UserCountFooter_1" = "1 user opened {bot} through this link.";
|
||||
"AffiliateProgram.UserCountFooter_any" = "%d users opened {bot} through this link.";
|
||||
|
||||
"ChatList.InlineButtonOpenApp" = "OPEN";
|
||||
|
||||
"Monetization.EarnStarsInfo.Title" = "Earn Stars";
|
||||
"Monetization.EarnStarsInfo.Text" = "Distribute links to mini apps and earn a share of their revenue in Stars.";
|
||||
|
||||
"PeerInfo.ItemAffiliateProgram.Title" = "Affiliate Program";
|
||||
"PeerInfo.ItemAffiliatePrograms.Title" = "Affiliate Programs";
|
||||
"PeerInfo.ItemAffiliateProgram.Footer" = "Share a link to %1$@ with your friends and and earn %2$@% of their spending there.";
|
||||
"PeerInfo.ItemAffiliateProgram.ValueOff" = "Off";
|
||||
|
||||
"StarsTransaction.TitleCommission" = "%@% Commission";
|
||||
"StarsTransaction.StarRefReason.Title" = "Reason";
|
||||
"StarsTransaction.StarRefReason.Program" = "Affiliate Program";
|
||||
"StarsTransaction.StarRefReason.Miniapp" = "Mini App";
|
||||
"StarsTransaction.StarRefReason.Affiliate" = "Affiliate";
|
||||
"StarsTransaction.StarRefReason.Referred" = "Referred User";
|
||||
|
@ -1186,7 +1186,6 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
//TODO:localize
|
||||
self.context.sharedContext.openWebApp(
|
||||
context: self.context,
|
||||
parentController: self,
|
||||
|
@ -3098,8 +3098,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
var actionButtonTitleNodeLayoutAndApply: (TextNodeLayout, () -> TextNode)?
|
||||
if case .none = badgeContent, case .none = mentionBadgeContent, case let .chat(itemPeer) = contentPeer, case let .user(user) = itemPeer.chatMainPeer, let botInfo = user.botInfo, botInfo.flags.contains(.hasWebApp) {
|
||||
//TODO:localize
|
||||
actionButtonTitleNodeLayoutAndApply = makeActionButtonTitleNodeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "OPEN", font: Font.semibold(15.0), textColor: theme.unreadBadgeActiveTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: rawContentWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
actionButtonTitleNodeLayoutAndApply = makeActionButtonTitleNodeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.ChatList_InlineButtonOpenApp, font: Font.semibold(15.0), textColor: theme.unreadBadgeActiveTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: rawContentWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
}
|
||||
|
||||
var badgeSize: CGFloat = 0.0
|
||||
|
@ -1219,8 +1219,7 @@ private enum StatsEntry: ItemListNodeEntry {
|
||||
arguments.presentCpmLocked()
|
||||
})
|
||||
case .earnStarsInfo:
|
||||
//TODO:localize
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: PresentationResourcesSettings.earnStars, title: "Earn Stars", titleBadge: presentationData.strings.Settings_New, label: "Distribute links to mini apps and earn a share of their revenue in Stars.", labelStyle: .multilineDetailText, sectionId: self.section, style: .blocks, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: PresentationResourcesSettings.earnStars, title: presentationData.strings.Monetization_EarnStarsInfo_Title, titleBadge: presentationData.strings.Settings_New, label: presentationData.strings.Monetization_EarnStarsInfo_Text, labelStyle: .multilineDetailText, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openEarnStars()
|
||||
})
|
||||
}
|
||||
@ -1702,7 +1701,6 @@ private func monetizationEntries(
|
||||
if displayStarsTransactions {
|
||||
if !addedTransactionsTabs {
|
||||
if canJoinRefPrograms {
|
||||
//TODO:localize
|
||||
entries.append(.earnStarsInfo)
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,23 @@ private func textForTimeout(value: Int32) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
private func textForDurationMonths(strings: PresentationStrings, value: Int) -> (short: String, full: String) {
|
||||
if value >= Int(Int32.max) {
|
||||
return ("∞", strings.AffiliateProgram_DurationLifetime.uppercased())
|
||||
}
|
||||
if value > 12 {
|
||||
return (
|
||||
strings.AffiliateProgram_ValueShortYears(Int32(value / 12)),
|
||||
strings.AffiliateProgram_ValueLongYears(Int32(value / 12))
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
strings.AffiliateProgram_ValueShortMonths(Int32(value)),
|
||||
strings.AffiliateProgram_ValueLongMonths(Int32(value))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
final class AffiliateProgramSetupScreenComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
@ -181,25 +198,25 @@ final class AffiliateProgramSetupScreenComponent: Component {
|
||||
if let durationMonths = programDuration {
|
||||
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (30 * 24 * 60 * 60))
|
||||
} else {
|
||||
durationTitle = "Lifetime"
|
||||
durationTitle = environment.strings.AffiliateProgram_DurationLifetime
|
||||
}
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 })
|
||||
self.environment?.controller()?.present(tableAlert(
|
||||
theme: presentationData.theme,
|
||||
title: "Warning",
|
||||
text: "Once you start the affiliate program, you won't be able to decrease its commission or duration. You can only increase these parameters or end the program, whuch will disable all previously distributed referral links.",
|
||||
title: environment.strings.AffiliateSetup_AlertApply_Title,
|
||||
text: environment.strings.AffiliateSetup_AlertApply_Text,
|
||||
table: TableComponent(theme: environment.theme, items: [
|
||||
TableComponent.Item(id: 0, title: "Commission", component: AnyComponent(MultilineTextComponent(
|
||||
TableComponent.Item(id: 0, title: environment.strings.AffiliateSetup_AlertApply_SectionCommission, component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: commissionTitle, font: Font.regular(17.0), textColor: environment.theme.actionSheet.primaryTextColor))
|
||||
))),
|
||||
TableComponent.Item(id: 1, title: "Duration", component: AnyComponent(MultilineTextComponent(
|
||||
TableComponent.Item(id: 1, title: environment.strings.AffiliateSetup_AlertApply_SectionDuration, component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: durationTitle, font: Font.regular(17.0), textColor: environment.theme.actionSheet.primaryTextColor))
|
||||
)))
|
||||
]),
|
||||
actions: [
|
||||
ComponentAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}),
|
||||
ComponentAlertAction(type: .defaultAction, title: "Start", action: { [weak self] in
|
||||
ComponentAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {}),
|
||||
ComponentAlertAction(type: .defaultAction, title: environment.strings.AffiliateSetup_AlertApply_Action, action: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -210,26 +227,17 @@ final class AffiliateProgramSetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
private func requestApplyEndProgram() {
|
||||
guard let component = self.component else {
|
||||
guard let component = self.component, let environment = self.environment else {
|
||||
return
|
||||
}
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 })
|
||||
self.environment?.controller()?.present(standardTextAlertController(
|
||||
theme: AlertControllerTheme(presentationData: presentationData),
|
||||
title: "Warning",
|
||||
text:
|
||||
"""
|
||||
If you end your affiliate program:
|
||||
|
||||
• Any referral links already shared will be disabled in 24 hours.
|
||||
|
||||
• All participating affiliates will be notified.
|
||||
|
||||
• You will be able to start a new affiliate program only in 24 hours.
|
||||
""",
|
||||
title: environment.strings.AffiliateSetup_AlertTerminate_Title,
|
||||
text: environment.strings.AffiliateSetup_AlertTerminate_Text,
|
||||
actions: [
|
||||
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}),
|
||||
TextAlertAction(type: .defaultDestructiveAction, title: "End Anyway", action: { [weak self] in
|
||||
TextAlertAction(type: .defaultDestructiveAction, title: environment.strings.AffiliateSetup_AlertTerminate_Action, action: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -291,7 +299,7 @@ If you end your affiliate program:
|
||||
program: nil
|
||||
)
|
||||
|> deliverOnMainQueue).startStrict(completed: { [weak self] in
|
||||
guard let self, let component = self.component, let controller = self.environment?.controller() else {
|
||||
guard let self, let component = self.component, let environment = self.environment, let controller = self.environment?.controller() else {
|
||||
return
|
||||
}
|
||||
self.isApplying = false
|
||||
@ -300,7 +308,7 @@ If you end your affiliate program:
|
||||
|
||||
if let navigationController = controller.navigationController, let index = navigationController.viewControllers.firstIndex(where: { $0 === controller }), index != 0 {
|
||||
if let previousController = navigationController.viewControllers[index - 1] as? ViewController {
|
||||
previousController.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_link_broken", scale: 0.065, colors: [:], title: "Affiliate Program Ended", text: "Participating affiliates have been notified. All referral links will be disabled in 24 hours.", customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
previousController.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_link_broken", scale: 0.065, colors: [:], title: environment.strings.AffiliateSetup_ToastTerminated_Title, text: environment.strings.AffiliateSetup_ToastTerminated_Text, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
}
|
||||
controller.dismiss()
|
||||
@ -378,7 +386,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 **\(formatPermille(bot.commissionPermille))%** 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: presentationData.strings.AffiliateProgram_ToastLinkCopied_Title, text: presentationData.strings.AffiliateProgram_ToastLinkCopied_Text(formatPermille(bot.commissionPermille), bot.peer.compactDisplayTitle).string), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
))
|
||||
))
|
||||
@ -417,9 +425,9 @@ If you end your affiliate program:
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
let availableModes: [(TelegramSuggestedStarRefBotList.SortMode, String)] = [
|
||||
(.profitability, "Profitability"),
|
||||
(.revenue, "Revenue"),
|
||||
(.date, "Date")
|
||||
(.profitability, environment.strings.AffiliateProgram_SortSelectorProfitability),
|
||||
(.revenue, environment.strings.AffiliateProgram_SortSelectorRevenue),
|
||||
(.date, environment.strings.AffiliateProgram_SortSelectorDate)
|
||||
]
|
||||
for (mode, title) in availableModes {
|
||||
let isSelected = mode == self.suggestedSortMode
|
||||
@ -483,14 +491,14 @@ If you end your affiliate program:
|
||||
self.isUpdating = false
|
||||
}
|
||||
|
||||
let durationItems: [(months: Int32, title: String, selectedTitle: String)] = [
|
||||
(1, "1m", "1 MONTH"),
|
||||
(3, "3m", "3 MONTHS"),
|
||||
(6, "6m", "6 MONTHS"),
|
||||
(12, "1y", "1 YEAR"),
|
||||
(2 * 12, "2y", "2 YEARS"),
|
||||
(3 * 12, "3y", "3 YEARS"),
|
||||
(Int32.max, "∞", "LIFETIME")
|
||||
let durationItems: [Int32] = [
|
||||
1,
|
||||
3,
|
||||
6,
|
||||
12,
|
||||
2 * 12,
|
||||
3 * 12,
|
||||
Int32.max
|
||||
]
|
||||
|
||||
let environment = environment[EnvironmentType.self].value
|
||||
@ -630,11 +638,11 @@ If you end your affiliate program:
|
||||
let subtitleValue: String
|
||||
switch component.initialContent.mode {
|
||||
case .editProgram:
|
||||
titleValue = "Affiliate Program"
|
||||
subtitleValue = "Reward those who help grow your userbase."
|
||||
titleValue = environment.strings.AffiliateSetup_TitleNew
|
||||
subtitleValue = environment.strings.AffiliateSetup_TextNew
|
||||
case .connectedPrograms:
|
||||
titleValue = "Affiliate Programs"
|
||||
subtitleValue = "Earn a commission each time a user who first accessed a mini app through your referral link spends **Stars** within it."
|
||||
titleValue = environment.strings.AffiliateSetup_TitleJoin
|
||||
subtitleValue = environment.strings.AffiliateSetup_TextJoin
|
||||
}
|
||||
let titleSize = self.title.update(
|
||||
transition: .immediate,
|
||||
@ -696,36 +704,36 @@ If you end your affiliate program:
|
||||
introItems = [
|
||||
(
|
||||
"Chat/Context Menu/Smile",
|
||||
"Share revenue with affiliates",
|
||||
"Set the commission for revenue generated by users referred to you."
|
||||
environment.strings.AffiliateSetup_IntroNew_Title1,
|
||||
environment.strings.AffiliateSetup_IntroNew_Text1
|
||||
),
|
||||
(
|
||||
"Chat/Context Menu/Channels",
|
||||
"Launch your affiliate program",
|
||||
"Telegram will feature your program for millions of potential affiliates."
|
||||
environment.strings.AffiliateSetup_IntroNew_Title2,
|
||||
environment.strings.AffiliateSetup_IntroNew_Text2
|
||||
),
|
||||
(
|
||||
"Chat/Context Menu/Link",
|
||||
"Let affiliates promote you",
|
||||
"Affiliates will share your referral link with their audience."
|
||||
environment.strings.AffiliateSetup_IntroNew_Title3,
|
||||
environment.strings.AffiliateSetup_IntroNew_Text3
|
||||
)
|
||||
]
|
||||
case .connectedPrograms:
|
||||
introItems = [
|
||||
(
|
||||
"Peer Info/RefProgram/IntroListSecure",
|
||||
"Reliable",
|
||||
"Receive guaranteed commissions for spending by users you refer."
|
||||
environment.strings.AffiliateSetup_IntroJoin_Title1,
|
||||
environment.strings.AffiliateSetup_IntroJoin_Text1
|
||||
),
|
||||
(
|
||||
"Peer Info/RefProgram/IntroListEye",
|
||||
"Transparent",
|
||||
"Track your commissions from referred users in real time."
|
||||
environment.strings.AffiliateSetup_IntroJoin_Title2,
|
||||
environment.strings.AffiliateSetup_IntroJoin_Text2
|
||||
),
|
||||
(
|
||||
"Peer Info/RefProgram/IntroListLike",
|
||||
"Simple",
|
||||
"Choose a mini app below, get your referral link, and start earning Stars."
|
||||
environment.strings.AffiliateSetup_IntroJoin_Title3,
|
||||
environment.strings.AffiliateSetup_IntroJoin_Text3
|
||||
)
|
||||
]
|
||||
}
|
||||
@ -855,7 +863,7 @@ If you end your affiliate program:
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "COMMISSION",
|
||||
string: environment.strings.AffiliateSetup_SectionCommission,
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -863,7 +871,7 @@ If you end your affiliate program:
|
||||
)),
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Define the percentage of star revenue your affiliates earn for referring users to your bot.",
|
||||
string: environment.strings.AffiliateSetup_SectionCommissionFooter,
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -911,10 +919,10 @@ If you end your affiliate program:
|
||||
var selectedDurationIndex = 0
|
||||
var durationMinValueIndex = 0
|
||||
for i in 0 ..< durationItems.count {
|
||||
if self.durationValue == Int(durationItems[i].months) {
|
||||
if self.durationValue == Int(durationItems[i]) {
|
||||
selectedDurationIndex = i
|
||||
}
|
||||
if self.durationMinValue == Int(durationItems[i].months) {
|
||||
if self.durationMinValue == Int(durationItems[i]) {
|
||||
durationMinValueIndex = i
|
||||
}
|
||||
}
|
||||
@ -925,7 +933,7 @@ If you end your affiliate program:
|
||||
header: AnyComponent(HStack([
|
||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "DURATION",
|
||||
string: environment.strings.AffiliateSetup_SectionDuration,
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -933,7 +941,7 @@ If you end your affiliate program:
|
||||
))),
|
||||
AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: durationItems[selectedDurationIndex].selectedTitle,
|
||||
string: textForDurationMonths(strings: environment.strings, value: Int(durationItems[selectedDurationIndex])).full,
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -942,7 +950,7 @@ If you end your affiliate program:
|
||||
], spacing: 4.0, alignment: .alternatingLeftRight)),
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Set the duration for which affiliates will earn commissions from referred users.",
|
||||
string: environment.strings.AffiliateSetup_SectionDurationFooter,
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -952,7 +960,9 @@ If you end your affiliate program:
|
||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListItemSliderSelectorComponent(
|
||||
theme: environment.theme,
|
||||
content: .discrete(ListItemSliderSelectorComponent.Discrete(
|
||||
values: durationItems.map(\.title),
|
||||
values: durationItems.map {
|
||||
textForDurationMonths(strings: environment.strings, value: Int($0)).short
|
||||
},
|
||||
markPositions: true,
|
||||
selectedIndex: max(durationMinValueIndex, selectedDurationIndex),
|
||||
minSelectedIndex: durationMinValueIndex,
|
||||
@ -961,7 +971,7 @@ If you end your affiliate program:
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.durationValue = Int(durationItems[value].months)
|
||||
self.durationValue = Int(durationItems[value])
|
||||
self.state?.updated(transition: .immediate)
|
||||
}
|
||||
))
|
||||
@ -990,7 +1000,7 @@ If you end your affiliate program:
|
||||
header: nil,
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Explore what other mini apps offer.",
|
||||
string: environment.strings.AffiliateSetup_ExistingPrograms_Footer,
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -1002,7 +1012,7 @@ If you end your affiliate program:
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "View Existing Programs",
|
||||
string: environment.strings.AffiliateSetup_ExistingPrograms_Action,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -1045,7 +1055,7 @@ If you end your affiliate program:
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "End Affiliate Program",
|
||||
string: environment.strings.AffiliateSetup_EndAction,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemDestructiveColor
|
||||
)),
|
||||
@ -1086,7 +1096,7 @@ If you end your affiliate program:
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .markdown(
|
||||
text: "By creating an affiliate program, you afree to the [terms and conditions](https://telegram.org/terms) of Affiliate Programs.",
|
||||
text: environment.strings.AffiliateSetup_TermsFooter,
|
||||
attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: Font.regular(13.0), textColor: environment.theme.list.itemSecondaryTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(13.0), textColor: environment.theme.list.itemSecondaryTextColor),
|
||||
@ -1111,9 +1121,9 @@ If you end your affiliate program:
|
||||
let remainingTime: Int32 = max(0, endDate - timestamp)
|
||||
buttonText = textForTimeout(value: remainingTime)
|
||||
} else if self.currentProgram != nil {
|
||||
buttonText = "Update Affiliate Program"
|
||||
buttonText = environment.strings.AffiliateSetup_UpdateTitle
|
||||
} else {
|
||||
buttonText = "Start Affiliate Program"
|
||||
buttonText = environment.strings.AffiliateSetup_StartTitle
|
||||
}
|
||||
let bottomPanelButtonSize = self.bottomPanelButton.update(
|
||||
transition: transition,
|
||||
@ -1187,7 +1197,7 @@ If you end your affiliate program:
|
||||
if let durationMonths = item.durationMonths {
|
||||
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (30 * 24 * 60 * 60))
|
||||
} else {
|
||||
durationTitle = "Lifetime"
|
||||
durationTitle = environment.strings.AffiliateProgram_DurationLifetime
|
||||
}
|
||||
let commissionTitle = "\(formatPermille(item.commissionPermille))%"
|
||||
|
||||
@ -1201,9 +1211,9 @@ If you end your affiliate program:
|
||||
|
||||
let openTitle: String
|
||||
if case let .user(user) = item.peer, let botInfo = user.botInfo, botInfo.flags.contains(.hasWebApp) {
|
||||
openTitle = "Open App"
|
||||
openTitle = environment.strings.AffiliateSetup_ProgramMenu_OpenApp
|
||||
} else {
|
||||
openTitle = "Open Bot"
|
||||
openTitle = environment.strings.AffiliateSetup_ProgramMenu_OpenBot
|
||||
}
|
||||
itemList.append(.action(ContextMenuActionItem(text: openTitle, textColor: .primary, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Bots"), color: theme.contextMenu.primaryColor)
|
||||
@ -1239,7 +1249,7 @@ If you end your affiliate program:
|
||||
})
|
||||
})))
|
||||
|
||||
itemList.append(.action(ContextMenuActionItem(text: "Copy Link", textColor: .primary, icon: { theme in
|
||||
itemList.append(.action(ContextMenuActionItem(text: environment.strings.AffiliateSetup_ProgramMenu_CopyLink, textColor: .primary, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
@ -1251,10 +1261,10 @@ 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 **\(formatPermille(item.commissionPermille))%** 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: environment.strings.AffiliateProgram_ToastLinkCopied_Title, text: environment.strings.AffiliateProgram_ToastLinkCopied_Text(formatPermille(item.commissionPermille), item.peer.compactDisplayTitle ).string), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
|
||||
itemList.append(.action(ContextMenuActionItem(text: "Leave", textColor: .destructive, icon: { theme in
|
||||
itemList.append(.action(ContextMenuActionItem(text: environment.strings.AffiliateSetup_ProgramMenu_Leave, textColor: .destructive, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor)
|
||||
}, action: { [weak self] c, _ in
|
||||
c?.dismiss(completion: {
|
||||
@ -1314,7 +1324,7 @@ If you end your affiliate program:
|
||||
self.openConnectedBot(bot: item)
|
||||
},
|
||||
inlineActions: PeerListItemComponent.InlineActionsState(actions: [
|
||||
PeerListItemComponent.InlineAction(id: 0, title: "Leave", color: .destructive, action: { [weak self] in
|
||||
PeerListItemComponent.InlineAction(id: 0, title: environment.strings.AffiliateSetup_ProgramLeave, color: .destructive, action: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -1333,7 +1343,7 @@ If you end your affiliate program:
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "MY PROGRAMS",
|
||||
string: environment.strings.AffiliateSetup_ConnectedSectionTitle,
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -1369,7 +1379,7 @@ If you end your affiliate program:
|
||||
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)),
|
||||
text: .plain(NSAttributedString(string: environment.strings.AffiliateSetup_SuggestedSectionEmpty, font: Font.regular(15.0), textColor: environment.theme.list.itemSecondaryTextColor)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2
|
||||
@ -1382,7 +1392,7 @@ If you end your affiliate program:
|
||||
if let durationMonths = item.program.durationMonths {
|
||||
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (30 * 24 * 60 * 60))
|
||||
} else {
|
||||
durationTitle = "Lifetime"
|
||||
durationTitle = environment.strings.AffiliateProgram_DurationLifetime
|
||||
}
|
||||
|
||||
suggestedSectionItems.append(AnyComponentWithIdentity(id: item.peer.id, component: AnyComponent(PeerListItemComponent(
|
||||
@ -1476,7 +1486,7 @@ If you end your affiliate program:
|
||||
var suggestedHeaderItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
suggestedHeaderItems.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "PROGRAMS",
|
||||
string: environment.strings.AffiliateSetup_SuggestedSectionTitle,
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
|
@ -365,11 +365,11 @@ private final class JoinAffiliateProgramScreenComponent: Component {
|
||||
for peer in peers {
|
||||
let peerLabel: String
|
||||
if peer.id == component.context.account.peerId {
|
||||
peerLabel = "personal account"
|
||||
peerLabel = environment.strings.AffiliateProgram_PeerTypeSelf
|
||||
} else if case .channel = peer {
|
||||
peerLabel = "channel"
|
||||
peerLabel = environment.strings.Channel_Status
|
||||
} else {
|
||||
peerLabel = "bot"
|
||||
peerLabel = environment.strings.Bot_GenericBotStatus
|
||||
}
|
||||
let isSelected = peer.id == self.currentTargetPeer?.id
|
||||
let accentColor = environment.theme.list.itemAccentColor
|
||||
@ -767,12 +767,6 @@ private final class JoinAffiliateProgramScreenComponent: Component {
|
||||
}
|
||||
|
||||
let commissionTitle = "\(formatPermille(component.commissionPermille))%"
|
||||
let durationTitle: String
|
||||
if let durationMonths = component.programDuration {
|
||||
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (24 * 60 * 60))
|
||||
} else {
|
||||
durationTitle = "lifetime"
|
||||
}
|
||||
|
||||
let titleString: String
|
||||
var subtitleString: String
|
||||
@ -780,34 +774,40 @@ private final class JoinAffiliateProgramScreenComponent: Component {
|
||||
let termsString: String
|
||||
switch currentMode {
|
||||
case .join:
|
||||
titleString = "Affiliate Program"
|
||||
subtitleString = "**\(component.sourcePeer.compactDisplayTitle)** will share **\(commissionTitle)** of the revenue from each user you refer to it for **\(durationTitle)**."
|
||||
titleString = environment.strings.AffiliateProgram_JoinTitle
|
||||
|
||||
if let programDuration = component.programDuration {
|
||||
if programDuration < 12 {
|
||||
subtitleString = environment.strings.AffiliateProgram_JoinSubtitleMonths(Int32(programDuration)).replacingOccurrences(of: "{bot}", with: component.sourcePeer.compactDisplayTitle).replacingOccurrences(of: "{commission}", with: commissionTitle)
|
||||
} else {
|
||||
subtitleString = environment.strings.AffiliateProgram_JoinSubtitleYears(Int32(programDuration / 12)).replacingOccurrences(of: "{bot}", with: component.sourcePeer.compactDisplayTitle).replacingOccurrences(of: "{commission}", with: commissionTitle)
|
||||
}
|
||||
} else {
|
||||
subtitleString = environment.strings.AffiliateProgram_JoinSubtitleLifetime.replacingOccurrences(of: "{bot}", with: component.sourcePeer.compactDisplayTitle).replacingOccurrences(of: "{commission}", with: commissionTitle)
|
||||
}
|
||||
|
||||
if component.revenuePerUser != 0.0 {
|
||||
var revenueString = String(format: "%.1f", component.revenuePerUser)
|
||||
if revenueString.hasSuffix(".0") {
|
||||
revenueString = String(revenueString[revenueString.startIndex ..< revenueString.index(revenueString.endIndex, offsetBy: -2)])
|
||||
}
|
||||
dailyRevenueString = "Daily revenue per user: #**\(revenueString)**"
|
||||
dailyRevenueString = environment.strings.AffiliateProgram_DailyRevenueText(revenueString).string
|
||||
}
|
||||
|
||||
termsString = "By joining this program, you afree to the [terms and conditions](https://telegram.org/terms) of Affiliate Programs."
|
||||
termsString = environment.strings.AffiliateProgram_JoinTerms
|
||||
case let .active(active):
|
||||
titleString = "Referral Link"
|
||||
let timeString: String
|
||||
if component.programDuration == nil {
|
||||
timeString = "**forever** after they follow your link."
|
||||
titleString = environment.strings.AffiliateProgram_LinkTitle
|
||||
if let programDuration = component.programDuration {
|
||||
if programDuration < 12 {
|
||||
subtitleString = environment.strings.AffiliateProgram_LinkSubtitleMonths(Int32(programDuration)).replacingOccurrences(of: "{bot}", with: component.sourcePeer.compactDisplayTitle).replacingOccurrences(of: "{commission}", with: commissionTitle)
|
||||
} else {
|
||||
subtitleString = environment.strings.AffiliateProgram_LinkSubtitleYears(Int32(programDuration / 12)).replacingOccurrences(of: "{bot}", with: component.sourcePeer.compactDisplayTitle).replacingOccurrences(of: "{commission}", with: commissionTitle)
|
||||
}
|
||||
} else {
|
||||
timeString = "for **\(durationTitle)** after they follow your link."
|
||||
}
|
||||
subtitleString = "Share this link with your users to earn a **\(commissionTitle)** commission on their spending in **\(component.sourcePeer.compactDisplayTitle)** \(timeString)."
|
||||
if active.bot.participants == 0 {
|
||||
termsString = "No one opened \(component.sourcePeer.compactDisplayTitle) through this link yet."
|
||||
} else if active.bot.participants == 1 {
|
||||
termsString = "1 user opened \(component.sourcePeer.compactDisplayTitle) through this link."
|
||||
} else {
|
||||
termsString = "\(active.bot.participants) users opened \(component.sourcePeer.compactDisplayTitle) through this link."
|
||||
subtitleString = environment.strings.AffiliateProgram_LinkSubtitleLifetime.replacingOccurrences(of: "{bot}", with: component.sourcePeer.compactDisplayTitle).replacingOccurrences(of: "{commission}", with: commissionTitle)
|
||||
}
|
||||
|
||||
termsString = environment.strings.AffiliateProgram_UserCountFooter(Int32(active.bot.participants)).replacingOccurrences(of: "{bot}", with: component.sourcePeer.compactDisplayTitle)
|
||||
}
|
||||
let titleSize = self.title.update(
|
||||
transition: .immediate,
|
||||
@ -986,7 +986,7 @@ private final class JoinAffiliateProgramScreenComponent: Component {
|
||||
let targetTextSize = self.targetText.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "Commission will be sent to:", font: Font.regular(15.0), textColor: environment.theme.list.itemPrimaryTextColor)),
|
||||
text: .plain(NSAttributedString(string: environment.strings.AffiliateProgram_CommistionDestinationText, font: Font.regular(15.0), textColor: environment.theme.list.itemPrimaryTextColor)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2
|
||||
@ -1087,9 +1087,9 @@ private final class JoinAffiliateProgramScreenComponent: Component {
|
||||
let actionButtonTitle: String
|
||||
switch currentMode {
|
||||
case .join:
|
||||
actionButtonTitle = "Join Program"
|
||||
actionButtonTitle = environment.strings.AffiliateProgram_ActionJoin
|
||||
case .active:
|
||||
actionButtonTitle = "Copy Link"
|
||||
actionButtonTitle = environment.strings.AffiliateProgram_ActionCopyLink
|
||||
}
|
||||
let actionButtonSize = self.actionButton.update(
|
||||
transition: transition,
|
||||
@ -1207,11 +1207,11 @@ private final class JoinAffiliateProgramScreenComponent: Component {
|
||||
)),
|
||||
content: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
|
||||
text: .markdown(text: "Program joined", attributes: MarkdownAttributes(body: bold, bold: bold, link: body, linkAttribute: { _ in nil })),
|
||||
text: .markdown(text: environment.strings.AffiliateProgram_ToastJoined_Title, attributes: MarkdownAttributes(body: bold, bold: bold, link: body, linkAttribute: { _ in nil })),
|
||||
maximumNumberOfLines: 0
|
||||
))),
|
||||
AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent(
|
||||
text: .markdown(text: "You can now copy the referral link.", attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in nil })),
|
||||
text: .markdown(text: environment.strings.AffiliateProgram_ToastJoined_Text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in nil })),
|
||||
maximumNumberOfLines: 0
|
||||
)))
|
||||
], alignment: .left, spacing: 6.0)),
|
||||
@ -1920,11 +1920,11 @@ final class BotSectionSortButtonComponent: Component {
|
||||
let sortByString: String
|
||||
switch component.sortMode {
|
||||
case .date:
|
||||
sortByString = "SORT BY [DATE]()"
|
||||
sortByString = component.strings.AffiliateSetup_SortSectionHeader_Date
|
||||
case .profitability:
|
||||
sortByString = "SORT BY [PROFITABILITY]()"
|
||||
sortByString = component.strings.AffiliateSetup_SortSectionHeader_Profitability
|
||||
case .revenue:
|
||||
sortByString = "SORT BY [REVENUE]()"
|
||||
sortByString = component.strings.AffiliateSetup_SortSectionHeader_Revenue
|
||||
}
|
||||
let textSize = self.text.update(
|
||||
transition: .immediate,
|
||||
|
@ -1443,14 +1443,12 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
if items[.botAffiliateProgram] == nil {
|
||||
items[.botAffiliateProgram] = []
|
||||
}
|
||||
//TODO:localize
|
||||
let programTitleValue: String
|
||||
programTitleValue = "\(formatPermille(starRefProgram.commissionPermille))%"
|
||||
//TODO:localize
|
||||
items[.botAffiliateProgram]!.append(PeerInfoScreenDisclosureItem(id: 0, label: .labelBadge(programTitleValue), additionalBadgeLabel: nil, text: "Affiliate Program", icon: PresentationResourcesSettings.affiliateProgram, action: {
|
||||
items[.botAffiliateProgram]!.append(PeerInfoScreenDisclosureItem(id: 0, label: .labelBadge(programTitleValue), additionalBadgeLabel: nil, text: presentationData.strings.PeerInfo_ItemAffiliateProgram_Title, 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 \(formatPermille(starRefProgram.commissionPermille))% of their spending there."))
|
||||
items[.botAffiliateProgram]!.append(PeerInfoScreenCommentItem(id: 1, text: presentationData.strings.PeerInfo_ItemAffiliateProgram_Footer(EnginePeer.user(user).compactDisplayTitle, formatPermille(starRefProgram.commissionPermille)).string))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1960,14 +1958,13 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
|
||||
}
|
||||
|
||||
if canSetupRefProgram {
|
||||
//TODO:localize
|
||||
let programTitleValue: PeerInfoScreenDisclosureItem.Label
|
||||
if let cachedData = data.cachedData as? CachedUserData, let starRefProgram = cachedData.starRefProgram, starRefProgram.endDate == nil {
|
||||
programTitleValue = .labelBadge("\(formatPermille(starRefProgram.commissionPermille))%")
|
||||
} else {
|
||||
programTitleValue = .text("Off")
|
||||
programTitleValue = .text(presentationData.strings.PeerInfo_ItemAffiliateProgram_ValueOff)
|
||||
}
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAffiliateProgram, label: programTitleValue, additionalBadgeLabel: presentationData.strings.Settings_New, text: "Affiliate Program", icon: PresentationResourcesSettings.affiliateProgram, action: {
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAffiliateProgram, label: programTitleValue, additionalBadgeLabel: presentationData.strings.Settings_New, text: presentationData.strings.PeerInfo_ItemAffiliateProgram_Title, icon: PresentationResourcesSettings.affiliateProgram, action: {
|
||||
interaction.editingOpenAffiliateProgram()
|
||||
}))
|
||||
}
|
||||
@ -2232,7 +2229,7 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
|
||||
}
|
||||
|
||||
if canJoinRefProgram {
|
||||
items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAffiliatePrograms, label: .text(""), additionalBadgeLabel: presentationData.strings.Settings_New, text: "Affiliate Programs", icon: PresentationResourcesSettings.affiliateProgram, action: {
|
||||
items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAffiliatePrograms, label: .text(""), additionalBadgeLabel: presentationData.strings.Settings_New, text: presentationData.strings.PeerInfo_ItemAffiliatePrograms_Title, icon: PresentationResourcesSettings.affiliateProgram, action: {
|
||||
interaction.editingOpenAffiliateProgram()
|
||||
}))
|
||||
}
|
||||
@ -8659,10 +8656,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
//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 **\(formatPermille(result.commissionPermille))%** 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: presentationData.strings.AffiliateProgram_ToastLinkCopied_Title, text: presentationData.strings.AffiliateProgram_ToastLinkCopied_Text(formatPermille(result.commissionPermille), result.peer.compactDisplayTitle).string), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
))
|
||||
} else {
|
||||
|
@ -404,12 +404,11 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
transactionPeer = transaction.peer
|
||||
isGift = true
|
||||
} else if let starrefCommissionPermille = transaction.starrefCommissionPermille {
|
||||
//TODO:localize
|
||||
isRefProgram = true
|
||||
if transaction.starrefPeerId == nil {
|
||||
titleText = "\(formatPermille(starrefCommissionPermille))% Commission"
|
||||
titleText = strings.StarsTransaction_TitleCommission(formatPermille(starrefCommissionPermille)).string
|
||||
} else {
|
||||
titleText = transaction.title ?? "Product"
|
||||
titleText = transaction.title ?? " "
|
||||
}
|
||||
descriptionText = ""
|
||||
count = transaction.count
|
||||
@ -868,15 +867,14 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
}
|
||||
|
||||
if case let .transaction(transaction, _) = subject {
|
||||
//TODO:localize
|
||||
if transaction.starrefCommissionPermille != nil {
|
||||
if transaction.starrefPeerId == nil {
|
||||
tableItems.append(.init(
|
||||
id: "reason",
|
||||
title: "Reason",
|
||||
title: strings.StarsTransaction_StarRefReason_Title,
|
||||
component: AnyComponent(
|
||||
Button(
|
||||
content: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "Affiliate Program", font: tableFont, textColor: tableLinkColor))
|
||||
content: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: strings.StarsTransaction_StarRefReason_Program, font: tableFont, textColor: tableLinkColor))
|
||||
)),
|
||||
action: {
|
||||
if let toPeer {
|
||||
@ -894,7 +892,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
if let toPeer, transaction.starrefPeerId == nil {
|
||||
tableItems.append(.init(
|
||||
id: "miniapp",
|
||||
title: "Mini App",
|
||||
title: strings.StarsTransaction_StarRefReason_Miniapp,
|
||||
component: AnyComponent(
|
||||
Button(
|
||||
content: AnyComponent(
|
||||
@ -923,10 +921,9 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
}
|
||||
}
|
||||
if let starRefPeerId = transaction.starrefPeerId, let starRefPeer = state.peerMap[starRefPeerId] {
|
||||
//TODO:localize
|
||||
tableItems.append(.init(
|
||||
id: "to",
|
||||
title: "Affiliate",
|
||||
title: strings.StarsTransaction_StarRefReason_Affiliate,
|
||||
component: AnyComponent(
|
||||
Button(
|
||||
content: AnyComponent(
|
||||
@ -955,7 +952,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
if let toPeer {
|
||||
tableItems.append(.init(
|
||||
id: "referred",
|
||||
title: "Referred User",
|
||||
title: strings.StarsTransaction_StarRefReason_Referred,
|
||||
component: AnyComponent(
|
||||
Button(
|
||||
content: AnyComponent(
|
||||
|
@ -679,9 +679,8 @@ final class StarsTransactionsScreenComponent: Component {
|
||||
header: nil,
|
||||
footer: nil,
|
||||
items: [
|
||||
//TODO:localize
|
||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListItemComponentAdaptor(
|
||||
itemGenerator: ItemListDisclosureItem(presentationData: ItemListPresentationData(presentationData), icon: PresentationResourcesSettings.earnStars, title: "Earn Stars", titleBadge: presentationData.strings.Settings_New, label: "Distribute links to mini apps and earn a share of their revenue in Stars.", labelStyle: .multilineDetailText, sectionId: 0, style: .blocks, action: {
|
||||
itemGenerator: ItemListDisclosureItem(presentationData: ItemListPresentationData(presentationData), icon: PresentationResourcesSettings.earnStars, title: environment.strings.Monetization_EarnStarsInfo_Title, titleBadge: presentationData.strings.Settings_New, label: environment.strings.Monetization_EarnStarsInfo_Text, labelStyle: .multilineDetailText, sectionId: 0, style: .blocks, action: {
|
||||
}),
|
||||
params: ListViewItemLayoutParams(width: availableSize.width, leftInset: 0.0, rightInset: 0.0, availableHeight: 10000.0, isStandalone: true),
|
||||
action: { [weak self] in
|
||||
|
Loading…
x
Reference in New Issue
Block a user