Improvements

This commit is contained in:
Isaac 2024-03-28 16:02:30 +04:00
parent 9e1fdb3c8d
commit d192889e0e
10 changed files with 102 additions and 26 deletions

View File

@ -167,19 +167,34 @@ public func incomingMessagePrivacyScreen(context: AccountContext, value: Bool, u
}
)
let enableSetting: Signal<Bool, NoError> = context.engine.data.subscribe(
TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId),
TelegramEngine.EngineData.Item.Configuration.App()
)
|> map { accountPeer, appConfig -> Bool in
if let accountPeer, accountPeer.isPremium {
return true
}
if let data = appConfig.data, let setting = data["new_noncontact_peers_require_premium_without_ownpremium"] as? Bool {
if setting {
return true
}
}
return false
}
|> distinctUntilChanged
let signal = combineLatest(queue: .mainQueue(),
context.sharedContext.presentationData,
context.engine.data.subscribe(
TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)
),
statePromise.get()
statePromise.get(),
enableSetting
)
|> map { presentationData, accountPeer, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
|> map { presentationData, state, enableSetting -> (ItemListControllerState, (ItemListNodeState, Any)) in
let rightNavigationButton: ItemListNavigationButton? = nil
let title: ItemListControllerTitle = .text(presentationData.strings.Privacy_Messages_Title)
let entries: [GlobalAutoremoveEntry] = incomingMessagePrivacyScreenEntries(presentationData: presentationData, state: state, isPremium: accountPeer?.isPremium ?? false)
let entries: [GlobalAutoremoveEntry] = incomingMessagePrivacyScreenEntries(presentationData: presentationData, state: state, isPremium: enableSetting)
let animateChanges = false

View File

@ -47,6 +47,7 @@ public final class EmojiActionIconComponent: Component {
let size = CGSize(width: 24.0, height: 24.0)
if let fileId = component.fileId {
var iconSize = size
let icon: ComponentView<Empty>
if let current = self.icon {
icon = current
@ -56,6 +57,9 @@ public final class EmojiActionIconComponent: Component {
}
let content: EmojiStatusComponent.AnimationContent
if let file = component.file {
if let dimensions = file.dimensions {
iconSize = dimensions.cgSize.aspectFitted(size)
}
content = .file(file: file)
} else {
content = .customEmoji(fileId: fileId)
@ -68,7 +72,7 @@ public final class EmojiActionIconComponent: Component {
animationRenderer: component.context.animationRenderer,
content: .animation(
content: content,
size: size,
size: iconSize,
placeholderColor: .lightGray,
themeColor: component.color,
loopMode: .forever
@ -77,9 +81,9 @@ public final class EmojiActionIconComponent: Component {
action: nil
)),
environment: {},
containerSize: size
containerSize: iconSize
)
let iconFrame = CGRect(origin: CGPoint(), size: size)
let iconFrame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) * 0.5), y: floor((size.height - iconSize.height) * 0.5)), size: iconSize)
if let iconView = icon.view {
if iconView.superview == nil {
self.addSubview(iconView)

View File

@ -30,6 +30,12 @@ public final class ListMultilineTextFieldItemComponent: Component {
}
}
public enum EmptyLineHandling {
case allowed
case oneConsecutive
case notAllowed
}
public let externalState: ExternalState?
public let context: AccountContext
public let theme: PresentationTheme
@ -41,7 +47,7 @@ public final class ListMultilineTextFieldItemComponent: Component {
public let autocorrectionType: UITextAutocorrectionType
public let characterLimit: Int?
public let displayCharacterLimit: Bool
public let allowEmptyLines: Bool
public let emptyLineHandling: EmptyLineHandling
public let updated: ((String) -> Void)?
public let textUpdateTransition: Transition
public let tag: AnyObject?
@ -58,7 +64,7 @@ public final class ListMultilineTextFieldItemComponent: Component {
autocorrectionType: UITextAutocorrectionType = .default,
characterLimit: Int? = nil,
displayCharacterLimit: Bool = false,
allowEmptyLines: Bool = true,
emptyLineHandling: EmptyLineHandling = .allowed,
updated: ((String) -> Void)?,
textUpdateTransition: Transition = .immediate,
tag: AnyObject? = nil
@ -74,7 +80,7 @@ public final class ListMultilineTextFieldItemComponent: Component {
self.autocorrectionType = autocorrectionType
self.characterLimit = characterLimit
self.displayCharacterLimit = displayCharacterLimit
self.allowEmptyLines = allowEmptyLines
self.emptyLineHandling = emptyLineHandling
self.updated = updated
self.textUpdateTransition = textUpdateTransition
self.tag = tag
@ -114,7 +120,7 @@ public final class ListMultilineTextFieldItemComponent: Component {
if lhs.displayCharacterLimit != rhs.displayCharacterLimit {
return false
}
if lhs.allowEmptyLines != rhs.allowEmptyLines {
if lhs.emptyLineHandling != rhs.emptyLineHandling {
return false
}
if (lhs.updated == nil) != (rhs.updated == nil) {
@ -225,6 +231,16 @@ public final class ListMultilineTextFieldItemComponent: Component {
self.measureTextLimitLabel = nil
}
let mappedEmptyLineHandling: TextFieldComponent.EmptyLineHandling
switch component.emptyLineHandling {
case .allowed:
mappedEmptyLineHandling = .allowed
case .oneConsecutive:
mappedEmptyLineHandling = .oneConsecutive
case .notAllowed:
mappedEmptyLineHandling = .notAllowed
}
let textFieldSize = self.textField.update(
transition: transition,
component: AnyComponent(TextFieldComponent(
@ -242,7 +258,7 @@ public final class ListMultilineTextFieldItemComponent: Component {
},
isOneLineWhenUnfocused: false,
characterLimit: component.characterLimit,
allowEmptyLines: component.allowEmptyLines,
emptyLineHandling: mappedEmptyLineHandling,
formatMenuAvailability: .none,
lockedFormatAction: {
},

View File

@ -321,7 +321,12 @@ private final class SendInviteLinkScreenComponent: Component {
self.scrollContentView.addSubview(avatarsNode.view)
}
let avatarPeers = component.peers.map(\.peer)
let avatarPeers: [EnginePeer]
if !premiumRestrictedUsers.isEmpty {
avatarPeers = premiumRestrictedUsers.map(\.peer)
} else {
avatarPeers = component.peers.map(\.peer)
}
let avatarsContent = self.avatarsContext.update(peers: avatarPeers.count <= 3 ? avatarPeers : Array(avatarPeers.prefix(upTo: 3)), animated: false)
let avatarsSize = avatarsNode.update(
context: component.context,

View File

@ -767,7 +767,7 @@ final class BusinessIntroSetupScreenComponent: Component {
autocorrectionType: .no,
characterLimit: 32,
displayCharacterLimit: true,
allowEmptyLines: false,
emptyLineHandling: .notAllowed,
updated: { _ in
},
textUpdateTransition: .spring(duration: 0.4),
@ -788,7 +788,7 @@ final class BusinessIntroSetupScreenComponent: Component {
autocorrectionType: .no,
characterLimit: 70,
displayCharacterLimit: true,
allowEmptyLines: false,
emptyLineHandling: .notAllowed,
updated: { _ in
},
textUpdateTransition: .spring(duration: 0.4),

View File

@ -406,7 +406,7 @@ final class BusinessLocationSetupScreenComponent: Component {
autocapitalizationType: .none,
autocorrectionType: .no,
characterLimit: 256,
allowEmptyLines: false,
emptyLineHandling: .oneConsecutive,
updated: { _ in
},
textUpdateTransition: .spring(duration: 0.4),

View File

@ -295,7 +295,7 @@ final class ChatbotSetupScreenComponent: Component {
break
case let .result(peer):
let previousState = self.botResolutionState?.state
if let peer {
if let peer, case let .user(user) = peer, user.botInfo != nil {
self.botResolutionState?.state = .found(peer: peer, isInstalled: false)
} else {
self.botResolutionState?.state = .notFound

View File

@ -89,6 +89,12 @@ public final class TextFieldComponent: Component {
case none
}
public enum EmptyLineHandling {
case allowed
case oneConsecutive
case notAllowed
}
public let context: AccountContext
public let theme: PresentationTheme
public let strings: PresentationStrings
@ -101,7 +107,7 @@ public final class TextFieldComponent: Component {
public let resetText: NSAttributedString?
public let isOneLineWhenUnfocused: Bool
public let characterLimit: Int?
public let allowEmptyLines: Bool
public let emptyLineHandling: EmptyLineHandling
public let formatMenuAvailability: FormatMenuAvailability
public let lockedFormatAction: () -> Void
public let present: (ViewController) -> Void
@ -120,7 +126,7 @@ public final class TextFieldComponent: Component {
resetText: NSAttributedString?,
isOneLineWhenUnfocused: Bool,
characterLimit: Int? = nil,
allowEmptyLines: Bool = true,
emptyLineHandling: EmptyLineHandling = .allowed,
formatMenuAvailability: FormatMenuAvailability,
lockedFormatAction: @escaping () -> Void,
present: @escaping (ViewController) -> Void,
@ -138,7 +144,7 @@ public final class TextFieldComponent: Component {
self.resetText = resetText
self.isOneLineWhenUnfocused = isOneLineWhenUnfocused
self.characterLimit = characterLimit
self.allowEmptyLines = allowEmptyLines
self.emptyLineHandling = emptyLineHandling
self.formatMenuAvailability = formatMenuAvailability
self.lockedFormatAction = lockedFormatAction
self.present = present
@ -182,7 +188,7 @@ public final class TextFieldComponent: Component {
if lhs.characterLimit != rhs.characterLimit {
return false
}
if lhs.allowEmptyLines != rhs.allowEmptyLines {
if lhs.emptyLineHandling != rhs.emptyLineHandling {
return false
}
if lhs.formatMenuAvailability != rhs.formatMenuAvailability {
@ -566,12 +572,21 @@ public final class TextFieldComponent: Component {
return false
}
}
if !component.allowEmptyLines {
switch component.emptyLineHandling {
case .allowed:
break
case .oneConsecutive:
let string = self.inputState.inputText.string as NSString
let updatedString = string.replacingCharacters(in: range, with: text)
if updatedString.range(of: "\n\n") != nil {
return false
}
case .notAllowed:
let string = self.inputState.inputText.string as NSString
let updatedString = string.replacingCharacters(in: range, with: text)
if updatedString.range(of: "\n") != nil {
return false
}
}
return true

View File

@ -17,7 +17,7 @@ extension ChatControllerImpl {
guard let self, let itemNode else {
return
}
if value >= 1 {
if value >= 2 {
return
}
@ -29,7 +29,7 @@ extension ChatControllerImpl {
let location = CGPoint(x: bounds.midX, y: bounds.minY - 11.0)
//TODO:localize
let tooltipController = TooltipController(content: .text("Only you can see that this message was sent by the bot."), baseFontSize: self.presentationData.listsFontSize.baseDisplaySize, balancedTextLayout: true, timeout: 3.5, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true)
let tooltipController = TooltipController(content: .text("Only you can see that this\nmessage was sent by the bot."), baseFontSize: self.presentationData.listsFontSize.baseDisplaySize, balancedTextLayout: true, timeout: 3.5, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true)
self.checksTooltipController = tooltipController
tooltipController.dismissed = { [weak self, weak tooltipController] _ in
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.checksTooltipController === tooltipController {
@ -57,6 +57,11 @@ extension ChatControllerImpl {
return (self.chatDisplayNode, CGRect(origin: location, size: CGSize()))
}))
#if DEBUG
if "".isEmpty {
return
}
#endif
let _ = ApplicationSpecificNotice.incrementBusinessBotMessageTooltip(accountManager: self.context.sharedContext.accountManager).startStandalone()
})
}

View File

@ -675,6 +675,22 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
}
}
}
} else if parsedUrl.host == "message" {
if let components = URLComponents(string: "/?" + query) {
var parameter: String?
if let queryItems = components.queryItems {
for queryItem in queryItems {
if let value = queryItem.value {
if queryItem.name == "slug" {
parameter = value
}
}
}
}
if let parameter {
convertedUrl = "https://t.me/m/\(parameter)"
}
}
}
if parsedUrl.host == "resolve" {