mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Update localization
This commit is contained in:
parent
983e720453
commit
d23e67a62d
@ -10151,3 +10151,150 @@ Sorry for the inconvenience.";
|
||||
|
||||
"Stats.Boosts.ShowMoreBoosts_1" = "Show %@ More Boost";
|
||||
"Stats.Boosts.ShowMoreBoosts_any" = "Show %@ More Boosts";
|
||||
|
||||
"ReassignBoost.Title" = "Reassign Boosts";
|
||||
"ReassignBoost.Description" = "To boost **%1$@**, reassign a previous boost or gift **Telegram Premium** to a friend to get **%2$@** additional boosts.";
|
||||
"ReassignBoost.ReassignBoosts" = "Reassign Boosts";
|
||||
"ReassignBoost.AvailableIn" = "Available in %@";
|
||||
"ReassignBoost.ExpiresOn" = "Boost expires on %@";
|
||||
"ReassignBoost.WaitForCooldown" = "Wait until the boost is available or get **%1$@** more boosts by gifting a **Telegram Premium** subscription.";
|
||||
|
||||
"ReassignBoost.Success" = "Wait until the boost is available or get **%1$@** more boosts by gifting a **Telegram Premium** subscription.";
|
||||
|
||||
//"\(replacedBoosts) boosts are reassigned from \(inChannels) other channel."
|
||||
|
||||
"ChannelBoost.MoreBoosts.Title" = "More Boosts Needed";
|
||||
"ChannelBoost.MoreBoosts.Text" = "To boost **%1$@** again, gift **Telegram Premium** to a friend and get **%2$@** additional boosts.";
|
||||
|
||||
"BoostGift.Title" = "Boosts via Gifts";
|
||||
"BoostGift.Description" = "Get more boosts for your channel by gifting\nPremium to your subscribers.";
|
||||
"BoostGift.PrepaidGiveawayTitle" = "PREPAID GIVEAWAY";
|
||||
"BoostGift.PrepaidGiveawayCount_1" = "%@ Telegram Premium";
|
||||
"BoostGift.PrepaidGiveawayCount_any" = "%@ Telegram Premium";
|
||||
"BoostGift.PrepaidGiveawayMonths" = "%@-month subscriptions";
|
||||
"BoostGift.CreateGiveaway" = "Create Giveaway";
|
||||
"BoostGift.CreateGiveawayInfo" = "winners are chosen randomly";
|
||||
"BoostGift.AwardSpecificUsers" = "Award Specific Users";
|
||||
"BoostGift.SelectRecipients" = "select recipients";
|
||||
"BoostGift.QuantityTitle" = "QUANTITY OF PRIZES";
|
||||
"BoostGift.QuantityBoosts_1" = "%@ BOOST";
|
||||
"BoostGift.QuantityBoosts_any" = "%@ BOOSTS";
|
||||
"BoostGift.QuantityInfo" = "Choose how many Premium subscriptions to give away and boosts to receive.";
|
||||
"BoostGift.ChannelsTitle" = "CHANNELS INCLUDED IN THE GIVEAWAY";
|
||||
"BoostGift.AddChannel" = "Add Channel";
|
||||
"BoostGift.ChannelsBoosts_1" = "this channel will receive %@ boost";
|
||||
"BoostGift.ChannelsBoosts_any" = "this channel will receive %@ boosts";
|
||||
"BoostGift.ChannelsInfo" = "Choose the channels users need to be subscribed to take part in the giveaway";
|
||||
"BoostGift.UsersTitle" = "USERS ELIGIBLE FOR THE GIVEAWAY";
|
||||
"BoostGift.FromCountries_1" = "from %@ country";
|
||||
"BoostGift.FromCountries_any" = "from %@ countries";
|
||||
"BoostGift.FromTwoCountries" = "from %1$@ and %2$@";
|
||||
"BoostGift.FromOneCountry" = "from %1$@";
|
||||
"BoostGift.FromAllCountries" = "from all countries";
|
||||
"BoostGift.AllSubscribers" = "All subscribers";
|
||||
"BoostGift.OnlyNewSubscribers" = "Only new subscribers";
|
||||
"BoostGift.LimitSubscribersInfo" = "Choose if you want to limit the giveaway only to those who joined the channel after the giveaway started.";
|
||||
"BoostGift.DateTitle" = "DATE WHEN GIVEAWAY ENDS";
|
||||
"BoostGift.DateEnds" = "Ends";
|
||||
"BoostGift.DateInfo" = "Choose when %1$@ of your channel will be randomly selected to receive Telegram Premium.";
|
||||
"BoostGift.DateInfoSubscribers_1" = "%@ subscriber";
|
||||
"BoostGift.DateInfoSubscribers_any" = "%@ subscribers";
|
||||
"BoostGift.DurationTitle" = "DURATION OF PREMIUM SUBSCRIPTIONS";
|
||||
"BoostGift.PremiumInfo" = "You can review the list of features and terms of use for Telegram Premium [here]().";
|
||||
"BoostGift.GiftPremium" = "Gift Premium";
|
||||
"BoostGift.StartGiveaway" = "Start Giveaway";
|
||||
"BoostGift.ReduceQuantity.Title" = "Reduce Quantity";
|
||||
"BoostGift.ReduceQuantity.Text" = "You can't acquire %1$@ %2$@-month subscriptions in the app. Do you want to reduce quantity to %3$@?";
|
||||
"BoostGift.ReduceQuantity.Reduce" = "Reduce";
|
||||
"BoostGift.GiveawayCreated.Title" = "Giveaway Created";
|
||||
"BoostGift.GiveawayCreated.Text" = "Check your channel's [Statistics]() to see how this giveaway boosted your channel.";
|
||||
"BoostGift.PremiumGifted.Title" = "Premium Subscriptions Gifted";
|
||||
"BoostGift.PremiumGifted.Text" = "Check your channel's [Statistics]() to see how gifts boosted your channel.";
|
||||
|
||||
"BoostGift.Subscribers.Title" = "Gift Premium";
|
||||
"BoostGift.Subscribers.Subtitle" = "select up to %@ subscribers";
|
||||
"BoostGift.Subscribers.SectionTitle" = "SUBSCRIBERS";
|
||||
"BoostGift.Subscribers.Joined" = "joined %@";
|
||||
"BoostGift.Subscribers.Search" = "Search Subscribers";
|
||||
"BoostGift.Subscribers.MaximumReached" = "You can select maximum %@ subscribers.";
|
||||
"BoostGift.Subscribers.Save" = "Save Recipients";
|
||||
|
||||
"BoostGift.Channels.Title" = "Add Channels";
|
||||
"BoostGift.Channels.Subtitle" = "select up to %@ channels";
|
||||
"BoostGift.Channels.SectionTitle" = "CHANNELS";
|
||||
"BoostGift.Channels.Search" = "Search Channels";
|
||||
"BoostGift.Channels.MaximumReached" = "You can select maximum %@ channels.";
|
||||
"BoostGift.Channels.PrivateChannel.Title" = "Channel is Private";
|
||||
"BoostGift.Channels.PrivateChannel.Text" = "Are you sure you want to add a private channel? Users won't be able to join it without an invite link.";
|
||||
"BoostGift.Channels.PrivateChannel.Add" = "Add";
|
||||
"BoostGift.Channels.Save" = "Save Channels";
|
||||
|
||||
"Stats.Boosts.PrepaidGiveawaysTitle" = "PREPAID GIVEAWAYS";
|
||||
"Stats.Boosts.PrepaidGiveawayCount_any" = "%@ Telegram Premium";
|
||||
"Stats.Boosts.PrepaidGiveawayMonths" = "%@-month subscriptions";
|
||||
"Stats.Boosts.PrepaidGiveawaysInfo" = "Select a giveaway you already paid for to set it up.";
|
||||
"Stats.Boosts.ShortMonth" = "%@m";
|
||||
"Stats.Boosts.Giveaway" = "Giveaway";
|
||||
"Stats.Boosts.Gift" = "Gift";
|
||||
"Stats.Boosts.TabBoosts_1" = "%@ Boost";
|
||||
"Stats.Boosts.TabBoosts_any" = "%@ Boosts";
|
||||
"Stats.Boosts.TabGifts_1" = "%@ Boost";
|
||||
"Stats.Boosts.TabGifts_any" = "%@ Boosts";
|
||||
"Stats.Boosts.ToBeDistributed" = "To Be Distributed";
|
||||
"Stats.Boosts.Unclaimed" = "Unclaimed";
|
||||
"Stats.Boosts.GetBoosts" = "Get Boosts via Gifts";
|
||||
"Stats.Boosts.GetBoostsInfo" = "Get more boosts for your channel by gifting Premium to your subscribers.";
|
||||
|
||||
"Notification.PremiumPrize.Title" = "Congratulations!";
|
||||
"Notification.PremiumPrize.UnclaimedText" = "You have an unclaimed prize from a giveaway by **%1$@**.\n\nThis prize is a **Telegram Premium** subscription for %2$@.";
|
||||
"Notification.PremiumPrize.GiveawayText" = "You won a prize in a giveaway organized by **%1$@**.\n\nYour prize is a **Telegram Premium** subscription for %2$@.";
|
||||
"Notification.PremiumPrize.GiftText" = "You've received a gift from **%1$@**.\n\nYour gift is a **Telegram Premium** subscription for %2$@.";
|
||||
"Notification.PremiumPrize.Months_1" = "**%@** month";
|
||||
"Notification.PremiumPrize.Months_any" = "**%@** months";
|
||||
"Notification.PremiumPrize.View" = "Open Gift Link";
|
||||
"Notification.PremiumPrize.Unclaimed" = "Unclaimed Prize";
|
||||
|
||||
"Story.SlideToSeek" = "Slide left or right to seek";
|
||||
"Story.Guide.Title" = "Watching Stories";
|
||||
"Story.Guide.Description" = "You can use these gestures to control playback.";
|
||||
"Story.Guide.ForwardTitle" = "Go forward";
|
||||
"Story.Guide.ForwardDescription" = "Tap the screen";
|
||||
"Story.Guide.PauseTitle" = "Pause and Seek";
|
||||
"Story.Guide.PauseDescription" = "Hold and move sideways";
|
||||
"Story.Guide.BackTitle" = "Go back";
|
||||
"Story.Guide.BackDescription" = "Tap the left edge";
|
||||
"Story.Guide.MoveTitle" = "Move between stories";
|
||||
"Story.Guide.MoveDescription" = "Swipe left or right";
|
||||
"Story.Guide.Proceed" = "Tap to keep watching";
|
||||
|
||||
"Chat.Giveaway.Info.Title" = "About This Giveaway";
|
||||
"Chat.Giveaway.Info.EndedTitle" = "Giveaway Ended";
|
||||
|
||||
"Chat.Giveaway.Info.AlmostOver" = "The giveaway is almost over.";
|
||||
|
||||
"Chat.Giveaway.Info.Subscriptions_1" = "**%@ Telegram Premium** subscription";
|
||||
"Chat.Giveaway.Info.Subscriptions_any" = "**%@ Telegram Premium** subscriptions";
|
||||
|
||||
"Chat.Giveaway.Info.RandomUsers_1" = "**%@** random user";
|
||||
"Chat.Giveaway.Info.RandomUsers_any" = "**%@** random user";
|
||||
|
||||
"Chat.Giveaway.Info.RandomSubscribers_1" = "**%@** random subscriber";
|
||||
"Chat.Giveaway.Info.RandomSubscribers_any" = "**%@** random subscribers";
|
||||
|
||||
"Chat.Giveaway.Info.Months_1" = "**%@** month";
|
||||
"Chat.Giveaway.Info.Months_any" = "**%@** months";
|
||||
|
||||
"Chat.Giveaway.Info.ActivatedLinks_1" = "%@ winner already used their gift link.";
|
||||
"Chat.Giveaway.Info.ActivatedLinks_any" = "%@ of the winners already used their gift links.";
|
||||
|
||||
"Chat.Giveaway.Info.Refunded" = "The channel cancelled the prizes by reversing the payment for them.";
|
||||
"Chat.Giveaway.Info.Won" = "You won a prize in this giveaway. %@";
|
||||
"Chat.Giveaway.Info.DidntWin" = "You didn't win a prize in this giveaway.";
|
||||
"Chat.Giveaway.Info.ViewPrize" = "View My Prize";
|
||||
|
||||
"Chat.Giveaway.Toast.NotAllowed" = "You can't participate in this giveaway.";
|
||||
"Chat.Giveaway.Toast.Participating" = "You are participating in this giveaway.";
|
||||
"Chat.Giveaway.Toast.NotQualified" = "You are not qualified for this giveaway yet.";
|
||||
"Chat.Giveaway.Toast.AlmostOver" = "The giveaway is almost over.";
|
||||
"Chat.Giveaway.Toast.Ended" = "The giveaway is ended.";
|
||||
"Chat.Giveaway.Toast.LearnMore" = "Learn More";
|
||||
|
@ -109,6 +109,7 @@ swift_library(
|
||||
"//submodules/CountrySelectionUI",
|
||||
"//submodules/TelegramUI/Components/Stories/PeerListItemComponent",
|
||||
"//submodules/InvisibleInkDustNode",
|
||||
"//submodules/AlertUI",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -377,8 +377,7 @@ private enum CreateGiveawayEntry: ItemListNodeEntry {
|
||||
case let .channelsHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .channel(_, _, peer, boosts, isRevealed):
|
||||
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: PresentationDateTimeFormat(), nameDisplayOrder: presentationData.nameDisplayOrder, context: arguments.context, peer: peer, presence: nil, text: boosts.flatMap { .text("this channel will receive \($0) boosts", .secondary) } ?? .none, label: .none, editing: ItemListPeerItemEditing(editable: boosts == nil, editing: false, revealed: isRevealed), switchValue: nil, enabled: true, selectable: peer.id != arguments.context.account.peerId, sectionId: self.section, action: {
|
||||
// arguments.openPeer(peer)
|
||||
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: PresentationDateTimeFormat(), nameDisplayOrder: presentationData.nameDisplayOrder, context: arguments.context, peer: peer, presence: nil, text: boosts.flatMap { .text(presentationData.strings.BoostGift_ChannelsBoosts($0), .secondary) } ?? .none, label: .none, editing: ItemListPeerItemEditing(editable: boosts == nil, editing: false, revealed: isRevealed), switchValue: nil, enabled: true, selectable: peer.id != arguments.context.account.peerId, sectionId: self.section, action: {
|
||||
}, setPeerIdWithRevealedOptions: { lhs, rhs in
|
||||
arguments.setItemIdWithRevealedOptions(lhs, rhs)
|
||||
}, removePeer: { id in
|
||||
@ -433,7 +432,7 @@ private enum CreateGiveawayEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
text = presentationData.strings.InviteLink_Create_TimeLimitExpiryDateNever
|
||||
}
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: "Ends", label: text, labelStyle: active ? .coloredText(theme.list.itemAccentColor) : .text, sectionId: self.section, style: .blocks, disclosureStyle: .none, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: presentationData.strings.BoostGift_DateEnds, label: text, labelStyle: active ? .coloredText(theme.list.itemAccentColor) : .text, sectionId: self.section, style: .blocks, disclosureStyle: .none, action: {
|
||||
arguments.dismissInput()
|
||||
var focus = false
|
||||
arguments.updateState { state in
|
||||
@ -515,7 +514,7 @@ private func createGiveawayControllerEntries(
|
||||
|
||||
switch subject {
|
||||
case .generic:
|
||||
entries.append(.createGiveaway(presentationData.theme, "Create Giveaway", "winners are chosen randomly", state.mode == .giveaway))
|
||||
entries.append(.createGiveaway(presentationData.theme, presentationData.strings.BoostGift_CreateGiveaway, presentationData.strings.BoostGift_CreateGiveawayInfo, state.mode == .giveaway))
|
||||
|
||||
let recipientsText: String
|
||||
if !state.peers.isEmpty {
|
||||
@ -533,22 +532,22 @@ private func createGiveawayControllerEntries(
|
||||
recipientsText = presentationData.strings.PremiumGift_LabelRecipients(Int32(peersCount))
|
||||
}
|
||||
} else {
|
||||
recipientsText = "select recipients"
|
||||
recipientsText = presentationData.strings.BoostGift_SelectRecipients
|
||||
}
|
||||
entries.append(.awardUsers(presentationData.theme, "Award Specific Users", recipientsText, state.mode == .gift))
|
||||
entries.append(.awardUsers(presentationData.theme, presentationData.strings.BoostGift_AwardSpecificUsers, recipientsText, state.mode == .gift))
|
||||
case let .prepaid(prepaidGiveaway):
|
||||
entries.append(.prepaidHeader(presentationData.theme, "PREPAID GIVEAWAY"))
|
||||
entries.append(.prepaid(presentationData.theme, "\(prepaidGiveaway.quantity) Telegram Premium", "\(prepaidGiveaway.months)-month subscriptions", prepaidGiveaway))
|
||||
entries.append(.prepaidHeader(presentationData.theme, presentationData.strings.BoostGift_PrepaidGiveawayTitle))
|
||||
entries.append(.prepaid(presentationData.theme, presentationData.strings.BoostGift_PrepaidGiveawayCount(prepaidGiveaway.quantity), presentationData.strings.BoostGift_PrepaidGiveawayMonths("\(prepaidGiveaway.months)").string, prepaidGiveaway))
|
||||
}
|
||||
|
||||
if case .giveaway = state.mode {
|
||||
if case .generic = subject {
|
||||
entries.append(.subscriptionsHeader(presentationData.theme, "QUANTITY OF PRIZES".uppercased(), "\(state.subscriptions * 4) BOOSTS"))
|
||||
entries.append(.subscriptionsHeader(presentationData.theme, presentationData.strings.BoostGift_QuantityTitle.uppercased(), presentationData.strings.BoostGift_QuantityBoosts(state.subscriptions * 4)))
|
||||
entries.append(.subscriptions(presentationData.theme, state.subscriptions))
|
||||
entries.append(.subscriptionsInfo(presentationData.theme, "Choose how many Premium subscriptions to give away and boosts to receive."))
|
||||
entries.append(.subscriptionsInfo(presentationData.theme, presentationData.strings.BoostGift_QuantityInfo))
|
||||
}
|
||||
|
||||
entries.append(.channelsHeader(presentationData.theme, "CHANNELS INCLUDED IN THE GIVEAWAY".uppercased()))
|
||||
entries.append(.channelsHeader(presentationData.theme, presentationData.strings.BoostGift_ChannelsTitle.uppercased()))
|
||||
var index: Int32 = 0
|
||||
let channels = [peerId] + state.channels
|
||||
for channelId in channels {
|
||||
@ -557,35 +556,44 @@ private func createGiveawayControllerEntries(
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
entries.append(.channelAdd(presentationData.theme, "Add Channel"))
|
||||
entries.append(.channelsInfo(presentationData.theme, "Choose the channels users need to be subscribed to take part in the giveaway"))
|
||||
entries.append(.channelAdd(presentationData.theme, presentationData.strings.BoostGift_AddChannel))
|
||||
entries.append(.channelsInfo(presentationData.theme, presentationData.strings.BoostGift_ChannelsInfo))
|
||||
|
||||
entries.append(.usersHeader(presentationData.theme, "USERS ELIGIBLE FOR THE GIVEAWAY".uppercased()))
|
||||
entries.append(.usersHeader(presentationData.theme, presentationData.strings.BoostGift_UsersTitle.uppercased()))
|
||||
|
||||
let countriesText: String
|
||||
if state.countries.count > 2 {
|
||||
countriesText = "from \(state.countries.count) countries"
|
||||
countriesText = presentationData.strings.BoostGift_FromCountries(Int32(state.countries.count))
|
||||
} else if !state.countries.isEmpty {
|
||||
let allCountries = state.countries.map { locale.localizedString(forRegionCode: $0) ?? $0 }.joined(separator: " and ")
|
||||
countriesText = "from \(allCountries)"
|
||||
if state.countries.count == 2 {
|
||||
let firstCountryCode = state.countries.first ?? ""
|
||||
let secondCountryCode = state.countries.last ?? ""
|
||||
let firstCountryName = locale.localizedString(forRegionCode: firstCountryCode) ?? firstCountryCode
|
||||
let secondCountryName = locale.localizedString(forRegionCode: secondCountryCode) ?? secondCountryCode
|
||||
countriesText = presentationData.strings.BoostGift_FromTwoCountries(firstCountryName, secondCountryName).string
|
||||
} else {
|
||||
let countryCode = state.countries.first ?? ""
|
||||
let countryName = locale.localizedString(forRegionCode: countryCode) ?? countryCode
|
||||
countriesText = presentationData.strings.BoostGift_FromOneCountry(countryName).string
|
||||
}
|
||||
} else {
|
||||
countriesText = "from all countries"
|
||||
countriesText = presentationData.strings.BoostGift_FromAllCountries
|
||||
}
|
||||
|
||||
entries.append(.usersAll(presentationData.theme, "All subscribers", countriesText, !state.onlyNewEligible))
|
||||
entries.append(.usersNew(presentationData.theme, "Only new subscribers", countriesText, state.onlyNewEligible))
|
||||
entries.append(.usersInfo(presentationData.theme, "Choose if you want to limit the giveaway only to those who joined the channel after the giveaway started."))
|
||||
entries.append(.usersAll(presentationData.theme, presentationData.strings.BoostGift_AllSubscribers, countriesText, !state.onlyNewEligible))
|
||||
entries.append(.usersNew(presentationData.theme, presentationData.strings.BoostGift_OnlyNewSubscribers, countriesText, state.onlyNewEligible))
|
||||
entries.append(.usersInfo(presentationData.theme, presentationData.strings.BoostGift_LimitSubscribersInfo))
|
||||
|
||||
entries.append(.timeHeader(presentationData.theme, "DATE WHEN GIVEAWAY ENDS".uppercased()))
|
||||
entries.append(.timeHeader(presentationData.theme, presentationData.strings.BoostGift_DateTitle.uppercased()))
|
||||
entries.append(.timeExpiryDate(presentationData.theme, presentationData.dateTimeFormat, state.time, state.pickingTimeLimit))
|
||||
if state.pickingTimeLimit {
|
||||
entries.append(.timeCustomPicker(presentationData.theme, presentationData.dateTimeFormat, state.time, minDate, maxDate))
|
||||
}
|
||||
entries.append(.timeInfo(presentationData.theme, "Choose when \(state.subscriptions) subscribers of your channel will be randomly selected to receive Telegram Premium."))
|
||||
entries.append(.timeInfo(presentationData.theme, presentationData.strings.BoostGift_DateInfo(presentationData.strings.BoostGift_DateInfoSubscribers(Int32(state.subscriptions))).string))
|
||||
}
|
||||
|
||||
if case .generic = subject {
|
||||
entries.append(.durationHeader(presentationData.theme, "DURATION OF PREMIUM SUBSCRIPTIONS".uppercased()))
|
||||
entries.append(.durationHeader(presentationData.theme, presentationData.strings.BoostGift_DurationTitle.uppercased()))
|
||||
|
||||
let recipientCount: Int
|
||||
switch state.mode {
|
||||
@ -628,7 +636,7 @@ private func createGiveawayControllerEntries(
|
||||
i += 1
|
||||
}
|
||||
|
||||
entries.append(.durationInfo(presentationData.theme, "You can review the list of features and terms of use for Telegram Premium [here]()."))
|
||||
entries.append(.durationInfo(presentationData.theme, presentationData.strings.BoostGift_PremiumInfo))
|
||||
}
|
||||
|
||||
return entries
|
||||
@ -776,7 +784,7 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
|
||||
|
||||
let (state, peersMap) = stateAndPeersMap
|
||||
|
||||
let headerItem = CreateGiveawayHeaderItem(theme: presentationData.theme, title: "Boosts via Gifts", text: "Get more boosts for your channel by gifting\nPremium to your subscribers.", cancel: {
|
||||
let headerItem = CreateGiveawayHeaderItem(theme: presentationData.theme, strings: presentationData.strings, title: presentationData.strings.BoostGift_Title, text: presentationData.strings.BoostGift_Description, cancel: {
|
||||
dismissImpl?()
|
||||
})
|
||||
|
||||
@ -787,7 +795,7 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
|
||||
case .gift:
|
||||
badgeCount = Int32(state.peers.count)
|
||||
}
|
||||
let footerItem = CreateGiveawayFooterItem(theme: presentationData.theme, title: state.mode == .gift ? "Gift Premium" : "Start Giveaway", badgeCount: badgeCount, isLoading: state.updating, action: {
|
||||
let footerItem = CreateGiveawayFooterItem(theme: presentationData.theme, title: state.mode == .gift ? presentationData.strings.BoostGift_GiftPremium : presentationData.strings.BoostGift_StartGiveaway, badgeCount: badgeCount, isLoading: state.updating, action: {
|
||||
buyActionImpl?()
|
||||
})
|
||||
let leftNavigationButton = ItemListNavigationButton(content: .none, style: .regular, enabled: false, action: {})
|
||||
@ -857,7 +865,7 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
|
||||
}
|
||||
|
||||
guard let selectedProduct else {
|
||||
let alertController = textAlertController(context: context, title: "Reduce Quantity", text: "You can't acquire \(state.subscriptions) \(selectedMonths)-month subscriptions in the app. Do you want to reduce quantity to 25?", actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: "Reduce", action: {
|
||||
let alertController = textAlertController(context: context, title: presentationData.strings.BoostGift_ReduceQuantity_Title, text: presentationData.strings.BoostGift_ReduceQuantity_Text("\(state.subscriptions)", "\(selectedMonths)", "\(25)").string, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.BoostGift_ReduceQuantity_Reduce, action: {
|
||||
updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.subscriptions = 25
|
||||
@ -915,11 +923,11 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
|
||||
let text: String
|
||||
switch state.mode {
|
||||
case .giveaway:
|
||||
title = "Giveaway Created"
|
||||
text = "Check your channel's [Statistics]() to see how this giveaway boosted your channel."
|
||||
title = presentationData.strings.BoostGift_GiveawayCreated_Title
|
||||
text = presentationData.strings.BoostGift_GiveawayCreated_Text
|
||||
case .gift:
|
||||
title = "Premium Subscriptions Gifted"
|
||||
text = "Check your channel's [Statistics]() to see how gifts boosted your channel."
|
||||
title = presentationData.strings.BoostGift_PremiumGifted_Title
|
||||
text = presentationData.strings.BoostGift_PremiumGifted_Text
|
||||
}
|
||||
|
||||
let tooltipController = UndoOverlayController(presentationData: presentationData, content: .premiumPaywall(title: title, text: text, customUndoText: nil, timeout: nil, linkAction: { [weak navigationController] _ in
|
||||
@ -992,8 +1000,8 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
|
||||
controllers.removeLast(count)
|
||||
navigationController.setViewControllers(controllers, animated: true)
|
||||
|
||||
let title = "Giveaway Created"
|
||||
let text = "Check your channel's [Statistics]() to see how this giveaway boosted your channel."
|
||||
let title = presentationData.strings.BoostGift_GiveawayCreated_Title
|
||||
let text = presentationData.strings.BoostGift_GiveawayCreated_Text
|
||||
|
||||
let tooltipController = UndoOverlayController(presentationData: presentationData, content: .premiumPaywall(title: title, text: text, customUndoText: nil, timeout: nil, linkAction: { [weak navigationController] _ in
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.StatsDatacenterId(id: peerId))
|
||||
|
@ -11,12 +11,14 @@ import ComponentFlow
|
||||
|
||||
final class CreateGiveawayHeaderItem: ItemListControllerHeaderItem {
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let title: String
|
||||
let text: String
|
||||
let cancel: () -> Void
|
||||
|
||||
init(theme: PresentationTheme, title: String, text: String, cancel: @escaping () -> Void) {
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, title: String, text: String, cancel: @escaping () -> Void) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.title = title
|
||||
self.text = text
|
||||
self.cancel = cancel
|
||||
@ -132,7 +134,7 @@ class CreateGiveawayHeaderItemNode: ItemListControllerHeaderItemNode {
|
||||
self.titleNode.attributedText = attributedTitle
|
||||
self.textNode.attributedText = attributedText
|
||||
|
||||
self.cancelNode.setAttributedTitle(NSAttributedString(string: "Cancel", font: Font.regular(17.0), textColor: self.item.theme.rootController.navigationBar.accentTextColor), for: .normal)
|
||||
self.cancelNode.setAttributedTitle(NSAttributedString(string: self.item.strings.Common_Cancel, font: Font.regular(17.0), textColor: self.item.theme.rootController.navigationBar.accentTextColor), for: .normal)
|
||||
}
|
||||
|
||||
override func updateContentOffset(_ contentOffset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
|
@ -4,12 +4,161 @@ import AsyncDisplayKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TextFormat
|
||||
import AccountContext
|
||||
import AlertUI
|
||||
import PresentationDataUtils
|
||||
import TelegramStringFormatting
|
||||
import TelegramPresentationData
|
||||
import Markdown
|
||||
import AlertUI
|
||||
|
||||
public func giveawayInfoController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, message: EngineMessage, giveawayInfo: PremiumGiveawayInfo) -> ViewController? {
|
||||
guard let giveaway = message.media.first(where: { $0 is TelegramMediaGiveaway }) as? TelegramMediaGiveaway else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
var peerName = ""
|
||||
if let peerId = giveaway.channelPeerIds.first, let peer = message.peers[peerId] {
|
||||
peerName = EnginePeer(peer).compactDisplayTitle
|
||||
}
|
||||
|
||||
let untilDate = stringForDate(timestamp: giveaway.untilDate, strings: presentationData.strings)
|
||||
|
||||
let title: String
|
||||
let text: String
|
||||
var warning: String?
|
||||
|
||||
var dismissImpl: (() -> Void)?
|
||||
|
||||
var actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
|
||||
dismissImpl?()
|
||||
})]
|
||||
|
||||
switch giveawayInfo {
|
||||
case let .ongoing(start, status):
|
||||
let startDate = stringForDate(timestamp: start, strings: presentationData.strings)
|
||||
|
||||
title = presentationData.strings.Chat_Giveaway_Info_Title
|
||||
|
||||
let intro: String
|
||||
if case .almostOver = status {
|
||||
intro = "The giveaway was sponsored by the admins of **\(peerName)**, who acquired **\(giveaway.quantity) Telegram Premium** subscriptions for **\(giveaway.months)** months for its followers."
|
||||
} else {
|
||||
intro = "The giveaway is sponsored by the admins of **\(peerName)**, who acquired **\(giveaway.quantity) Telegram Premium** subscriptions for **\(giveaway.months)** months for its followers."
|
||||
}
|
||||
|
||||
let ending: String
|
||||
if giveaway.flags.contains(.onlyNewSubscribers) {
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
ending = "On **\(untilDate)**, Telegram will automatically select **\(giveaway.quantity)** random users that joined **\(peerName)** and **\(giveaway.channelPeerIds.count - 1)** other listed channels after **\(startDate)**."
|
||||
} else {
|
||||
ending = "On **\(untilDate)**, Telegram will automatically select **\(giveaway.quantity)** random users that joined **\(peerName)** after **\(startDate)**."
|
||||
}
|
||||
} else {
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
ending = "On **\(untilDate)**, Telegram will automatically select **\(giveaway.quantity)** random subscribers of **\(peerName)** and **\(giveaway.channelPeerIds.count - 1)** other listed channels."
|
||||
} else {
|
||||
ending = "On **\(untilDate)**, Telegram will automatically select **\(giveaway.quantity)** random subscribers of **\(peerName)**."
|
||||
}
|
||||
}
|
||||
|
||||
var participation: String
|
||||
switch status {
|
||||
case .notQualified:
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
participation = "To take part in this giveaway please join the channel **\(peerName)** (**\(giveaway.channelPeerIds.count - 1)** other listed channels) before **\(untilDate)**."
|
||||
} else {
|
||||
participation = "To take part in this giveaway please join the channel **\(peerName)** before **\(untilDate)**."
|
||||
}
|
||||
case let .notAllowed(reason):
|
||||
switch reason {
|
||||
case let .joinedTooEarly(joinedOn):
|
||||
let joinDate = stringForDate(timestamp: joinedOn, strings: presentationData.strings)
|
||||
participation = "You are not eligible to participate in this giveaway, because you joined this channel on **\(joinDate)**, which is before the contest started."
|
||||
case let .channelAdmin(adminId):
|
||||
let _ = adminId
|
||||
participation = "You are not eligible to participate in this giveaway, because you are an admin of participating channel (**\(peerName)**)."
|
||||
case let .disallowedCountry(countryCode):
|
||||
let _ = countryCode
|
||||
participation = "You are not eligible to participate in this giveaway, because your country is not included in the terms of the giveaway."
|
||||
}
|
||||
case .participating:
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
participation = "You are participating in this giveaway, because you have joined the channel **\(peerName)** (**\(giveaway.channelPeerIds.count - 1)** other listed channels)."
|
||||
} else {
|
||||
participation = "You are participating in this giveaway, because you have joined the channel **\(peerName)**."
|
||||
}
|
||||
case .almostOver:
|
||||
participation = presentationData.strings.Chat_Giveaway_Info_AlmostOver
|
||||
}
|
||||
|
||||
if !participation.isEmpty {
|
||||
participation = "\n\n\(participation)"
|
||||
}
|
||||
|
||||
text = "\(intro)\n\n\(ending)\(participation)"
|
||||
case let .finished(status, start, finish, _, activatedCount):
|
||||
let startDate = stringForDate(timestamp: start, strings: presentationData.strings)
|
||||
let finishDate = stringForDate(timestamp: finish, strings: presentationData.strings)
|
||||
title = presentationData.strings.Chat_Giveaway_Info_EndedTitle
|
||||
|
||||
let intro = "The giveaway was sponsored by the admins of **\(peerName)**, who acquired **\(giveaway.quantity) Telegram Premium** subscriptions for **\(giveaway.months)** months for its followers."
|
||||
|
||||
var ending: String
|
||||
if giveaway.flags.contains(.onlyNewSubscribers) {
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
ending = "On **\(finishDate)**, Telegram automatically selected **\(giveaway.quantity)** random users that joined **\(peerName)** and other listed channels after **\(startDate)**."
|
||||
} else {
|
||||
ending = "On **\(finishDate)**, Telegram automatically selected **\(giveaway.quantity)** random users that joined **\(peerName)** after **\(startDate)**."
|
||||
}
|
||||
} else {
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
ending = "On **\(finishDate)**, Telegram automatically selected **\(giveaway.quantity)** random subscribers of **\(peerName)** and other listed channels."
|
||||
} else {
|
||||
ending = "On **\(finishDate)**, Telegram automatically selected **\(giveaway.quantity)** random subscribers of **\(peerName)**."
|
||||
}
|
||||
}
|
||||
|
||||
if activatedCount > 0 {
|
||||
ending += " " + presentationData.strings.Chat_Giveaway_Info_ActivatedLinks(activatedCount)
|
||||
}
|
||||
|
||||
var result: String
|
||||
switch status {
|
||||
case .refunded:
|
||||
result = ""
|
||||
warning = presentationData.strings.Chat_Giveaway_Info_Refunded
|
||||
actions = [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Close, action: {
|
||||
dismissImpl?()
|
||||
})]
|
||||
case .notWon:
|
||||
result = "\n\n" + presentationData.strings.Chat_Giveaway_Info_DidntWin
|
||||
case let .won(slug):
|
||||
result = "\n\n" + presentationData.strings.Chat_Giveaway_Info_Won("🏆").string
|
||||
let _ = slug
|
||||
actions = [TextAlertAction(type: .defaultAction, title: presentationData.strings.Chat_Giveaway_Info_ViewPrize, action: {
|
||||
dismissImpl?()
|
||||
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||
dismissImpl?()
|
||||
})]
|
||||
}
|
||||
|
||||
text = "\(intro)\n\n\(ending)\(result)"
|
||||
}
|
||||
|
||||
let alertController = giveawayInfoAlertController(
|
||||
context: context,
|
||||
updatedPresentationData: updatedPresentationData,
|
||||
title: title,
|
||||
text: text,
|
||||
warning: warning,
|
||||
actions: actions
|
||||
)
|
||||
dismissImpl = { [weak alertController] in
|
||||
alertController?.dismissAnimated()
|
||||
}
|
||||
return alertController
|
||||
}
|
||||
|
||||
private final class GiveawayInfoAlertContentNode: AlertContentNode {
|
||||
private let title: String
|
||||
@ -229,7 +378,7 @@ private final class GiveawayInfoAlertContentNode: AlertContentNode {
|
||||
}
|
||||
}
|
||||
|
||||
func giveawayInfoAlertController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, title: String, text: String, warning: String?, actions: [TextAlertAction]) -> AlertController {
|
||||
private func giveawayInfoAlertController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, title: String, text: String, warning: String?, actions: [TextAlertAction]) -> AlertController {
|
||||
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
let contentNode = GiveawayInfoAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: presentationData.theme, title: title, text: text, warning: warning, actions: actions)
|
@ -186,8 +186,8 @@ public func PremiumBoostScreen(
|
||||
let controller = textAlertController(
|
||||
sharedContext: context.sharedContext,
|
||||
updatedPresentationData: nil,
|
||||
title: "More Boosts Needed",
|
||||
text: "To boost **\(peer.compactDisplayTitle)** again, gift **Telegram Premium** to a friend and get **\(premiumConfiguration.boostsPerGiftCount)** additional boosts.",
|
||||
title: presentationData.strings.ChannelBoost_MoreBoosts_Title,
|
||||
text: presentationData.strings.ChannelBoost_MoreBoosts_Text(peer.compactDisplayTitle, "\(premiumConfiguration.boostsPerGiftCount)").string,
|
||||
actions: [
|
||||
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})
|
||||
],
|
||||
|
@ -22,6 +22,7 @@ import TelegramStringFormatting
|
||||
import UndoUI
|
||||
import InvisibleInkDustNode
|
||||
|
||||
//TODO:localize
|
||||
private final class PremiumGiftCodeSheetContent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
|
@ -19,8 +19,6 @@ import PeerListItemComponent
|
||||
import TelegramStringFormatting
|
||||
import AvatarNode
|
||||
|
||||
//TODO:localize
|
||||
|
||||
private final class ReplaceBoostScreenComponent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
@ -172,7 +170,7 @@ private final class ReplaceBoostScreenComponent: CombinedComponent {
|
||||
if channelName.count > 48 {
|
||||
channelName = "\(channelName.prefix(48))..."
|
||||
}
|
||||
let descriptionString = "To boost **\(channelName)**, reassign a previous boost or gift **Telegram Premium** to a friend to get **\(premiumConfiguration.boostsPerGiftCount)** additional boosts."
|
||||
let descriptionString = strings.ReassignBoost_Description(channelName, "\(premiumConfiguration.boostsPerGiftCount)").string
|
||||
|
||||
let description = description.update(
|
||||
component: MultilineTextComponent(
|
||||
@ -204,11 +202,11 @@ private final class ReplaceBoostScreenComponent: CombinedComponent {
|
||||
if let cooldownUntil = boost.cooldownUntil, cooldownUntil > state.currentTime {
|
||||
let duration = cooldownUntil - state.currentTime
|
||||
let durationValue = stringForDuration(duration, position: nil)
|
||||
subtitle = "Available in \(durationValue)"
|
||||
subtitle = strings.ReassignBoost_AvailableIn(durationValue).string
|
||||
isEnabled = false
|
||||
} else {
|
||||
let expiresValue = stringForDate(timestamp: boost.expires, strings: strings)
|
||||
subtitle = "Boost expires on \(expiresValue)"
|
||||
subtitle = strings.ReassignBoost_ExpiresOn(expiresValue).string
|
||||
}
|
||||
|
||||
let accountContext = context.component.context
|
||||
@ -245,7 +243,8 @@ private final class ReplaceBoostScreenComponent: CombinedComponent {
|
||||
selectedSlotsUpdated(state.selectedSlots)
|
||||
} else {
|
||||
let presentationData = accountContext.sharedContext.currentPresentationData.with { $0 }
|
||||
let undoController = UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: "Wait until the boost is available or get **3** more boosts by gifting a **Telegram Premium** subscription.", timeout: nil, customUndoText: nil), elevatedLayout: false, position: .top, action: { _ in return true })
|
||||
|
||||
let undoController = UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: strings.ReassignBoost_WaitForCooldown("\(premiumConfiguration.boostsPerGiftCount)").string, timeout: nil, customUndoText: nil), elevatedLayout: false, position: .top, action: { _ in return true })
|
||||
presentController(undoController)
|
||||
}
|
||||
})
|
||||
@ -559,7 +558,7 @@ public class ReplaceBoostScreen: ViewController {
|
||||
let footerInsets = UIEdgeInsets(top: 0.0, left: layout.safeInsets.left, bottom: layout.intrinsicInsets.bottom, right: layout.safeInsets.right)
|
||||
|
||||
transition.setFrame(view: self.footerView, frame: CGRect(origin: CGPoint(x: 0.0, y: -topInset), size: layout.size))
|
||||
self.footerHeight = self.footerView.update(size: layout.size, insets: footerInsets, theme: self.presentationData.theme, count: Int32(self.selectedSlots.count))
|
||||
self.footerHeight = self.footerView.update(size: layout.size, insets: footerInsets, theme: self.presentationData.theme, strings: self.presentationData.strings, count: Int32(self.selectedSlots.count))
|
||||
|
||||
if !hadLayout {
|
||||
self.updateFooterAlpha()
|
||||
@ -838,9 +837,9 @@ public class ReplaceBoostScreen: ViewController {
|
||||
presentControllerImpl?(c)
|
||||
}))
|
||||
|
||||
self.title = "Reassign Boosts"
|
||||
self.title = presentationData.strings.ReassignBoost_Title
|
||||
|
||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: presentationData.strings.Common_Close, style: .plain, target: self, action: #selector(self.cancelPressed))
|
||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed))
|
||||
|
||||
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||
|
||||
@ -984,10 +983,10 @@ private final class FooterView: UIView {
|
||||
|
||||
fileprivate var inProgress = false
|
||||
|
||||
private var currentLayout: (CGSize, UIEdgeInsets, PresentationTheme, Int32)?
|
||||
func update(size: CGSize, insets: UIEdgeInsets, theme: PresentationTheme, count: Int32) -> CGFloat {
|
||||
private var currentLayout: (CGSize, UIEdgeInsets, PresentationTheme, PresentationStrings, Int32)?
|
||||
func update(size: CGSize, insets: UIEdgeInsets, theme: PresentationTheme, strings: PresentationStrings, count: Int32) -> CGFloat {
|
||||
let hadLayout = self.currentLayout != nil
|
||||
self.currentLayout = (size, insets, theme, count)
|
||||
self.currentLayout = (size, insets, theme, strings, count)
|
||||
|
||||
self.backgroundNode.updateColor(color: theme.rootController.tabBar.backgroundColor, transition: .immediate)
|
||||
self.separatorView.backgroundColor = theme.rootController.tabBar.separatorColor
|
||||
@ -1019,7 +1018,7 @@ private final class FooterView: UIView {
|
||||
content: AnyComponentWithIdentity(
|
||||
id: AnyHashable(0),
|
||||
component: AnyComponent(ButtonTextContentComponent(
|
||||
text: "Reassign Boosts",
|
||||
text: strings.ReassignBoost_ReassignBoosts,
|
||||
badge: Int(count),
|
||||
textColor: theme.list.itemCheckColors.foregroundColor,
|
||||
badgeBackground: theme.list.itemCheckColors.foregroundColor,
|
||||
@ -1036,8 +1035,8 @@ private final class FooterView: UIView {
|
||||
return
|
||||
}
|
||||
self.inProgress = true
|
||||
if let (size, insets, theme, count) = self.currentLayout {
|
||||
let _ = self.update(size: size, insets: insets, theme: theme, count: count)
|
||||
if let (size, insets, theme, strings, count) = self.currentLayout {
|
||||
let _ = self.update(size: size, insets: insets, theme: theme, strings: strings, count: count)
|
||||
}
|
||||
self.action()
|
||||
}
|
||||
|
@ -554,15 +554,15 @@ private enum StatsEntry: ItemListNodeEntry {
|
||||
let expiresString: String
|
||||
|
||||
let durationMonths = Int32(round(Float(boost.expires - boost.date) / (86400.0 * 30.0)))
|
||||
let durationString = "\(durationMonths)m"
|
||||
let durationString = presentationData.strings.Stats_Boosts_ShortMonth("\(durationMonths)").string
|
||||
|
||||
let title: String
|
||||
let icon: GiftOptionItem.Icon
|
||||
var label: String?
|
||||
if boost.flags.contains(.isGiveaway) {
|
||||
label = "🏆 Giveaway"
|
||||
label = "🏆 \(presentationData.strings.Stats_Boosts_Giveaway)"
|
||||
} else if boost.flags.contains(.isGift) {
|
||||
label = "🎁 Gift"
|
||||
label = "🎁 \(presentationData.strings.Stats_Boosts_Gift)"
|
||||
}
|
||||
|
||||
let color: GiftOptionItem.Icon.Color
|
||||
@ -575,7 +575,7 @@ private enum StatsEntry: ItemListNodeEntry {
|
||||
}
|
||||
|
||||
if boost.flags.contains(.isUnclaimed) {
|
||||
title = "Unclaimed"
|
||||
title = presentationData.strings.Stats_Boosts_Unclaimed
|
||||
icon = .image(color: color, name: "Premium/Unclaimed")
|
||||
expiresString = "\(durationString) • \(expiresValue)"
|
||||
} else if let peer = boost.peer {
|
||||
@ -588,10 +588,10 @@ private enum StatsEntry: ItemListNodeEntry {
|
||||
}
|
||||
} else {
|
||||
if boost.flags.contains(.isUnclaimed) {
|
||||
title = "Unclaimed"
|
||||
title = presentationData.strings.Stats_Boosts_Unclaimed
|
||||
icon = .image(color: color, name: "Premium/Unclaimed")
|
||||
} else if boost.flags.contains(.isGiveaway) {
|
||||
title = "To be distributed"
|
||||
title = presentationData.strings.Stats_Boosts_ToBeDistributed
|
||||
icon = .image(color: color, name: "Premium/ToBeDistributed")
|
||||
} else {
|
||||
title = "Unknown"
|
||||
@ -774,15 +774,14 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
|
||||
entries.append(.boostOverviewTitle(presentationData.theme, presentationData.strings.Stats_Boosts_OverviewHeader))
|
||||
entries.append(.boostOverview(presentationData.theme, boostData))
|
||||
|
||||
//TODO:localize
|
||||
if !boostData.prepaidGiveaways.isEmpty {
|
||||
entries.append(.boostPrepaidTitle(presentationData.theme, "PREPAID GIVEAWAYS"))
|
||||
entries.append(.boostPrepaidTitle(presentationData.theme, presentationData.strings.Stats_Boosts_PrepaidGiveawaysTitle))
|
||||
var i: Int32 = 0
|
||||
for giveaway in boostData.prepaidGiveaways {
|
||||
entries.append(.boostPrepaid(i, presentationData.theme, "\(giveaway.quantity) Telegram Premium", "\(giveaway.months)-month subscriptions", giveaway))
|
||||
entries.append(.boostPrepaid(i, presentationData.theme, presentationData.strings.Stats_Boosts_PrepaidGiveawayCount(giveaway.quantity), presentationData.strings.Stats_Boosts_PrepaidGiveawayMonths("\(giveaway.months)").string, giveaway))
|
||||
i += 1
|
||||
}
|
||||
entries.append(.boostPrepaidInfo(presentationData.theme, "Select a giveaway you already paid for to set it up."))
|
||||
entries.append(.boostPrepaidInfo(presentationData.theme, presentationData.strings.Stats_Boosts_PrepaidGiveawaysInfo))
|
||||
}
|
||||
|
||||
let boostersTitle: String
|
||||
@ -813,7 +812,7 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
|
||||
}
|
||||
|
||||
if boostsCount > 0 && giftsCount > 0 && boostsCount != giftsCount {
|
||||
entries.append(.boosterTabs(presentationData.theme, "\(boostsCount) Boosts", "\(giftsCount) Gifts", state.giftsSelected))
|
||||
entries.append(.boosterTabs(presentationData.theme, presentationData.strings.Stats_Boosts_TabBoosts(boostsCount), presentationData.strings.Stats_Boosts_TabGifts(giftsCount), state.giftsSelected))
|
||||
}
|
||||
|
||||
let selectedState: ChannelBoostersContext.State?
|
||||
@ -853,8 +852,8 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
|
||||
entries.append(.boostLinkInfo(presentationData.theme, presentationData.strings.Stats_Boosts_LinkInfo))
|
||||
|
||||
if giveawayAvailable {
|
||||
entries.append(.gifts(presentationData.theme, "Get Boosts via Gifts"))
|
||||
entries.append(.giftsInfo(presentationData.theme, "Get more boosts for your channel by gifting Premium to your subscribers."))
|
||||
entries.append(.gifts(presentationData.theme, presentationData.strings.Stats_Boosts_GetBoosts))
|
||||
entries.append(.giftsInfo(presentationData.theme, presentationData.strings.Stats_Boosts_GetBoostsInfo))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,6 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
override public func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, unboundSize: CGSize?, maxWidth: CGFloat, layout: (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) {
|
||||
let makeLabelLayout = TextNode.asyncLayout(self.labelNode)
|
||||
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
|
||||
@ -226,24 +225,24 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
textSpacing += 13.0
|
||||
|
||||
if unclaimed {
|
||||
title = "Unclaimed Prize"
|
||||
title = item.presentationData.strings.Notification_PremiumPrize_Unclaimed
|
||||
} else {
|
||||
title = "Congratulations!"
|
||||
title = item.presentationData.strings.Notification_PremiumPrize_Title
|
||||
}
|
||||
var peerName = ""
|
||||
if let channelId, let channel = item.message.peers[channelId] {
|
||||
peerName = EnginePeer(channel).compactDisplayTitle
|
||||
}
|
||||
if unclaimed {
|
||||
text = "You have an unclaimed prize from a giveaway by **\(peerName)**.\n\nThis prize is a **Telegram Premium** subscription for **\(monthsValue)** months."
|
||||
text = item.presentationData.strings.Notification_PremiumPrize_UnclaimedText(peerName, item.presentationData.strings.Notification_PremiumPrize_Months(monthsValue)).string
|
||||
} else if fromGiveaway {
|
||||
text = "You won a prize in a giveaway organized by **\(peerName)**.\n\nYour prize is a **Telegram Premium** subscription for **\(monthsValue)** months."
|
||||
text = item.presentationData.strings.Notification_PremiumPrize_GiveawayText(peerName, item.presentationData.strings.Notification_PremiumPrize_Months(monthsValue)).string
|
||||
} else {
|
||||
text = "You've received a gift from **\(peerName)**.\n\nYour gift is a **Telegram Premium** subscription for **\(monthsValue)** months."
|
||||
text = item.presentationData.strings.Notification_PremiumPrize_GiftText(peerName, item.presentationData.strings.Notification_PremiumPrize_Months(monthsValue)).string
|
||||
}
|
||||
|
||||
months = monthsValue
|
||||
buttonTitle = "Open Gift Link"
|
||||
buttonTitle = item.presentationData.strings.Notification_PremiumPrize_View
|
||||
hasServiceMessage = false
|
||||
default:
|
||||
break
|
||||
|
@ -25,7 +25,6 @@ import TelegramUIPreferences
|
||||
import UndoUI
|
||||
import TelegramStringFormatting
|
||||
|
||||
//TODO:localize
|
||||
final class ShareWithPeersScreenComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
@ -941,9 +940,9 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
sectionTitle = environment.strings.Story_Privacy_WhoCanViewHeader
|
||||
} else if section.id == 1 {
|
||||
if case .members = component.stateContext.subject {
|
||||
sectionTitle = "SUBSCRIBERS"
|
||||
sectionTitle = environment.strings.BoostGift_Subscribers_SectionTitle
|
||||
} else if case .channels = component.stateContext.subject {
|
||||
sectionTitle = "CHANNELS"
|
||||
sectionTitle = environment.strings.BoostGift_Channels_SectionTitle
|
||||
} else {
|
||||
sectionTitle = environment.strings.Story_Privacy_ContactsHeader
|
||||
}
|
||||
@ -1390,7 +1389,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
} else {
|
||||
if case .members = component.stateContext.subject {
|
||||
if let invitedAt = stateValue.invitedAt[peer.id] {
|
||||
subtitle = "joined \(stringForMediumDate(timestamp: invitedAt, strings: environment.strings, dateTimeFormat: environment.dateTimeFormat))"
|
||||
subtitle = environment.strings.BoostGift_Subscribers_Joined(stringForMediumDate(timestamp: invitedAt, strings: environment.strings, dateTimeFormat: environment.dateTimeFormat)).string
|
||||
} else {
|
||||
subtitle = nil
|
||||
}
|
||||
@ -1445,7 +1444,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
self.hapticFeedback.error()
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: "You can select maximum \(component.context.userLimits.maxGiveawayChannelsCount) channels.", timeout: nil, customUndoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: environment.strings.BoostGift_Channels_MaximumReached("\(component.context.userLimits.maxGiveawayChannelsCount)").string, timeout: nil, customUndoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
return
|
||||
}
|
||||
if case .channels = component.stateContext.subject {
|
||||
@ -1453,11 +1452,11 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
let alertController = textAlertController(
|
||||
context: component.context,
|
||||
forceTheme: environment.theme,
|
||||
title: "Channel is Private",
|
||||
text: "Are you sure you want to add a private channel? Users won't be able to join it without an invite link.",
|
||||
title: environment.strings.BoostGift_Channels_PrivateChannel_Title,
|
||||
text: environment.strings.BoostGift_Channels_PrivateChannel_Text,
|
||||
actions: [
|
||||
TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {}),
|
||||
TextAlertAction(type: .defaultAction, title: "Add", action: {
|
||||
TextAlertAction(type: .defaultAction, title: environment.strings.BoostGift_Channels_PrivateChannel_Add, action: {
|
||||
togglePeer()
|
||||
})
|
||||
]
|
||||
@ -1475,7 +1474,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
self.hapticFeedback.error()
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: "You can select maximum 10 subscribers.", timeout: nil, customUndoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: environment.strings.BoostGift_Subscribers_MaximumReached("\(10)").string, timeout: nil, customUndoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
return
|
||||
}
|
||||
togglePeer()
|
||||
@ -2018,9 +2017,9 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
let placeholder: String
|
||||
switch component.stateContext.subject {
|
||||
case .members:
|
||||
placeholder = "Search Subscribers"
|
||||
placeholder = environment.strings.BoostGift_Subscribers_Search
|
||||
case .channels:
|
||||
placeholder = "Search Channels"
|
||||
placeholder = environment.strings.BoostGift_Channels_Search
|
||||
case .chats:
|
||||
placeholder = environment.strings.Story_Privacy_SearchChats
|
||||
default:
|
||||
@ -2367,13 +2366,13 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
case .contactsSearch:
|
||||
title = ""
|
||||
case .members:
|
||||
title = "Gift Premium"
|
||||
actionButtonTitle = "Save Recipients"
|
||||
subtitle = "select up to 10 subscribers"
|
||||
title = environment.strings.BoostGift_Subscribers_Title
|
||||
subtitle = environment.strings.BoostGift_Subscribers_Subtitle("\(10)").string
|
||||
actionButtonTitle = environment.strings.BoostGift_Subscribers_Save
|
||||
case .channels:
|
||||
title = "Add Channels"
|
||||
actionButtonTitle = "Save Channels"
|
||||
subtitle = "select up to \(component.context.userLimits.maxGiveawayChannelsCount) channels"
|
||||
title = environment.strings.BoostGift_Channels_Title
|
||||
subtitle = environment.strings.BoostGift_Channels_Subtitle("\(component.context.userLimits.maxGiveawayChannelsCount)").string
|
||||
actionButtonTitle = environment.strings.BoostGift_Channels_Save
|
||||
}
|
||||
|
||||
let titleComponent: AnyComponent<Empty>
|
||||
|
@ -180,8 +180,6 @@ final class MediaNavigationStripComponent: Component {
|
||||
let itemHeight: CGFloat = 2.0
|
||||
let minItemWidth: CGFloat = 2.0
|
||||
|
||||
var size = CGSize(width: availableSize.width, height: itemHeight)
|
||||
|
||||
var didSetCompletion = false
|
||||
|
||||
var validIndices: [Int] = []
|
||||
@ -223,7 +221,6 @@ final class MediaNavigationStripComponent: Component {
|
||||
var itemFrame = CGRect(origin: CGPoint(x: -globalOffset + CGFloat(i) * (itemWidth + spacing), y: 0.0), size: CGSize(width: itemWidth, height: itemHeight))
|
||||
if component.isSeeking {
|
||||
itemFrame = CGRect(origin: .zero, size: CGSize(width: availableSize.width, height: 6.0))
|
||||
size.height = itemFrame.height
|
||||
}
|
||||
if itemFrame.maxX < 0.0 || itemFrame.minX >= availableSize.width {
|
||||
continue
|
||||
|
@ -546,6 +546,14 @@ private final class StoryContainerScreenComponent: Component {
|
||||
}
|
||||
self.initialSeekTimestamp = nil
|
||||
self.previousSeekTime = nil
|
||||
|
||||
guard let stateValue = self.stateValue, let slice = stateValue.slice, let itemSetView = self.visibleItemSetViews[slice.peer.id], let itemSetComponentView = itemSetView.view.view as? StoryItemSetContainerComponent.View else {
|
||||
return
|
||||
}
|
||||
guard let visibleItemView = itemSetComponentView.visibleItems[slice.item.storyItem.id]?.view.view as? StoryItemContentComponent.View else {
|
||||
return
|
||||
}
|
||||
visibleItemView.seekEnded()
|
||||
}
|
||||
longPressRecognizer.shouldBegin = { [weak self] touch in
|
||||
guard let self else {
|
||||
|
@ -95,12 +95,13 @@ final class StoryInteractionGuideComponent: Component {
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
let strings = component.strings
|
||||
|
||||
let sideInset: CGFloat = 48.0
|
||||
|
||||
//TODO:localize
|
||||
let titleSize = self.titleLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "Watching Stories", font: Font.semibold(20.0), textColor: .white, paragraphAlignment: .center)))),
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: strings.Story_Guide_Title, font: Font.semibold(20.0), textColor: .white, paragraphAlignment: .center)))),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: availableSize.height)
|
||||
)
|
||||
@ -114,7 +115,7 @@ final class StoryInteractionGuideComponent: Component {
|
||||
|
||||
let textSize = self.descriptionLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(BalancedTextComponent(text: .plain(NSAttributedString(string: "You can use these gestures to control playback.", font: Font.regular(15.0), textColor: UIColor(rgb: 0xffffff, alpha: 0.6), paragraphAlignment: .center)), maximumNumberOfLines: 0, lineSpacing: 0.2)),
|
||||
component: AnyComponent(BalancedTextComponent(text: .plain(NSAttributedString(string: strings.Story_Guide_Description, font: Font.regular(15.0), textColor: UIColor(rgb: 0xffffff, alpha: 0.6), paragraphAlignment: .center)), maximumNumberOfLines: 0, lineSpacing: 0.2)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: availableSize.height)
|
||||
)
|
||||
@ -132,8 +133,8 @@ final class StoryInteractionGuideComponent: Component {
|
||||
component: AnyComponent(
|
||||
GuideItemComponent(
|
||||
context: component.context,
|
||||
title: "Go forward",
|
||||
text: "Tap the screen",
|
||||
title: strings.Story_Guide_ForwardTitle,
|
||||
text: strings.Story_Guide_ForwardDescription,
|
||||
animationName: "story_forward",
|
||||
isPlaying: self.currentIndex == 0,
|
||||
playbackCompleted: { [weak self] in
|
||||
@ -151,8 +152,8 @@ final class StoryInteractionGuideComponent: Component {
|
||||
component: AnyComponent(
|
||||
GuideItemComponent(
|
||||
context: component.context,
|
||||
title: "Pause and Seek",
|
||||
text: "Hold and move sideways",
|
||||
title: strings.Story_Guide_PauseTitle,
|
||||
text: strings.Story_Guide_PauseDescription,
|
||||
animationName: "story_pause",
|
||||
isPlaying: self.currentIndex == 1,
|
||||
playbackCompleted: { [weak self] in
|
||||
@ -170,8 +171,8 @@ final class StoryInteractionGuideComponent: Component {
|
||||
component: AnyComponent(
|
||||
GuideItemComponent(
|
||||
context: component.context,
|
||||
title: "Go back",
|
||||
text: "Tap the left edge",
|
||||
title: strings.Story_Guide_BackTitle,
|
||||
text: strings.Story_Guide_BackDescription,
|
||||
animationName: "story_back",
|
||||
isPlaying: self.currentIndex == 2,
|
||||
playbackCompleted: { [weak self] in
|
||||
@ -189,8 +190,8 @@ final class StoryInteractionGuideComponent: Component {
|
||||
component: AnyComponent(
|
||||
GuideItemComponent(
|
||||
context: component.context,
|
||||
title: "Move between stories",
|
||||
text: "Swipe left or right",
|
||||
title: strings.Story_Guide_MoveTitle,
|
||||
text: strings.Story_Guide_MoveDescription,
|
||||
animationName: "story_move",
|
||||
isPlaying: self.currentIndex == 3,
|
||||
playbackCompleted: { [weak self] in
|
||||
@ -222,7 +223,7 @@ final class StoryInteractionGuideComponent: Component {
|
||||
let buttonSize = self.proceedButton.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(Button(
|
||||
content: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "Tap to keep watching", font: Font.semibold(17.0), textColor: .white, paragraphAlignment: .center)))),
|
||||
content: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: strings.Story_Guide_Proceed, font: Font.semibold(17.0), textColor: .white, paragraphAlignment: .center)))),
|
||||
action: { [weak self] in
|
||||
self?.handleTap()
|
||||
}
|
||||
|
@ -277,7 +277,9 @@ final class StoryItemContentComponent: Component {
|
||||
}
|
||||
|
||||
self.videoPlaybackStatus = status
|
||||
self.updateVideoPlaybackProgress()
|
||||
if !self.isSeeking {
|
||||
self.updateVideoPlaybackProgress()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -360,7 +362,9 @@ final class StoryItemContentComponent: Component {
|
||||
}
|
||||
|
||||
if case .file = self.currentMessageMedia {
|
||||
self.updateVideoPlaybackProgress()
|
||||
if !self.isSeeking {
|
||||
self.updateVideoPlaybackProgress()
|
||||
}
|
||||
} else {
|
||||
if !self.markedAsSeen {
|
||||
self.markedAsSeen = true
|
||||
@ -536,6 +540,7 @@ final class StoryItemContentComponent: Component {
|
||||
)
|
||||
}
|
||||
|
||||
private var isSeeking = false
|
||||
func seekTo(_ timestamp: Double, apply: Bool) {
|
||||
guard let videoNode = self.videoNode else {
|
||||
return
|
||||
@ -543,9 +548,14 @@ final class StoryItemContentComponent: Component {
|
||||
if apply {
|
||||
videoNode.seek(timestamp)
|
||||
}
|
||||
self.isSeeking = true
|
||||
self.updateVideoPlaybackProgress(timestamp)
|
||||
}
|
||||
|
||||
func seekEnded() {
|
||||
self.isSeeking = false
|
||||
}
|
||||
|
||||
func update(component: StoryItemContentComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<StoryContentItem.Environment>, transition: Transition) -> CGSize {
|
||||
let previousItem = self.component?.item
|
||||
|
||||
|
@ -4710,7 +4710,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
|
||||
let seekLabelSize = self.seekLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(Text(text: "Slide left or right to seek", font: Font.semibold(14.0), color: .white)),
|
||||
component: AnyComponent(Text(text: component.strings.Story_SlideToSeek, font: Font.semibold(14.0), color: .white)),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
|
@ -4787,17 +4787,16 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
case let .ongoing(_, status):
|
||||
switch status {
|
||||
case .notAllowed:
|
||||
content = .info(title: nil, text: "You can't participate in this giveaway.", timeout: nil, customUndoText: "Learn More")
|
||||
content = .info(title: nil, text: self.presentationData.strings.Chat_Giveaway_Toast_NotAllowed, timeout: nil, customUndoText: self.presentationData.strings.Chat_Giveaway_Toast_LearnMore)
|
||||
case .participating:
|
||||
content = .succeed(text: "You are participating in this giveaway.", timeout: nil, customUndoText: "Learn More")
|
||||
content = .succeed(text: self.presentationData.strings.Chat_Giveaway_Toast_Participating, timeout: nil, customUndoText: self.presentationData.strings.Chat_Giveaway_Toast_LearnMore)
|
||||
case .notQualified:
|
||||
content = .info(title: nil, text: "You are not qualified for this giveaway yet.", timeout: nil, customUndoText: "Learn More")
|
||||
content = .info(title: nil, text: self.presentationData.strings.Chat_Giveaway_Toast_NotQualified, timeout: nil, customUndoText: self.presentationData.strings.Chat_Giveaway_Toast_LearnMore)
|
||||
case .almostOver:
|
||||
content = .info(title: nil, text: "The giveaway is almost over.", timeout: nil, customUndoText: "Learn More")
|
||||
content = .info(title: nil, text: self.presentationData.strings.Chat_Giveaway_Toast_AlmostOver, timeout: nil, customUndoText: self.presentationData.strings.Chat_Giveaway_Toast_LearnMore)
|
||||
}
|
||||
case let .finished(status, _, _, _, _):
|
||||
let _ = status
|
||||
content = .info(title: nil, text: "The giveaway is ended.", timeout: nil, customUndoText: "Learn More")
|
||||
case .finished:
|
||||
content = .info(title: nil, text: self.presentationData.strings.Chat_Giveaway_Toast_Ended, timeout: nil, customUndoText: self.presentationData.strings.Chat_Giveaway_Toast_LearnMore)
|
||||
}
|
||||
let controller = UndoOverlayController(presentationData: self.presentationData, content: content, elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { [weak self] action in
|
||||
if case .undo = action, let self {
|
||||
@ -19563,150 +19562,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
func displayGiveawayStatusInfo(messageId: EngineMessage.Id, giveawayInfo: PremiumGiveawayInfo) {
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] message in
|
||||
guard let self, let message, let giveaway = message.media.first(where: { $0 is TelegramMediaGiveaway }) as? TelegramMediaGiveaway else {
|
||||
guard let self, let message else {
|
||||
return
|
||||
}
|
||||
var peerName = ""
|
||||
if let peerId = giveaway.channelPeerIds.first, let peer = message.peers[peerId] {
|
||||
peerName = EnginePeer(peer).compactDisplayTitle
|
||||
}
|
||||
|
||||
let untilDate = stringForDate(timestamp: giveaway.untilDate, strings: self.presentationData.strings)
|
||||
|
||||
let title: String
|
||||
let text: String
|
||||
var warning: String?
|
||||
|
||||
var dismissImpl: (() -> Void)?
|
||||
|
||||
var actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {
|
||||
dismissImpl?()
|
||||
})]
|
||||
|
||||
switch giveawayInfo {
|
||||
case let .ongoing(start, status):
|
||||
let startDate = stringForDate(timestamp: start, strings: self.presentationData.strings)
|
||||
|
||||
title = "About This Giveaway"
|
||||
|
||||
let intro: String
|
||||
if case .almostOver = status {
|
||||
intro = "The giveaway was sponsored by the admins of **\(peerName)**, who acquired **\(giveaway.quantity) Telegram Premium** subscriptions for **\(giveaway.months)** months for its followers."
|
||||
} else {
|
||||
intro = "The giveaway is sponsored by the admins of **\(peerName)**, who acquired **\(giveaway.quantity) Telegram Premium** subscriptions for **\(giveaway.months)** months for its followers."
|
||||
}
|
||||
|
||||
let ending: String
|
||||
if giveaway.flags.contains(.onlyNewSubscribers) {
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
ending = "On **\(untilDate)**, Telegram will automatically select **\(giveaway.quantity)** random users that joined **\(peerName)** and **\(giveaway.channelPeerIds.count - 1)** other listed channels after **\(startDate)**."
|
||||
} else {
|
||||
ending = "On **\(untilDate)**, Telegram will automatically select **\(giveaway.quantity)** random users that joined **\(peerName)** after **\(startDate)**."
|
||||
}
|
||||
} else {
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
ending = "On **\(untilDate)**, Telegram will automatically select **\(giveaway.quantity)** random subscribers of **\(peerName)** and **\(giveaway.channelPeerIds.count - 1)** other listed channels."
|
||||
} else {
|
||||
ending = "On **\(untilDate)**, Telegram will automatically select **\(giveaway.quantity)** random subscribers of **\(peerName)**."
|
||||
}
|
||||
}
|
||||
|
||||
var participation: String
|
||||
switch status {
|
||||
case .notQualified:
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
participation = "To take part in this giveaway please join the channel **\(peerName)** (**\(giveaway.channelPeerIds.count - 1)** other listed channels) before **\(untilDate)**."
|
||||
} else {
|
||||
participation = "To take part in this giveaway please join the channel **\(peerName)** before **\(untilDate)**."
|
||||
}
|
||||
case let .notAllowed(reason):
|
||||
switch reason {
|
||||
case let .joinedTooEarly(joinedOn):
|
||||
let joinDate = stringForDate(timestamp: joinedOn, strings: self.presentationData.strings)
|
||||
participation = "You are not eligible to participate in this giveaway, because you joined this channel on **\(joinDate)**, which is before the contest started."
|
||||
case let .channelAdmin(adminId):
|
||||
let _ = adminId
|
||||
participation = "You are not eligible to participate in this giveaway, because you are an admin of participating channel (**\(peerName)**)."
|
||||
case let .disallowedCountry(countryCode):
|
||||
let _ = countryCode
|
||||
participation = "You are not eligible to participate in this giveaway, because your country is not included in the terms of the giveaway."
|
||||
}
|
||||
case .participating:
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
participation = "You are participating in this giveaway, because you have joined the channel **\(peerName)** (**\(giveaway.channelPeerIds.count - 1)** other listed channels)."
|
||||
} else {
|
||||
participation = "You are participating in this giveaway, because you have joined the channel **\(peerName)**."
|
||||
}
|
||||
case .almostOver:
|
||||
participation = "The giveaway is over, preparing results."
|
||||
}
|
||||
|
||||
if !participation.isEmpty {
|
||||
participation = "\n\n\(participation)"
|
||||
}
|
||||
|
||||
text = "\(intro)\n\n\(ending)\(participation)"
|
||||
case let .finished(status, start, finish, _, activatedCount):
|
||||
let startDate = stringForDate(timestamp: start, strings: self.presentationData.strings)
|
||||
let finishDate = stringForDate(timestamp: finish, strings: self.presentationData.strings)
|
||||
title = "Giveaway Ended"
|
||||
|
||||
let intro = "The giveaway was sponsored by the admins of **\(peerName)**, who acquired **\(giveaway.quantity) Telegram Premium** subscriptions for **\(giveaway.months)** months for its followers."
|
||||
|
||||
var ending: String
|
||||
if giveaway.flags.contains(.onlyNewSubscribers) {
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
ending = "On **\(finishDate)**, Telegram automatically selected **\(giveaway.quantity)** random users that joined **\(peerName)** and other listed channels after **\(startDate)**."
|
||||
} else {
|
||||
ending = "On **\(finishDate)**, Telegram automatically selected **\(giveaway.quantity)** random users that joined **\(peerName)** after **\(startDate)**."
|
||||
}
|
||||
} else {
|
||||
if giveaway.channelPeerIds.count > 1 {
|
||||
ending = "On **\(finishDate)**, Telegram automatically selected **\(giveaway.quantity)** random subscribers of **\(peerName)** and other listed channels."
|
||||
} else {
|
||||
ending = "On **\(finishDate)**, Telegram automatically selected **\(giveaway.quantity)** random subscribers of **\(peerName)**."
|
||||
}
|
||||
}
|
||||
|
||||
if activatedCount > 0 {
|
||||
ending += " \(activatedCount) of the winners already used their gift links."
|
||||
}
|
||||
|
||||
var result: String
|
||||
switch status {
|
||||
case .refunded:
|
||||
result = ""
|
||||
warning = "The channel cancelled the prizes by reversing the payment for them."
|
||||
actions = [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_Close, action: {
|
||||
dismissImpl?()
|
||||
})]
|
||||
case .notWon:
|
||||
result = "\n\nYou didn't win a prize in this giveaway."
|
||||
case let .won(slug):
|
||||
result = "\n\nYou won a prize in this giveaway. 🏆"
|
||||
let _ = slug
|
||||
actions = [TextAlertAction(type: .defaultAction, title: "View My Prize", action: {
|
||||
dismissImpl?()
|
||||
}), TextAlertAction(type: .genericAction, title: self.presentationData.strings.Common_Cancel, action: {
|
||||
dismissImpl?()
|
||||
})]
|
||||
}
|
||||
|
||||
text = "\(intro)\n\n\(ending)\(result)"
|
||||
}
|
||||
|
||||
let alertController = giveawayInfoAlertController(
|
||||
context: self.context,
|
||||
updatedPresentationData: self.updatedPresentationData,
|
||||
title: title,
|
||||
text: text,
|
||||
warning: warning,
|
||||
actions: actions
|
||||
)
|
||||
self.present(alertController, in: .window(.root))
|
||||
|
||||
dismissImpl = { [weak alertController] in
|
||||
alertController?.dismissAnimated()
|
||||
if let controller = giveawayInfoController(context: self.context, updatedPresentationData: self.updatedPresentationData, message: message, giveawayInfo: giveawayInfo) {
|
||||
self.present(controller, in: .window(.root))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user