mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit 'b738beaf55c533f99b30e75dd9bee0d54d10958a'
This commit is contained in:
commit
426c1859a6
@ -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";
|
||||
|
||||
|
@ -1252,6 +1252,8 @@ private final class TimePickerNode: ASDisplayNode {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
self.update()
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
}
|
||||
})
|
||||
]),
|
||||
|
@ -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() })])
|
||||
|
@ -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() })])
|
||||
|
@ -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 {
|
||||
|
@ -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?()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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 it is too large
Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user