mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-06-20 18:24:43 +00:00
Name color improvements
This commit is contained in:
@@ -10150,3 +10150,5 @@ Sorry for the inconvenience.";
|
||||
"Chat.ErrorQuoteOutdatedTitle" = "Quote Outdated";
|
||||
"Chat.ErrorQuoteOutdatedText" = "**%@** updated the message you are quoting. Edit your quote to make it up-to-date.";
|
||||
"Chat.ErrorQuoteOutdatedActionEdit" = "Edit";
|
||||
|
||||
"Premium.BoostByGiftDescription" = "Boost your channel by gifting your subscribers Telegram Premium. [Get boosts >]()";
|
||||
|
||||
@@ -1471,7 +1471,7 @@ private final class LimitSheetContent: CombinedComponent {
|
||||
state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: linkColor)!, environment.theme)
|
||||
}
|
||||
|
||||
let giftString = "Boost your channel by gifting your subscribers Telegram Premium. [Get boosts >]()"
|
||||
let giftString = environment.strings.Premium_BoostByGiftDescription
|
||||
let giftAttributedString = parseMarkdownIntoAttributedString(giftString, attributes: markdownAttributes).mutableCopy() as! NSMutableAttributedString
|
||||
|
||||
if let range = giftAttributedString.string.range(of: ">"), let chevronImage = state.cachedChevronImage?.0 {
|
||||
|
||||
@@ -91,6 +91,7 @@ func _internal_updatePeerDescription(account: Account, peerId: PeerId, descripti
|
||||
|
||||
public enum UpdatePeerNameColorAndEmojiError {
|
||||
case generic
|
||||
case channelBoostRequired
|
||||
}
|
||||
|
||||
func _internal_updatePeerNameColorAndEmoji(account: Account, peerId: EnginePeer.Id, nameColor: PeerNameColor, backgroundEmojiId: Int64?) -> Signal<Void, UpdatePeerNameColorAndEmojiError> {
|
||||
@@ -111,7 +112,10 @@ func _internal_updatePeerNameColorAndEmoji(account: Account, peerId: EnginePeer.
|
||||
if let peer = peer as? TelegramChannel, let inputChannel = apiInputChannel(peer) {
|
||||
let flags: Int32 = (1 << 0)
|
||||
return account.network.request(Api.functions.channels.updateColor(flags: flags, channel: inputChannel, color: nameColor.rawValue, backgroundEmojiId: backgroundEmojiId ?? 0))
|
||||
|> mapError { _ -> UpdatePeerNameColorAndEmojiError in
|
||||
|> mapError { error -> UpdatePeerNameColorAndEmojiError in
|
||||
if error.errorDescription.hasPrefix("BOOSTS_REQUIRED") {
|
||||
return .channelBoostRequired
|
||||
}
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Void, UpdatePeerNameColorAndEmojiError> in
|
||||
|
||||
@@ -302,9 +302,6 @@ public enum PresentationResourceKey: Int32 {
|
||||
case chatReplyBackgroundTemplateOutgoingDashedImage
|
||||
case chatReplyServiceBackgroundTemplateImage
|
||||
|
||||
case chatReplyLineDashTemplateIncomingImage
|
||||
case chatReplyLineDashTemplateOutgoingImage
|
||||
|
||||
case chatBubbleCloseIcon
|
||||
}
|
||||
|
||||
|
||||
@@ -1319,38 +1319,6 @@ public struct PresentationResourcesChat {
|
||||
})
|
||||
}
|
||||
|
||||
public static func chatReplyLineDashTemplateImage(_ theme: PresentationTheme, incoming: Bool) -> UIImage? {
|
||||
let key: PresentationResourceKey = incoming ? .chatReplyLineDashTemplateIncomingImage : .chatReplyLineDashTemplateOutgoingImage
|
||||
return theme.image(key.rawValue, { theme in
|
||||
let radius: CGFloat = 3.0
|
||||
let offset: CGFloat = incoming ? 5.0 : -3.0
|
||||
|
||||
return generateImage(CGSize(width: 12.0, height: radius * 6.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
context.move(to: CGPoint(x: radius, y: offset))
|
||||
context.addLine(to: CGPoint(x: radius, y: offset + radius * 3.0))
|
||||
context.addLine(to: CGPoint(x: 0.0, y: offset + radius * 4.0))
|
||||
context.addLine(to: CGPoint(x: 0.0, y: offset + radius))
|
||||
context.closePath()
|
||||
|
||||
context.setFillColor(UIColor.white.cgColor)
|
||||
context.fillPath()
|
||||
|
||||
if !incoming {
|
||||
context.move(to: CGPoint(x: radius, y: size.height + offset))
|
||||
context.addLine(to: CGPoint(x: radius, y: size.height + offset + radius * 3.0))
|
||||
context.addLine(to: CGPoint(x: 0.0, y: size.height + offset + radius * 4.0))
|
||||
context.addLine(to: CGPoint(x: 0.0, y: size.height + offset + radius))
|
||||
context.closePath()
|
||||
|
||||
context.setFillColor(UIColor.white.cgColor)
|
||||
context.fillPath()
|
||||
}
|
||||
})?.resizableImage(withCapInsets: .zero, resizingMode: .tile).withRenderingMode(.alwaysTemplate)
|
||||
})
|
||||
}
|
||||
|
||||
public static func chatBubbleCloseIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatBubbleCloseIcon.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 12.0, height: 12.0), rotatedContext: { size, context in
|
||||
|
||||
+1
-25
@@ -748,31 +748,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
||||
pattern: pattern,
|
||||
animation: animation
|
||||
)
|
||||
|
||||
let _ = secondaryColor
|
||||
/*if let secondaryColor {
|
||||
let lineDashView: UIImageView
|
||||
if let current = node.lineDashView {
|
||||
lineDashView = current
|
||||
} else {
|
||||
lineDashView = UIImageView(image: PresentationResourcesChat.chatReplyLineDashTemplateImage(arguments.presentationData.theme.theme, incoming: isIncoming))
|
||||
lineDashView.clipsToBounds = true
|
||||
node.lineDashView = lineDashView
|
||||
node.contentNode.view.addSubview(lineDashView)
|
||||
}
|
||||
lineDashView.tintColor = secondaryColor
|
||||
lineDashView.frame = CGRect(origin: .zero, size: CGSize(width: 12.0, height: backgroundFrame.height))
|
||||
lineDashView.layer.cornerRadius = 6.0
|
||||
if #available(iOS 13.0, *) {
|
||||
lineDashView.layer.cornerCurve = .continuous
|
||||
}
|
||||
} else {
|
||||
if let lineDashView = node.lineDashView {
|
||||
node.lineDashView = nil
|
||||
lineDashView.removeFromSuperview()
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
if arguments.quote != nil || arguments.replyForward?.quote != nil {
|
||||
let quoteIconView: UIImageView
|
||||
if let current = node.quoteIconView {
|
||||
|
||||
@@ -25,6 +25,7 @@ swift_library(
|
||||
"//submodules/TelegramUI/Components/EntityKeyboard",
|
||||
"//submodules/SolidRoundedButtonNode",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/PremiumUI",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
+16
-2
@@ -12,18 +12,20 @@ final class ApplyColorFooterItem: ItemListControllerFooterItem {
|
||||
let theme: PresentationTheme
|
||||
let title: String
|
||||
let locked: Bool
|
||||
let inProgress: Bool
|
||||
let action: () -> Void
|
||||
|
||||
init(theme: PresentationTheme, title: String, locked: Bool, action: @escaping () -> Void) {
|
||||
init(theme: PresentationTheme, title: String, locked: Bool, inProgress: Bool, action: @escaping () -> Void) {
|
||||
self.theme = theme
|
||||
self.title = title
|
||||
self.locked = locked
|
||||
self.inProgress = inProgress
|
||||
self.action = action
|
||||
}
|
||||
|
||||
func isEqual(to: ItemListControllerFooterItem) -> Bool {
|
||||
if let item = to as? ApplyColorFooterItem {
|
||||
return self.theme === item.theme && self.title == item.title && self.locked == item.locked
|
||||
return self.theme === item.theme && self.title == item.title && self.locked == item.locked && self.inProgress == item.inProgress
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
@@ -63,6 +65,7 @@ final class ApplyColorFooterItemNode: ItemListControllerFooterItemNode {
|
||||
|
||||
self.buttonNode = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .black, foregroundColor: .white), height: 50.0, cornerRadius: 11.0)
|
||||
self.buttonNode.icon = item.locked ? UIImage(bundleImageName: "Chat/Stickers/Lock") : nil
|
||||
self.buttonNode.progressType = .embedded
|
||||
|
||||
super.init()
|
||||
|
||||
@@ -73,6 +76,7 @@ final class ApplyColorFooterItemNode: ItemListControllerFooterItemNode {
|
||||
self.updateItem()
|
||||
}
|
||||
|
||||
private var inProgress = false
|
||||
private func updateItem() {
|
||||
self.backgroundNode.updateColor(color: self.item.theme.rootController.tabBar.backgroundColor, transition: .immediate)
|
||||
self.separatorNode.backgroundColor = self.item.theme.rootController.tabBar.separatorColor
|
||||
@@ -87,6 +91,16 @@ final class ApplyColorFooterItemNode: ItemListControllerFooterItemNode {
|
||||
self.buttonNode.pressed = { [weak self] in
|
||||
self?.item.action()
|
||||
}
|
||||
|
||||
if self.inProgress != self.item.inProgress {
|
||||
self.inProgress = true
|
||||
|
||||
if self.item.inProgress {
|
||||
self.buttonNode.transitionToProgress()
|
||||
} else {
|
||||
self.buttonNode.transitionFromProgress()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func updateBackgroundAlpha(_ alpha: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
|
||||
+46
-4
@@ -12,6 +12,7 @@ import PresentationDataUtils
|
||||
import AccountContext
|
||||
import UndoUI
|
||||
import EntityKeyboard
|
||||
import PremiumUI
|
||||
|
||||
private final class PeerNameColorScreenArguments {
|
||||
let context: AccountContext
|
||||
@@ -180,6 +181,7 @@ private enum PeerNameColorScreenEntry: ItemListNodeEntry {
|
||||
private struct PeerNameColorScreenState: Equatable {
|
||||
var updatedNameColor: PeerNameColor?
|
||||
var updatedBackgroundEmojiId: Int64?
|
||||
var inProgress: Bool = false
|
||||
}
|
||||
|
||||
private func peerNameColorScreenEntries(
|
||||
@@ -392,6 +394,7 @@ public func PeerNameColorScreen(
|
||||
theme: presentationData.theme,
|
||||
title: buttonTitle,
|
||||
locked: isLocked,
|
||||
inProgress: state.inProgress,
|
||||
action: {
|
||||
if !isLocked {
|
||||
let state = stateValue.with { $0 }
|
||||
@@ -402,13 +405,52 @@ public func PeerNameColorScreen(
|
||||
switch subject {
|
||||
case .account:
|
||||
let _ = context.engine.accountData.updateNameColorAndEmoji(nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0).startStandalone()
|
||||
dismissImpl?()
|
||||
case let .channel(peerId):
|
||||
let _ = context.engine.peers.updatePeerNameColorAndEmoji(peerId: peerId, nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0).startStandalone()
|
||||
updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.inProgress = true
|
||||
return updatedState
|
||||
}
|
||||
let _ = context.engine.peers.updatePeerNameColorAndEmoji(peerId: peerId, nameColor: nameColor ?? .blue, backgroundEmojiId: backgroundEmojiId ?? 0).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, isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, myBoostCount: 0), 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 = true
|
||||
return updatedState
|
||||
}
|
||||
}, completed: {
|
||||
dismissImpl?()
|
||||
})
|
||||
}
|
||||
|
||||
dismissImpl?()
|
||||
} else {
|
||||
HapticFeedback().error()
|
||||
HapticFeedback().impact(.light)
|
||||
let controller = UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .premiumPaywall(
|
||||
|
||||
@@ -8387,6 +8387,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
if let self {
|
||||
self.openStats(boosts: true, boostStatus: status)
|
||||
}
|
||||
}, openGift: { [weak self] in
|
||||
if let self {
|
||||
let controller = createGiveawayController(context: self.context, peerId: self.peerId, subject: .generic)
|
||||
self.controller?.push(controller)
|
||||
}
|
||||
})
|
||||
navigationController.pushViewController(controller)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user