Skip to content

Commit 313833b

Browse files
author
Isaac
committed
Merge commit 'c5081979f04f4c165d9572a7e50eb769af6dc5c8'
2 parents 46d9465 + c508197 commit 313833b

File tree

12 files changed

+189
-46
lines changed

12 files changed

+189
-46
lines changed

Telegram/Telegram-iOS/en.lproj/Localizable.strings

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14293,3 +14293,6 @@ Sorry for the inconvenience.";
1429314293

1429414294
"Gift.Resale.Unavailable.Title" = "Resell Gift";
1429514295
"Gift.Resale.Unavailable.Text" = "Sorry, you can't list this gift yet.\n\Reselling will be available on %@.";
14296+
14297+
"Gift.Transfer.Unavailable.Title" = "Transfer Gift";
14298+
"Gift.Transfer.Unavailable.Text" = "Sorry, you can't transfer this gift yet.\n\Transferring will be available on %@.";

submodules/AccountContext/Sources/Premium.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ public enum PremiumLimitSubject {
101101
case membershipInSharedFolders
102102
case channels
103103
case expiringStories
104+
case multiStories
104105
case storiesWeekly
105106
case storiesMonthly
106107
case storiesChannelBoost(peer: EnginePeer, isCurrent: Bool, level: Int32, currentLevelBoosts: Int32, nextLevelBoosts: Int32?, link: String?, myBoostCount: Int32, canBoostAgain: Bool)

submodules/MediaPickerUI/Sources/MediaPickerScreen.swift

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,10 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
388388

389389
self.itemsDisposable = (updatedState
390390
|> deliverOnMainQueue).start(next: { [weak self] state in
391-
guard let strongSelf = self else {
391+
guard let self else {
392392
return
393393
}
394-
strongSelf.updateState(state)
394+
self.updateState(state)
395395
})
396396

397397
self.gridNode.scrollingInitiated = { [weak self] in
@@ -404,15 +404,16 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
404404

405405
self.hiddenMediaDisposable = (self.hiddenMediaId.get()
406406
|> deliverOnMainQueue).start(next: { [weak self] id in
407-
if let strongSelf = self {
408-
strongSelf.controller?.interaction?.hiddenMediaId = id
409-
strongSelf.gridNode.forEachItemNode { itemNode in
410-
if let itemNode = itemNode as? MediaPickerGridItemNode {
411-
itemNode.updateHiddenMedia()
412-
}
407+
guard let self else {
408+
return
409+
}
410+
self.controller?.interaction?.hiddenMediaId = id
411+
self.gridNode.forEachItemNode { itemNode in
412+
if let itemNode = itemNode as? MediaPickerGridItemNode {
413+
itemNode.updateHiddenMedia()
413414
}
414-
strongSelf.selectionNode?.updateHiddenMedia()
415415
}
416+
self.selectionNode?.updateHiddenMedia()
416417
})
417418

418419
if let selectionState = self.controller?.interaction?.selectionState {
@@ -431,8 +432,8 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
431432

432433
self.selectionChangedDisposable = (selectionChangedSignal(selectionState: selectionState)
433434
|> deliverOnMainQueue).start(next: { [weak self] animated in
434-
if let strongSelf = self {
435-
strongSelf.updateSelectionState(animated: animated)
435+
if let self {
436+
self.updateSelectionState(animated: animated)
436437
}
437438
})
438439
}
@@ -451,8 +452,8 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
451452

452453
self.itemsDimensionsUpdatedDisposable = (itemsDimensionsUpdatedSignal(editingState: editingState)
453454
|> deliverOnMainQueue).start(next: { [weak self] _ in
454-
if let strongSelf = self {
455-
strongSelf.updateSelectionState()
455+
if let self {
456+
self.updateSelectionState()
456457
}
457458
})
458459
}
@@ -536,8 +537,8 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
536537
self?.gridNode.scrollView.isScrollEnabled = isEnabled
537538
}
538539
selectionGesture.itemAt = { [weak self] point in
539-
if let strongSelf = self, let itemNode = strongSelf.gridNode.itemNodeAtPoint(point) as? MediaPickerGridItemNode, let selectableItem = itemNode.selectableItem {
540-
return (selectableItem, strongSelf.controller?.interaction?.selectionState?.isIdentifierSelected(selectableItem.uniqueIdentifier) ?? false)
540+
if let self, let itemNode = self.gridNode.itemNodeAtPoint(point) as? MediaPickerGridItemNode, let selectableItem = itemNode.selectableItem {
541+
return (selectableItem, self.controller?.interaction?.selectionState?.isIdentifierSelected(selectableItem.uniqueIdentifier) ?? false)
541542
} else {
542543
return nil
543544
}
@@ -2004,8 +2005,11 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
20042005
var hasSelect = false
20052006
if forCollage {
20062007
hasSelect = true
2007-
} else if case .story = mode, selectionContext.selectionLimit > 1 {
2008-
hasSelect = true
2008+
} else if case .story = mode {
2009+
if selectionContext.selectionLimit == 1 && context.isPremium {
2010+
} else {
2011+
hasSelect = true
2012+
}
20092013
}
20102014

20112015
if hasSelect {
@@ -2584,6 +2588,34 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
25842588
}
25852589

25862590
@objc private func selectPressed() {
2591+
let context = self.context
2592+
if let selectionState = self.interaction?.selectionState, selectionState.selectionLimit == 1, !context.isPremium {
2593+
var replaceImpl: ((ViewController) -> Void)?
2594+
let controller = context.sharedContext.makePremiumLimitController(
2595+
context: self.context,
2596+
subject: .multiStories,
2597+
count: 1,
2598+
forceDark: true,
2599+
cancel: {},
2600+
action: {
2601+
let controller = context.sharedContext.makePremiumIntroController(
2602+
context: context,
2603+
source: .stories,
2604+
forceDark: true,
2605+
dismissed: nil
2606+
)
2607+
replaceImpl?(controller)
2608+
return true
2609+
})
2610+
replaceImpl = { [weak controller] c in
2611+
controller?.replace(with: c)
2612+
}
2613+
self.requestDismiss {
2614+
self.parentController()?.push(controller)
2615+
}
2616+
return
2617+
}
2618+
25872619
self.navigationItem.setRightBarButton(nil, animated: true)
25882620
self.explicitMultipleSelection = true
25892621

@@ -2724,11 +2756,10 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
27242756
loop: true
27252757
), action: { [weak self] _, f in
27262758
f(.default)
2727-
guard let strongSelf = self else {
2759+
guard let self else {
27282760
return
27292761
}
2730-
2731-
if let selectionContext = strongSelf.interaction?.selectionState, let editingContext = strongSelf.interaction?.editingState {
2762+
if let selectionContext = self.interaction?.selectionState, let editingContext = self.interaction?.editingState {
27322763
for case let item as TGMediaEditableItem in selectionContext.selectedItems() {
27332764
editingContext.setSpoiler(hasGeneric, for: item)
27342765
}
@@ -2754,10 +2785,10 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
27542785
}
27552786

27562787
let controller = self.context.sharedContext.makeStarsAmountScreen(context: self.context, initialValue: price, completion: { [weak self] amount in
2757-
guard let strongSelf = self else {
2788+
guard let self else {
27582789
return
27592790
}
2760-
if let selectionContext = strongSelf.interaction?.selectionState, let editingContext = strongSelf.interaction?.editingState {
2791+
if let selectionContext = self.interaction?.selectionState, let editingContext = self.interaction?.editingState {
27612792
selectionContext.selectionLimit = 10
27622793
for case let item as TGMediaEditableItem in selectionContext.selectedItems() {
27632794
editingContext.setPrice(NSNumber(value: amount), for: item)

submodules/PremiumUI/Sources/PremiumLimitScreen.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,30 @@ private final class LimitSheetContent: CombinedComponent {
11011101
badgePosition = max(0.32, CGFloat(component.count) / CGFloat(premiumLimit))
11021102
badgeGraphPosition = badgePosition
11031103

1104+
if isPremiumDisabled {
1105+
badgeText = "\(limit)"
1106+
let numberString = strings.Premium_MaxExpiringStoriesNoPremiumTextNumberFormat(Int32(limit))
1107+
string = strings.Premium_MaxExpiringStoriesNoPremiumTextFormat(numberString).string
1108+
}
1109+
buttonAnimationName = nil
1110+
case .multiStories:
1111+
let limit = state.limits.maxExpiringStoriesCount
1112+
let premiumLimit = state.premiumLimits.maxExpiringStoriesCount
1113+
iconName = "Premium/Stories"
1114+
badgeText = "\(limit)"
1115+
if component.count >= premiumLimit {
1116+
let limitNumberString = strings.Premium_MaxExpiringStoriesFinalTextNumberFormat(Int32(premiumLimit))
1117+
string = strings.Premium_MaxExpiringStoriesFinalTextFormat(limitNumberString).string
1118+
} else {
1119+
let limitNumberString = strings.Premium_MaxExpiringStoriesTextNumberFormat(Int32(limit))
1120+
let premiumLimitNumberString = strings.Premium_MaxExpiringStoriesTextPremiumNumberFormat(Int32(premiumLimit))
1121+
string = strings.Premium_MaxExpiringStoriesTextFormat(limitNumberString, premiumLimitNumberString).string
1122+
}
1123+
defaultValue = ""
1124+
premiumValue = component.count >= premiumLimit ? "" : "\(premiumLimit)"
1125+
badgePosition = max(0.32, CGFloat(component.count) / CGFloat(premiumLimit))
1126+
badgeGraphPosition = badgePosition
1127+
11041128
if isPremiumDisabled {
11051129
badgeText = "\(limit)"
11061130
let numberString = strings.Premium_MaxExpiringStoriesNoPremiumTextNumberFormat(Int32(limit))
@@ -1210,7 +1234,6 @@ private final class LimitSheetContent: CombinedComponent {
12101234
remaining = nextLevelBoosts - component.count
12111235
}
12121236

1213-
12141237
if let _ = link {
12151238
if let remaining {
12161239
let storiesString = strings.ChannelBoost_StoriesPerDay(level + 1)
@@ -1813,6 +1836,7 @@ public class PremiumLimitScreen: ViewControllerComponentContainer {
18131836
case membershipInSharedFolders
18141837
case channels
18151838
case expiringStories
1839+
case multiStories
18161840
case storiesWeekly
18171841
case storiesMonthly
18181842

submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,13 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
484484
case peerId(EnginePeer.Id)
485485
case name(String)
486486
case address(String)
487+
488+
public var peerId: EnginePeer.Id? {
489+
if case let .peerId(peerId) = self {
490+
return peerId
491+
}
492+
return nil
493+
}
487494
}
488495

489496
public enum DecodingError: Error {

submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3253,6 +3253,24 @@ public class GiftViewScreen: ViewControllerComponentContainer {
32533253
guard let self, let arguments = self.subject.arguments, let navigationController = self.navigationController as? NavigationController, case let .unique(gift) = arguments.gift, let reference = arguments.reference, let transferStars = arguments.transferStars else {
32543254
return
32553255
}
3256+
3257+
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
3258+
if let canTransferDate = arguments.canTransferDate, currentTime < canTransferDate {
3259+
let dateString = stringForFullDate(timestamp: canTransferDate, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat)
3260+
let controller = textAlertController(
3261+
context: self.context,
3262+
title: presentationData.strings.Gift_Transfer_Unavailable_Title,
3263+
text: presentationData.strings.Gift_Transfer_Unavailable_Text(dateString).string,
3264+
actions: [
3265+
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})
3266+
],
3267+
parseMarkdown: true
3268+
)
3269+
self.present(controller, in: .window(.root))
3270+
return
3271+
}
3272+
3273+
32563274
let _ = (context.account.stateManager.contactBirthdays
32573275
|> take(1)
32583276
|> deliverOnMainQueue).start(next: { birthdays in
@@ -3477,8 +3495,33 @@ public class GiftViewScreen: ViewControllerComponentContainer {
34773495
}
34783496

34793497
let _ = ((updateResellStars?(price) ?? context.engine.payments.updateStarGiftResalePrice(reference: reference, price: price))
3480-
|> deliverOnMainQueue).startStandalone(error: { error in
3498+
|> deliverOnMainQueue).startStandalone(error: { [weak self] error in
3499+
guard let self else {
3500+
return
3501+
}
3502+
3503+
let title: String?
3504+
let text: String
3505+
switch error {
3506+
case .generic:
3507+
title = nil
3508+
text = presentationData.strings.Gift_Send_ErrorUnknown
3509+
case let .starGiftResellTooEarly(canResaleDate):
3510+
let dateString = stringForFullDate(timestamp: canResaleDate, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat)
3511+
title = presentationData.strings.Gift_Resale_Unavailable_Title
3512+
text = presentationData.strings.Gift_Resale_Unavailable_Text(dateString).string
3513+
}
34813514

3515+
let controller = textAlertController(
3516+
context: self.context,
3517+
title: title,
3518+
text: text,
3519+
actions: [
3520+
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})
3521+
],
3522+
parseMarkdown: true
3523+
)
3524+
self.present(controller, in: .window(.root))
34823525
}, completed: { [weak self] in
34833526
guard let self else {
34843527
return
@@ -3597,13 +3640,15 @@ public class GiftViewScreen: ViewControllerComponentContainer {
35973640
}
35983641

35993642
if case let .unique(gift) = arguments.gift, let resellStars = gift.resellStars, resellStars > 0 {
3600-
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Gift_View_Context_ChangePrice, icon: { theme in
3601-
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/PriceTag"), color: theme.contextMenu.primaryColor)
3602-
}, action: { c, _ in
3603-
c?.dismiss(completion: nil)
3604-
3605-
resellGiftImpl?(true)
3606-
})))
3643+
if arguments.reference != nil || gift.owner.peerId == context.account.peerId {
3644+
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Gift_View_Context_ChangePrice, icon: { theme in
3645+
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/PriceTag"), color: theme.contextMenu.primaryColor)
3646+
}, action: { c, _ in
3647+
c?.dismiss(completion: nil)
3648+
3649+
resellGiftImpl?(true)
3650+
})))
3651+
}
36073652
}
36083653

36093654
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Gift_View_Context_CopyLink, icon: { theme in

submodules/TelegramUI/Components/MarqueeComponent/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ swift_library(
1212
deps = [
1313
"//submodules/Display",
1414
"//submodules/ComponentFlow",
15+
"//submodules/SSignalKit/SwiftSignalKit",
1516
],
1617
visibility = [
1718
"//visibility:public",

0 commit comments

Comments
 (0)