Merge commit 'b738beaf55c533f99b30e75dd9bee0d54d10958a'

This commit is contained in:
Ali 2021-02-17 17:46:06 +04:00
commit 426c1859a6
18 changed files with 3635 additions and 3547 deletions

View File

@ -5933,6 +5933,8 @@ Sorry for the inconvenience.";
"InviteLink.InviteLinks_many" = "%@ invite links";
"InviteLink.InviteLinks_any" = "%@ invite links";
"InviteLink.InviteLinkRevoked" = "The invite link has been revoked.";
"Conversation.ChecksTooltip.Delivered" = "Delivered";
"Conversation.ChecksTooltip.Read" = "Read";

View File

@ -1252,6 +1252,8 @@ private final class TimePickerNode: ASDisplayNode {
break
}
}
self.update()
}
override func didLoad() {

View File

@ -16,7 +16,7 @@ public final class TextFieldNodeView: UITextField {
}
override public func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return self.editingRect(forBounds: bounds.offsetBy(dx: 0.0, dy: -1.0))
return self.editingRect(forBounds: bounds.offsetBy(dx: 0.0, dy: 0.0))
}
override public func deleteBackward() {

View File

@ -17,6 +17,7 @@ import PresentationDataUtils
import AppBundle
import ContextUI
import TelegramStringFormatting
import UndoUI
private final class InviteLinkEditControllerArguments {
let context: AccountContext
@ -40,6 +41,9 @@ private enum InviteLinksEditSection: Int32 {
private let invalidAmountCharacters = CharacterSet(charactersIn: "01234567890.,").inverted
func isValidNumberOfUsers(_ number: String) -> Bool {
if number.isEmpty {
return true
}
let number = normalizeArabicNumeralString(number, type: .western)
if number.rangeOfCharacter(from: invalidAmountCharacters) != nil || number == "0" {
return false
@ -233,12 +237,11 @@ private enum InviteLinksEditEntry: ItemListNodeEntry {
text = focused ? "" : presentationData.strings.InviteLink_Create_UsersLimitNumberOfUsersUnlimited
}
return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: presentationData.strings.InviteLink_Create_UsersLimitNumberOfUsers, textColor: theme.list.itemPrimaryTextColor), text: text, placeholder: "", type: .number, alignment: .right, selectAllOnFocus: true, secondaryStyle: !customValue, tag: nil, sectionId: self.section, textUpdated: { updatedText in
guard !updatedText.isEmpty else {
return
}
arguments.updateState { state in
var updatedState = state
if let value = Int32(updatedText) {
if updatedText.isEmpty {
updatedState.usage = .unlimited
} else if let value = Int32(updatedText) {
updatedState.usage = InviteLinkUsageLimit(value: value)
}
return updatedState
@ -395,6 +398,9 @@ public func inviteLinkEditController(context: AccountContext, peerId: PeerId, in
case let .replace(_, invitation):
completion?(invitation)
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkRevoked(text: presentationData.strings.InviteLink_InviteLinkRevoked), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
}, error: { _ in
updateState { state in
var updatedState = state

View File

@ -396,6 +396,9 @@ public final class InviteLinkInviteController: ViewController {
mainInvitePromise.set(invite)
}
})
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkRevoked(text: presentationData.strings.InviteLink_InviteLinkRevoked), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
}
})
]),

View File

@ -320,8 +320,8 @@ private func inviteLinkListControllerEntries(presentationData: PresentationData,
}
var hasLinks = false
if let additionalInvites = additionalInvites, !additionalInvites.isEmpty {
hasLinks = true
if let additionalInvites = additionalInvites {
hasLinks = !additionalInvites.isEmpty
} else if let admin = admin, admin.count > 1 {
hasLinks = true
}
@ -422,6 +422,10 @@ public func inviteLinkListController(context: AccountContext, peerId: PeerId, ad
let arguments = InviteLinkListControllerArguments(context: context, shareMainLink: { invite in
let shareController = ShareController(context: context, subject: .url(invite.link))
shareController.actionCompleted = {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
}
presentControllerImpl?(shareController, nil)
}, openMainLink: { invite in
let controller = InviteLinkViewController(context: context, peerId: peerId, invite: invite, invitationsContext: nil, revokedInvitationsContext: revokedInvitesContext, importersContext: nil)
@ -525,6 +529,9 @@ public func inviteLinkListController(context: AccountContext, peerId: PeerId, ad
invitesContext.add(newInvite)
}
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkRevoked(text: presentationData.strings.InviteLink_InviteLinkRevoked), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
}))
}
})
@ -580,6 +587,10 @@ public func inviteLinkListController(context: AccountContext, peerId: PeerId, ad
f(.default)
let shareController = ShareController(context: context, subject: .url(invite.link))
shareController.actionCompleted = {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
}
presentControllerImpl?(shareController, nil)
})))
@ -680,6 +691,9 @@ public func inviteLinkListController(context: AccountContext, peerId: PeerId, ad
invitesContext.remove(invite)
revokedInvitesContext.add(invite.withUpdated(isRevoked: true))
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkRevoked(text: presentationData.strings.InviteLink_InviteLinkRevoked), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
})
]),
ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })])

View File

@ -435,6 +435,10 @@ public final class InviteLinkViewController: ViewController {
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
}, shareLink: { [weak self] invite in
let shareController = ShareController(context: context, subject: .url(invite.link))
shareController.actionCompleted = { [weak self] in
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
}
self?.controller?.present(shareController, in: .window(.root))
}, editLink: { [weak self] invite in
self?.editButtonPressed()
@ -537,6 +541,9 @@ public final class InviteLinkViewController: ViewController {
self?.controller?.invitationsContext?.remove(invite)
let revokedInvite = invite.withUpdated(isRevoked: true)
self?.controller?.revokedInvitationsContext?.add(revokedInvite)
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkRevoked(text: presentationData.strings.InviteLink_InviteLinkRevoked), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
})
]),
ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })])

View File

@ -918,6 +918,10 @@ public func channelVisibilityController(context: AccountContext, peerId: PeerId,
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
}, shareLink: { invite in
let shareController = ShareController(context: context, subject: .url(invite.link))
shareController.actionCompleted = {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
}
presentControllerImpl?(shareController, nil)
}, linkContextAction: { node in
guard let node = node as? ContextExtractedContentContainingNode, let controller = getControllerImpl?() else {

View File

@ -304,6 +304,7 @@ public final class ShareController: ViewController {
private var defaultAction: ShareControllerAction?
public var actionCompleted: (() -> Void)?
public var dismissed: ((Bool) -> Void)?
public var completed: (([PeerId]) -> Void)? {
didSet {
@ -346,6 +347,8 @@ public final class ShareController: ViewController {
self.defaultAction = ShareControllerAction(title: forcedActionTitle ?? self.presentationData.strings.ShareMenu_CopyShareLink, action: { [weak self] in
UIPasteboard.general.string = text
self?.controllerNode.cancel?()
self?.actionCompleted?()
})
case .text:
break
@ -355,6 +358,8 @@ public final class ShareController: ViewController {
let url = "https://maps.apple.com/maps?ll=\(latLong)&q=\(latLong)&t=m"
UIPasteboard.general.string = url
self?.controllerNode.cancel?()
self?.actionCompleted?()
})
break
case .quote:
@ -363,6 +368,7 @@ public final class ShareController: ViewController {
if case .saveToCameraRoll = preferredAction {
self.defaultAction = ShareControllerAction(title: self.presentationData.strings.Preview_SaveToCameraRoll, action: { [weak self] in
self?.saveToCameraRoll(representations: representations)
self?.actionCompleted?()
})
}
case let .media(mediaReference):
@ -375,12 +381,14 @@ public final class ShareController: ViewController {
if case .saveToCameraRoll = preferredAction, canSave {
self.defaultAction = ShareControllerAction(title: self.presentationData.strings.Preview_SaveToCameraRoll, action: { [weak self] in
self?.saveToCameraRoll(mediaReference: mediaReference)
self?.actionCompleted?()
})
}
case let .messages(messages):
if case .saveToCameraRoll = preferredAction {
self.defaultAction = ShareControllerAction(title: self.presentationData.strings.Preview_SaveToCameraRoll, action: { [weak self] in
self?.saveToCameraRoll(messages: messages)
self?.actionCompleted?()
})
} else if let message = messages.first {
let groupingKey: Int64? = message.groupingKey
@ -397,6 +405,7 @@ public final class ShareController: ViewController {
self.defaultAction = ShareControllerAction(title: self.presentationData.strings.SharedMedia_ViewInChat, action: { [weak self] in
self?.controllerNode.cancel?()
showInChat(message)
self?.actionCompleted?()
})
} else if let chatPeer = message.peers[message.id.peerId] as? TelegramChannel, messages.count == 1 || sameGroupingKey {
if message.id.namespace == Namespaces.Message.Cloud {
@ -414,6 +423,7 @@ public final class ShareController: ViewController {
}
})
strongSelf.controllerNode.cancel?()
strongSelf.actionCompleted?()
})
}
}
@ -426,6 +436,7 @@ public final class ShareController: ViewController {
self.defaultAction = ShareControllerAction(title: action.title, action: { [weak self] in
self?.controllerNode.cancel?()
action.action()
self?.actionCompleted?()
})
}

View File

@ -599,6 +599,7 @@ public final class VoiceChatController: ViewController {
private var didSetContentsReady: Bool = false
private var didSetDataReady: Bool = false
private var peer: Peer?
private var currentTitle: String = ""
private var currentSubtitle: String = ""
private var currentCallMembers: ([GroupCallParticipantsContext.Participant], String?)?
@ -1298,6 +1299,7 @@ public final class VoiceChatController: ViewController {
}
if let peer = peerViewMainPeer(view) {
strongSelf.peer = peer
strongSelf.currentTitle = peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)
}
if !strongSelf.didSetDataReady {
@ -2466,8 +2468,17 @@ public final class VoiceChatController: ViewController {
var processedPeerIds = Set<PeerId>()
entries.append(.invite(self.presentationData.theme, self.presentationData.strings, self.presentationData.strings.VoiceChat_InviteMember))
var canInvite = true
if let peer = self.peer as? TelegramChannel, peer.flags.contains(.isGigagroup) {
if peer.flags.contains(.isCreator) || peer.adminRights != nil {
} else {
canInvite = false
}
}
if canInvite {
entries.append(.invite(self.presentationData.theme, self.presentationData.strings, self.presentationData.strings.VoiceChat_InviteMember))
}
for member in callMembers.0 {
if processedPeerIds.contains(member.peer.id) {
continue

File diff suppressed because one or more lines are too long

View File

@ -55,6 +55,13 @@ private func canEditMessage(accountPeerId: PeerId, limitsConfiguration: LimitsCo
} else if let author = message.author, author.id == accountPeerId, let peer = message.peers[message.id.peerId] {
hasEditRights = true
if let peer = peer as? TelegramChannel {
if peer.flags.contains(.isGigagroup) {
if peer.flags.contains(.isCreator) || peer.adminRights != nil {
hasEditRights = true
} else {
hasEditRights = false
}
}
switch peer.info {
case .broadcast:
if peer.hasPermission(.editAllMessages) || !message.flags.contains(.Incoming) {

View File

@ -6252,7 +6252,7 @@ func presentAddMembers(context: AccountContext, parentController: ViewController
default:
break
}
} else if let channel = groupPeer as? TelegramChannel {
} else if let channel = groupPeer as? TelegramChannel, (channel.addressName?.isEmpty ?? true) {
if channel.flags.contains(.isCreator) || (channel.adminRights?.flags.contains(.canInviteUsers) == true) {
canCreateInviteLink = true
}

View File

@ -31,6 +31,7 @@ public enum UndoOverlayContent {
case forward(savedMessages: Bool, text: String)
case autoDelete(isOn: Bool, title: String?, text: String)
case gigagroupConversion(text: String)
case linkRevoked(text: String)
}
public enum UndoOverlayAction {

View File

@ -534,6 +534,21 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
self.textNode.attributedText = attributedText
self.textNode.maximumNumberOfLines = 2
displayUndo = false
self.originalRemainingSeconds = 3
case let .linkRevoked(text):
self.avatarNode = nil
self.iconNode = nil
self.iconCheckNode = nil
self.animationNode = AnimationNode(animation: "anim_linkrevoked", colors: [:], scale: 0.066)
self.animatedStickerNode = nil
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white)
let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white)
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in return nil }), textAlignment: .natural)
self.textNode.attributedText = attributedText
self.textNode.maximumNumberOfLines = 2
displayUndo = false
self.originalRemainingSeconds = 3
}
@ -564,7 +579,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
switch content {
case .removedChat:
self.panelWrapperNode.addSubnode(self.timerTextNode)
case .archivedChat, .hidArchive, .revealedArchive, .autoDelete, .succeed, .emoji, .swipeToReply, .actionSucceeded, .stickersModified, .chatAddedToFolder, .chatRemovedFromFolder, .messagesUnpinned, .setProximityAlert, .invitedToVoiceChat, .linkCopied, .banned, .importedMessage, .audioRate, .forward, .gigagroupConversion:
case .archivedChat, .hidArchive, .revealedArchive, .autoDelete, .succeed, .emoji, .swipeToReply, .actionSucceeded, .stickersModified, .chatAddedToFolder, .chatRemovedFromFolder, .messagesUnpinned, .setProximityAlert, .invitedToVoiceChat, .linkCopied, .banned, .importedMessage, .audioRate, .forward, .gigagroupConversion, .linkRevoked:
break
case .dice:
self.panelWrapperNode.clipsToBounds = true

View File

@ -522,7 +522,10 @@ public func resolveUrlImpl(account: Account, url: String) -> Signal<ResolvedUrl,
let urlHandlingConfiguration = UrlHandlingConfiguration.with(appConfiguration: appConfiguration)
var url = url
if let urlValue = URL(string: url), let host = urlValue.host, urlHandlingConfiguration.domains.contains(host), var components = URLComponents(string: url) {
if !(url.hasPrefix("http") || url.hasPrefix("https")) {
url = "http://\(url)"
}
if let urlValue = URL(string: url), let host = urlValue.host, urlHandlingConfiguration.domains.contains(host.lowercased()), var components = URLComponents(string: url) {
components.scheme = "https"
var queryItems = components.queryItems ?? []
queryItems.append(URLQueryItem(name: "autologin_token", value: urlHandlingConfiguration.token))