Various improvements

This commit is contained in:
Ilya Laktyushin 2023-10-26 17:51:10 +04:00
parent 60815f9fb5
commit 6a811ae8bc
4 changed files with 143 additions and 90 deletions

View File

@ -10145,6 +10145,11 @@ Sorry for the inconvenience.";
"NameColor.BackgroundEmoji.Title" = "ADD ICONS TO REPLIES";
"NameColor.BackgroundEmoji.Remove" = "REMOVE ICON";
"NameColor.UnsavedChanges.Title" = "Unsaved Changes";
"NameColor.UnsavedChanges.Text" = "You have changed your color or icon settings. Apply changes?";
"NameColor.UnsavedChanges.Discard" = "Discard";
"NameColor.UnsavedChanges.Apply" = "Apply";
"Chat.ErrorQuoteOutdatedTitle" = "Quote Outdated";
"Chat.ErrorQuoteOutdatedText" = "**%@** updated the message you are quoting. Edit your quote to make it up-to-date.";
"Chat.ErrorQuoteOutdatedActionEdit" = "Edit";

View File

@ -147,31 +147,49 @@ public func PremiumBoostScreen(
availableBoosts.removeFirst()
} else if !occupiedBoosts.isEmpty, let myBoostStatus {
var dismissReplaceImpl: (() -> Void)?
let replaceController = ReplaceBoostScreen(context: context, peerId: peerId, myBoostStatus: myBoostStatus, replaceBoosts: { slots in
var channelIds = Set<EnginePeer.Id>()
for boost in myBoostStatus.boosts {
if slots.contains(boost.slot) {
if let peer = boost.peer {
channelIds.insert(peer.id)
if canBoostAgain {
var dismissReplaceImpl: (() -> Void)?
let replaceController = ReplaceBoostScreen(context: context, peerId: peerId, myBoostStatus: myBoostStatus, replaceBoosts: { slots in
var channelIds = Set<EnginePeer.Id>()
for boost in myBoostStatus.boosts {
if slots.contains(boost.slot) {
if let peer = boost.peer {
channelIds.insert(peer.id)
}
}
}
}
let _ = context.engine.peers.applyChannelBoost(peerId: peerId, slots: slots).startStandalone(completed: {
let _ = combineLatest(queue: Queue.mainQueue(),
context.engine.peers.getChannelBoostStatus(peerId: peerId),
context.engine.peers.getMyBoostStatus()
).startStandalone(next: { boostStatus, myBoostStatus in
dismissReplaceImpl?()
PremiumBoostScreen(context: context, contentContext: contentContext, peerId: peerId, isCurrent: isCurrent, status: boostStatus, myBoostStatus: myBoostStatus, replacedBoosts: (Int32(slots.count), Int32(channelIds.count)), forceDark: forceDark, openPeer: openPeer, presentController: presentController, pushController: pushController, dismissed: dismissed)
let _ = context.engine.peers.applyChannelBoost(peerId: peerId, slots: slots).startStandalone(completed: {
let _ = combineLatest(queue: Queue.mainQueue(),
context.engine.peers.getChannelBoostStatus(peerId: peerId),
context.engine.peers.getMyBoostStatus()
).startStandalone(next: { boostStatus, myBoostStatus in
dismissReplaceImpl?()
PremiumBoostScreen(context: context, contentContext: contentContext, peerId: peerId, isCurrent: isCurrent, status: boostStatus, myBoostStatus: myBoostStatus, replacedBoosts: (Int32(slots.count), Int32(channelIds.count)), forceDark: forceDark, openPeer: openPeer, presentController: presentController, pushController: pushController, dismissed: dismissed)
})
})
})
})
dismissImpl?()
pushController(replaceController)
dismissReplaceImpl = { [weak replaceController] in
replaceController?.dismiss(animated: true)
dismissImpl?()
pushController(replaceController)
dismissReplaceImpl = { [weak replaceController] in
replaceController?.dismiss(animated: true)
}
} else if let boost = occupiedBoosts.first, let occupiedPeer = boost.peer {
let replaceController = replaceBoostConfirmationController(context: context, fromPeers: [occupiedPeer], toPeer: peer, commit: {
let _ = (context.engine.peers.applyChannelBoost(peerId: peerId, slots: [boost.slot])
|> deliverOnMainQueue).startStandalone(completed: { [weak controller] in
let _ = (updatedState.get()
|> take(1)
|> deliverOnMainQueue).startStandalone(next: { [weak controller] state in
guard let state else {
return
}
let (subject, count) = state.displayData(peer: peer, isCurrent: isCurrent, canBoostAgain: canBoostAgain, myBoostCount: myBoostCount, currentMyBoostCount: currentMyBoostCount)
controller?.updateSubject(subject, count: count)
})
})
})
presentController(replaceController)
}
} else {
if isPremium {

View File

@ -1,3 +1,4 @@
import Foundation
import UIKit
import SwiftSignalKit
@ -342,30 +343,21 @@ private final class ReplaceBoostConfirmationAlertContentNode: AlertContentNode {
}
func replaceBoostConfirmationController(context: AccountContext, fromPeers: [EnginePeer], toPeer: EnginePeer, commit: @escaping () -> Void) -> AlertController {
let fromPeers = [fromPeers.first!, fromPeers.first!]
let theme = defaultDarkColorPresentationTheme
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let strings = presentationData.strings
let text: String
if fromPeers.count > 1 {
text = "To boost **\(toPeer.compactDisplayTitle)**, reassign a previous boost from:"
//strings.ChannelBoost_ReplaceBoost(previousPeer.compactDisplayTitle, toPeer.compactDisplayTitle).string
} else {
text = strings.ChannelBoost_ReplaceBoost(fromPeers.first!.compactDisplayTitle, toPeer.compactDisplayTitle).string
}
let text = strings.ChannelBoost_ReplaceBoost(fromPeers.first!.compactDisplayTitle, toPeer.compactDisplayTitle).string
var dismissImpl: ((Bool) -> Void)?
var contentNode: ReplaceBoostConfirmationAlertContentNode?
let actions: [TextAlertAction] = [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
dismissImpl?(true)
}), TextAlertAction(type: .defaultAction, title: "Reassign", action: {
}), TextAlertAction(type: .defaultAction, title: strings.ChannelBoost_Replace, action: {
dismissImpl?(true)
commit()
})]
contentNode = ReplaceBoostConfirmationAlertContentNode(context: context, theme: AlertControllerTheme(presentationData: presentationData), ptheme: theme, strings: strings, fromPeers: fromPeers, toPeer: toPeer, text: text, actions: actions)
contentNode = ReplaceBoostConfirmationAlertContentNode(context: context, theme: AlertControllerTheme(presentationData: presentationData), ptheme: presentationData.theme, strings: strings, fromPeers: fromPeers, toPeer: toPeer, text: text, actions: actions)
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode!)
dismissImpl = { [weak controller] animated in

View File

@ -283,8 +283,8 @@ public func PeerNameColorScreen(
var presentImpl: ((ViewController) -> Void)?
var pushImpl: ((ViewController) -> Void)?
var dismissImpl: (() -> Void)?
// var openQuickReactionImpl: (() -> Void)?
var attemptNavigationImpl: ((@escaping () -> Void) -> Bool)?
var applyChangesImpl: (() -> Void)?
let actionsDisposable = DisposableSet()
@ -401,59 +401,7 @@ public func PeerNameColorScreen(
inProgress: state.inProgress,
action: {
if !isLocked {
let state = stateValue.with { $0 }
let nameColor = state.updatedNameColor ?? peer?.nameColor
let backgroundEmojiId = state.updatedBackgroundEmojiId ?? peer?.backgroundEmojiId
switch subject {
case .account:
let _ = context.engine.accountData.updateNameColorAndEmoji(nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0).startStandalone()
dismissImpl?()
case let .channel(peerId):
updateState { state in
var updatedState = state
updatedState.inProgress = true
return updatedState
}
let _ = (context.engine.peers.updatePeerNameColorAndEmoji(peerId: peerId, nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0)
|> deliverOnMainQueue).startStandalone(next: {
}, error: { error in
if case .channelBoostRequired = error {
let _ = combineLatest(
queue: Queue.mainQueue(),
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)),
context.engine.peers.getChannelBoostStatus(peerId: peerId)
).startStandalone(next: { peer, status in
guard let peer, let status else {
return
}
let link = status.url
let controller = PremiumLimitScreen(context: context, subject: .storiesChannelBoost(peer: peer, boostSubject: .nameColors, isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, myBoostCount: 0, canBoostAgain: false), count: Int32(status.boosts), action: {
UIPasteboard.general.string = link
presentImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.ChannelBoost_BoostLinkCopied), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false }))
return true
}, openStats: nil, openGift: {
let controller = createGiveawayController(context: context, peerId: peerId, subject: .generic)
pushImpl?(controller)
})
pushImpl?(controller)
HapticFeedback().impact(.light)
})
} else {
}
updateState { state in
var updatedState = state
updatedState.inProgress = false
return updatedState
}
}, completed: {
dismissImpl?()
})
}
applyChangesImpl?()
} else {
HapticFeedback().impact(.light)
let controller = UndoOverlayController(
@ -598,7 +546,97 @@ public func PeerNameColorScreen(
}
controller.dismiss()
}
controller.attemptNavigation = { f in
return attemptNavigationImpl?(f) ?? true
}
attemptNavigationImpl = { f in
if !context.isPremium {
f()
return true
}
let state = stateValue.with({ $0 })
var hasChanges = false
if state.updatedNameColor != nil || state.updatedBackgroundEmojiId != nil {
hasChanges = true
}
if hasChanges {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
presentImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.NameColor_UnsavedChanges_Title, text: presentationData.strings.NameColor_UnsavedChanges_Text, actions: [
TextAlertAction(type: .genericAction, title: presentationData.strings.NameColor_UnsavedChanges_Discard, action: {
f()
dismissImpl?()
}),
TextAlertAction(type: .defaultAction, title: presentationData.strings.NameColor_UnsavedChanges_Apply, action: {
applyChangesImpl?()
})
]))
return false
} else {
f()
return true
}
}
applyChangesImpl = {
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).startStandalone(next: { peer in
guard let peer else {
return
}
let state = stateValue.with { $0 }
let nameColor = state.updatedNameColor ?? peer.nameColor
let backgroundEmojiId = state.updatedBackgroundEmojiId ?? peer.backgroundEmojiId
switch subject {
case .account:
let _ = context.engine.accountData.updateNameColorAndEmoji(nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0).startStandalone()
dismissImpl?()
case let .channel(peerId):
updateState { state in
var updatedState = state
updatedState.inProgress = true
return updatedState
}
let _ = (context.engine.peers.updatePeerNameColorAndEmoji(peerId: peerId, nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0)
|> deliverOnMainQueue).startStandalone(next: {
}, error: { error in
if case .channelBoostRequired = error {
let _ = combineLatest(
queue: Queue.mainQueue(),
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)),
context.engine.peers.getChannelBoostStatus(peerId: peerId)
).startStandalone(next: { peer, status in
guard let peer, let status else {
return
}
let link = status.url
let controller = PremiumLimitScreen(context: context, subject: .storiesChannelBoost(peer: peer, boostSubject: .nameColors, isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, myBoostCount: 0, canBoostAgain: false), count: Int32(status.boosts), action: {
UIPasteboard.general.string = link
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
presentImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.ChannelBoost_BoostLinkCopied), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false }))
return true
}, openStats: nil, openGift: {
let controller = createGiveawayController(context: context, peerId: peerId, subject: .generic)
pushImpl?(controller)
})
pushImpl?(controller)
HapticFeedback().impact(.light)
})
} else {
}
updateState { state in
var updatedState = state
updatedState.inProgress = false
return updatedState
}
}, completed: {
dismissImpl?()
})
}
})
}
return controller
}