mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 08:31:13 +00:00
Various Fixes
This commit is contained in:
parent
35d39c6fbc
commit
d2015f3375
@ -7057,6 +7057,11 @@ Sorry for the inconvenience.";
|
|||||||
"Conversation.CopyProtectionInfoGroup" = "Admins restricted members to copy or forward content from this group.";
|
"Conversation.CopyProtectionInfoGroup" = "Admins restricted members to copy or forward content from this group.";
|
||||||
"Conversation.CopyProtectionInfoChannel" = "Admins restricted members to copy or forward content from this channel.";
|
"Conversation.CopyProtectionInfoChannel" = "Admins restricted members to copy or forward content from this channel.";
|
||||||
|
|
||||||
|
"Conversation.CopyProtectionForwardingDisabledGroup" = "Forwards from this group are restricted";
|
||||||
|
"Conversation.CopyProtectionForwardingDisabledChannel" = "Forwards from this channel are restricted";
|
||||||
|
"Conversation.CopyProtectionSavingDisabledGroup" = "Saving from this group is restricted";
|
||||||
|
"Conversation.CopyProtectionSavingDisabledChannel" = "Saving from this channel is restricted";
|
||||||
|
|
||||||
"Channel.AdminLog.MessageToggleNoForwardsOn" = "%@ restricted message forwarding";
|
"Channel.AdminLog.MessageToggleNoForwardsOn" = "%@ restricted message forwarding";
|
||||||
"Channel.AdminLog.MessageToggleNoForwardsOff" = "%@ allowed message forwarding";
|
"Channel.AdminLog.MessageToggleNoForwardsOff" = "%@ allowed message forwarding";
|
||||||
|
|
||||||
|
@ -13,15 +13,18 @@ public enum SharedMediaPlaybackDataType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum SharedMediaPlaybackDataSource: Equatable {
|
public enum SharedMediaPlaybackDataSource: Equatable {
|
||||||
case telegramFile(FileMediaReference)
|
case telegramFile(reference: FileMediaReference, isCopyProtected: Bool)
|
||||||
|
|
||||||
public static func ==(lhs: SharedMediaPlaybackDataSource, rhs: SharedMediaPlaybackDataSource) -> Bool {
|
public static func ==(lhs: SharedMediaPlaybackDataSource, rhs: SharedMediaPlaybackDataSource) -> Bool {
|
||||||
switch lhs {
|
switch lhs {
|
||||||
case let .telegramFile(lhsFileReference):
|
case let .telegramFile(lhsFileReference, lhsIsCopyProtected):
|
||||||
if case let .telegramFile(rhsFileReference) = rhs {
|
if case let .telegramFile(rhsFileReference, rhsIsCopyProtected) = rhs {
|
||||||
if !lhsFileReference.media.isEqual(to: rhsFileReference.media) {
|
if !lhsFileReference.media.isEqual(to: rhsFileReference.media) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhsIsCopyProtected != rhsIsCopyProtected {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
|
@ -2423,8 +2423,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
let url = content.url
|
let url = content.url
|
||||||
|
|
||||||
let item = OpenInItem.url(url: url)
|
let item = OpenInItem.url(url: url)
|
||||||
let canOpenIn = availableOpenInOptions(context: strongSelf.context, item: item).count > 1
|
let openText = strongSelf.presentationData.strings.Conversation_FileOpenIn
|
||||||
let openText = canOpenIn ? strongSelf.presentationData.strings.Conversation_FileOpenIn : strongSelf.presentationData.strings.Conversation_LinkDialogOpen
|
|
||||||
items.append(.action(ContextMenuActionItem(text: openText, textColor: .primary, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Share"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
items.append(.action(ContextMenuActionItem(text: openText, textColor: .primary, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Share"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||||
f(.default)
|
f(.default)
|
||||||
|
|
||||||
@ -2446,7 +2445,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let (message, maybeFile, _) = strongSelf.contentInfo(), let file = maybeFile {
|
if let (message, maybeFile, _) = strongSelf.contentInfo(), let file = maybeFile, !message.isCopyProtected() {
|
||||||
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Gallery_SaveVideo, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) }, action: { _, f in
|
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Gallery_SaveVideo, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) }, action: { _, f in
|
||||||
f(.default)
|
f(.default)
|
||||||
|
|
||||||
|
@ -46,13 +46,13 @@ final class InstantPageMediaPlaylistItem: SharedMediaPlaylistItem {
|
|||||||
switch attribute {
|
switch attribute {
|
||||||
case let .Audio(isVoice, _, _, _, _):
|
case let .Audio(isVoice, _, _, _, _):
|
||||||
if isVoice {
|
if isVoice {
|
||||||
return SharedMediaPlaybackData(type: .voice, source: .telegramFile(.webPage(webPage: WebpageReference(self.webPage), media: file)))
|
return SharedMediaPlaybackData(type: .voice, source: .telegramFile(reference: .webPage(webPage: WebpageReference(self.webPage), media: file), isCopyProtected: false))
|
||||||
} else {
|
} else {
|
||||||
return SharedMediaPlaybackData(type: .music, source: .telegramFile(.webPage(webPage: WebpageReference(self.webPage), media: file)))
|
return SharedMediaPlaybackData(type: .music, source: .telegramFile(reference: .webPage(webPage: WebpageReference(self.webPage), media: file), isCopyProtected: false))
|
||||||
}
|
}
|
||||||
case let .Video(_, _, flags):
|
case let .Video(_, _, flags):
|
||||||
if flags.contains(.instantRoundVideo) {
|
if flags.contains(.instantRoundVideo) {
|
||||||
return SharedMediaPlaybackData(type: .instantVideo, source: .telegramFile(.webPage(webPage: WebpageReference(self.webPage), media: file)))
|
return SharedMediaPlaybackData(type: .instantVideo, source: .telegramFile(reference: .webPage(webPage: WebpageReference(self.webPage), media: file), isCopyProtected: false))
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -61,12 +61,12 @@ final class InstantPageMediaPlaylistItem: SharedMediaPlaylistItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if file.mimeType.hasPrefix("audio/") {
|
if file.mimeType.hasPrefix("audio/") {
|
||||||
return SharedMediaPlaybackData(type: .music, source: .telegramFile(.webPage(webPage: WebpageReference(self.webPage), media: file)))
|
return SharedMediaPlaybackData(type: .music, source: .telegramFile(reference: .webPage(webPage: WebpageReference(self.webPage), media: file), isCopyProtected: false))
|
||||||
}
|
}
|
||||||
if let fileName = file.fileName {
|
if let fileName = file.fileName {
|
||||||
let ext = (fileName as NSString).pathExtension.lowercased()
|
let ext = (fileName as NSString).pathExtension.lowercased()
|
||||||
if ext == "wav" || ext == "opus" {
|
if ext == "wav" || ext == "opus" {
|
||||||
return SharedMediaPlaybackData(type: .music, source: .telegramFile(.webPage(webPage: WebpageReference(self.webPage), media: file)))
|
return SharedMediaPlaybackData(type: .music, source: .telegramFile(reference: .webPage(webPage: WebpageReference(self.webPage), media: file), isCopyProtected: false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@ final class AvatarGalleryItemFooterContentNode: GalleryFooterContentNode {
|
|||||||
var dateText: String?
|
var dateText: String?
|
||||||
var typeText: String?
|
var typeText: String?
|
||||||
var buttonText: String?
|
var buttonText: String?
|
||||||
|
var canShare = true
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .image(_, _, _, videoRepresentations, peer, date, _, _, _, _):
|
case let .image(_, _, _, videoRepresentations, peer, date, _, _, _, _):
|
||||||
nameText = peer.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? ""
|
nameText = peer.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? ""
|
||||||
@ -119,6 +120,10 @@ final class AvatarGalleryItemFooterContentNode: GalleryFooterContentNode {
|
|||||||
typeText = self.strings.ProfilePhoto_MainPhoto
|
typeText = self.strings.ProfilePhoto_MainPhoto
|
||||||
buttonText = self.strings.ProfilePhoto_SetMainPhoto
|
buttonText = self.strings.ProfilePhoto_SetMainPhoto
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let peer = peer {
|
||||||
|
canShare = !peer.isCopyProtectionEnabled
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -151,6 +156,8 @@ final class AvatarGalleryItemFooterContentNode: GalleryFooterContentNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.actionButton.isHidden = !canShare
|
||||||
|
|
||||||
switch content {
|
switch content {
|
||||||
case .info:
|
case .info:
|
||||||
self.nameNode.isHidden = false
|
self.nameNode.isHidden = false
|
||||||
|
@ -757,7 +757,7 @@ public func recentSessionsController(context: AccountContext, activeSessionsCont
|
|||||||
pushControllerImpl?(AuthTransferScanScreen(context: context, activeSessionsContext: activeSessionsContext))
|
pushControllerImpl?(AuthTransferScanScreen(context: context, activeSessionsContext: activeSessionsContext))
|
||||||
})
|
})
|
||||||
}, openOtherAppsUrl: {
|
}, openOtherAppsUrl: {
|
||||||
context.sharedContext.openExternalUrl(context: context, urlContext: .generic, url: "https://desktop.telegram.org", forceExternal: true, presentationData: context.sharedContext.currentPresentationData.with { $0 }, navigationController: nil, dismissInput: {})
|
context.sharedContext.openExternalUrl(context: context, urlContext: .generic, url: "https://getdesktop.telegram.org", forceExternal: true, presentationData: context.sharedContext.currentPresentationData.with { $0 }, navigationController: nil, dismissInput: {})
|
||||||
}, setupAuthorizationTTL: {
|
}, setupAuthorizationTTL: {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let controller = ActionSheetController(presentationData: presentationData)
|
let controller = ActionSheetController(presentationData: presentationData)
|
||||||
|
@ -131,7 +131,7 @@ class RecentSessionsHeaderItemNode: ListViewItemNode {
|
|||||||
|
|
||||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: attributedText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - leftInset * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: attributedText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - leftInset * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
let contentSize = CGSize(width: params.width, height: topInset + titleLayout.size.height + 85.0)
|
let contentSize = CGSize(width: params.width, height: topInset + titleLayout.size.height + 69.0)
|
||||||
let insets = itemListNeighborsGroupedInsets(neighbors, params)
|
let insets = itemListNeighborsGroupedInsets(neighbors, params)
|
||||||
|
|
||||||
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
||||||
@ -150,9 +150,9 @@ class RecentSessionsHeaderItemNode: ListViewItemNode {
|
|||||||
strongSelf.buttonNode.updateTheme(SolidRoundedButtonTheme(theme: item.theme))
|
strongSelf.buttonNode.updateTheme(SolidRoundedButtonTheme(theme: item.theme))
|
||||||
}
|
}
|
||||||
|
|
||||||
let buttonWidth = contentSize.width - 32.0
|
let buttonWidth = min(375, contentSize.width - params.leftInset - params.rightInset)
|
||||||
let buttonHeight = strongSelf.buttonNode.updateLayout(width: buttonWidth, transition: .immediate)
|
let buttonHeight = strongSelf.buttonNode.updateLayout(width: buttonWidth, transition: .immediate)
|
||||||
let buttonFrame = CGRect(x: 16.0, y: contentSize.height - buttonHeight - 12.0, width: buttonWidth, height: buttonHeight)
|
let buttonFrame = CGRect(x: params.leftInset, y: contentSize.height - buttonHeight + 4.0, width: buttonWidth, height: buttonHeight)
|
||||||
strongSelf.buttonNode.frame = buttonFrame
|
strongSelf.buttonNode.frame = buttonFrame
|
||||||
|
|
||||||
strongSelf.accessibilityLabel = attributedText.string
|
strongSelf.accessibilityLabel = attributedText.string
|
||||||
|
@ -782,15 +782,15 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
|
|
||||||
let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp())
|
let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp())
|
||||||
|
|
||||||
var needShareButton = false
|
var needsShareButton = false
|
||||||
if case .pinnedMessages = item.associatedData.subject {
|
if case .pinnedMessages = item.associatedData.subject {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
} else if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) {
|
} else if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) {
|
||||||
needShareButton = false
|
needsShareButton = false
|
||||||
} else if item.message.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) {
|
} else if item.message.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) {
|
||||||
for attribute in item.content.firstMessage.attributes {
|
for attribute in item.content.firstMessage.attributes {
|
||||||
if let _ = attribute as? SourceReferenceMessageAttribute {
|
if let _ = attribute as? SourceReferenceMessageAttribute {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -798,31 +798,35 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
if let peer = item.message.peers[item.message.id.peerId] {
|
if let peer = item.message.peers[item.message.id.peerId] {
|
||||||
if let channel = peer as? TelegramChannel {
|
if let channel = peer as? TelegramChannel {
|
||||||
if case .broadcast = channel.info {
|
if case .broadcast = channel.info {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !needShareButton, let author = item.message.author as? TelegramUser, let _ = author.botInfo, !item.message.media.isEmpty {
|
if !needsShareButton, let author = item.message.author as? TelegramUser, let _ = author.botInfo, !item.message.media.isEmpty {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
}
|
}
|
||||||
if !needShareButton {
|
if !needsShareButton {
|
||||||
loop: for media in item.message.media {
|
loop: for media in item.message.media {
|
||||||
if media is TelegramMediaGame || media is TelegramMediaInvoice {
|
if media is TelegramMediaGame || media is TelegramMediaInvoice {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
break loop
|
break loop
|
||||||
} else if let media = media as? TelegramMediaWebpage, case .Loaded = media.content {
|
} else if let media = media as? TelegramMediaWebpage, case .Loaded = media.content {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
loop: for media in item.message.media {
|
loop: for media in item.message.media {
|
||||||
if media is TelegramMediaAction {
|
if media is TelegramMediaAction {
|
||||||
needShareButton = false
|
needsShareButton = false
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if item.associatedData.isCopyProtectionEnabled {
|
||||||
|
needsShareButton = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var layoutInsets = UIEdgeInsets(top: mergedTop.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, left: 0.0, bottom: mergedBottom.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, right: 0.0)
|
var layoutInsets = UIEdgeInsets(top: mergedTop.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, left: 0.0, bottom: mergedBottom.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, right: 0.0)
|
||||||
@ -955,7 +959,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var updatedShareButtonNode: ChatMessageShareButton?
|
var updatedShareButtonNode: ChatMessageShareButton?
|
||||||
if needShareButton {
|
if needsShareButton {
|
||||||
if let currentShareButtonNode = currentShareButtonNode {
|
if let currentShareButtonNode = currentShareButtonNode {
|
||||||
updatedShareButtonNode = currentShareButtonNode
|
updatedShareButtonNode = currentShareButtonNode
|
||||||
} else {
|
} else {
|
||||||
|
@ -1118,6 +1118,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
|||||||
tmpWidth = baseWidth
|
tmpWidth = baseWidth
|
||||||
if needsShareButton || isAd {
|
if needsShareButton || isAd {
|
||||||
tmpWidth -= 38.0
|
tmpWidth -= 38.0
|
||||||
|
} else {
|
||||||
|
tmpWidth -= 4.0
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmpWidth = layoutConstants.bubble.maximumWidthFill.widthFor(baseWidth)
|
tmpWidth = layoutConstants.bubble.maximumWidthFill.widthFor(baseWidth)
|
||||||
|
@ -501,7 +501,11 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
|
|||||||
if self.peerId.namespace == Namespaces.Peer.Empty, case let .message(_, id, _, _, _) = self.messageReference?.content {
|
if self.peerId.namespace == Namespaces.Peer.Empty, case let .message(_, id, _, _, _) = self.messageReference?.content {
|
||||||
self.controllerInteraction.displayMessageTooltip(id, self.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, self.avatarNode.frame)
|
self.controllerInteraction.displayMessageTooltip(id, self.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, self.avatarNode.frame)
|
||||||
} else {
|
} else {
|
||||||
self.controllerInteraction.openPeer(self.peerId, .info, nil)
|
if let channel = self.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||||
|
self.controllerInteraction.openPeer(self.peerId, .chat(textInputState: nil, subject: nil, peekData: nil), nil)
|
||||||
|
} else {
|
||||||
|
self.controllerInteraction.openPeer(self.peerId, .info, nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,16 +306,16 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
|||||||
|
|
||||||
let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp())
|
let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp())
|
||||||
|
|
||||||
var needShareButton = false
|
var needsShareButton = false
|
||||||
if case .pinnedMessages = item.associatedData.subject {
|
if case .pinnedMessages = item.associatedData.subject {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
} else if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) {
|
} else if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) {
|
||||||
needShareButton = false
|
needsShareButton = false
|
||||||
}
|
}
|
||||||
else if item.message.id.peerId == item.context.account.peerId {
|
else if item.message.id.peerId == item.context.account.peerId {
|
||||||
for attribute in item.content.firstMessage.attributes {
|
for attribute in item.content.firstMessage.attributes {
|
||||||
if let _ = attribute as? SourceReferenceMessageAttribute {
|
if let _ = attribute as? SourceReferenceMessageAttribute {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,31 +323,35 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
|||||||
if let peer = item.message.peers[item.message.id.peerId] {
|
if let peer = item.message.peers[item.message.id.peerId] {
|
||||||
if let channel = peer as? TelegramChannel {
|
if let channel = peer as? TelegramChannel {
|
||||||
if case .broadcast = channel.info {
|
if case .broadcast = channel.info {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !needShareButton, let author = item.message.author as? TelegramUser, let _ = author.botInfo, !item.message.media.isEmpty {
|
if !needsShareButton, let author = item.message.author as? TelegramUser, let _ = author.botInfo, !item.message.media.isEmpty {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
}
|
}
|
||||||
if !needShareButton {
|
if !needsShareButton {
|
||||||
loop: for media in item.message.media {
|
loop: for media in item.message.media {
|
||||||
if media is TelegramMediaGame || media is TelegramMediaInvoice {
|
if media is TelegramMediaGame || media is TelegramMediaInvoice {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
break loop
|
break loop
|
||||||
} else if let media = media as? TelegramMediaWebpage, case .Loaded = media.content {
|
} else if let media = media as? TelegramMediaWebpage, case .Loaded = media.content {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
loop: for media in item.message.media {
|
loop: for media in item.message.media {
|
||||||
if media is TelegramMediaAction {
|
if media is TelegramMediaAction {
|
||||||
needShareButton = false
|
needsShareButton = false
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if item.associatedData.isCopyProtectionEnabled {
|
||||||
|
needsShareButton = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var layoutInsets = layoutConstants.instantVideo.insets
|
var layoutInsets = layoutConstants.instantVideo.insets
|
||||||
@ -472,7 +476,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
|||||||
}
|
}
|
||||||
|
|
||||||
var updatedShareButtonNode: ChatMessageShareButton?
|
var updatedShareButtonNode: ChatMessageShareButton?
|
||||||
if needShareButton {
|
if needsShareButton {
|
||||||
if currentShareButtonNode != nil {
|
if currentShareButtonNode != nil {
|
||||||
updatedShareButtonNode = currentShareButtonNode
|
updatedShareButtonNode = currentShareButtonNode
|
||||||
} else {
|
} else {
|
||||||
|
@ -380,15 +380,15 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
|
|
||||||
let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp())
|
let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp())
|
||||||
|
|
||||||
var needShareButton = false
|
var needsShareButton = false
|
||||||
if case .pinnedMessages = item.associatedData.subject {
|
if case .pinnedMessages = item.associatedData.subject {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
} else if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) {
|
} else if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) {
|
||||||
needShareButton = false
|
needsShareButton = false
|
||||||
} else if item.message.id.peerId == item.context.account.peerId {
|
} else if item.message.id.peerId == item.context.account.peerId {
|
||||||
for attribute in item.content.firstMessage.attributes {
|
for attribute in item.content.firstMessage.attributes {
|
||||||
if let _ = attribute as? SourceReferenceMessageAttribute {
|
if let _ = attribute as? SourceReferenceMessageAttribute {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,31 +396,35 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
if let peer = item.message.peers[item.message.id.peerId] {
|
if let peer = item.message.peers[item.message.id.peerId] {
|
||||||
if let channel = peer as? TelegramChannel {
|
if let channel = peer as? TelegramChannel {
|
||||||
if case .broadcast = channel.info {
|
if case .broadcast = channel.info {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !needShareButton, let author = item.message.author as? TelegramUser, let _ = author.botInfo, !item.message.media.isEmpty {
|
if !needsShareButton, let author = item.message.author as? TelegramUser, let _ = author.botInfo, !item.message.media.isEmpty {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
}
|
}
|
||||||
if !needShareButton {
|
if !needsShareButton {
|
||||||
loop: for media in item.message.media {
|
loop: for media in item.message.media {
|
||||||
if media is TelegramMediaGame || media is TelegramMediaInvoice {
|
if media is TelegramMediaGame || media is TelegramMediaInvoice {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
break loop
|
break loop
|
||||||
} else if let media = media as? TelegramMediaWebpage, case .Loaded = media.content {
|
} else if let media = media as? TelegramMediaWebpage, case .Loaded = media.content {
|
||||||
needShareButton = true
|
needsShareButton = true
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
loop: for media in item.message.media {
|
loop: for media in item.message.media {
|
||||||
if media is TelegramMediaAction {
|
if media is TelegramMediaAction {
|
||||||
needShareButton = false
|
needsShareButton = false
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if item.associatedData.isCopyProtectionEnabled {
|
||||||
|
needsShareButton = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var layoutInsets = UIEdgeInsets(top: mergedTop.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, left: 0.0, bottom: mergedBottom.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, right: 0.0)
|
var layoutInsets = UIEdgeInsets(top: mergedTop.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, left: 0.0, bottom: mergedBottom.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, right: 0.0)
|
||||||
@ -553,7 +557,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var updatedShareButtonNode: ChatMessageShareButton?
|
var updatedShareButtonNode: ChatMessageShareButton?
|
||||||
if needShareButton {
|
if needsShareButton {
|
||||||
if let currentShareButtonNode = currentShareButtonNode {
|
if let currentShareButtonNode = currentShareButtonNode {
|
||||||
updatedShareButtonNode = currentShareButtonNode
|
updatedShareButtonNode = currentShareButtonNode
|
||||||
} else {
|
} else {
|
||||||
|
@ -1115,7 +1115,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
|||||||
var hasMenuButton = false
|
var hasMenuButton = false
|
||||||
var menuButtonExpanded = false
|
var menuButtonExpanded = false
|
||||||
var isSendAsButton = false
|
var isSendAsButton = false
|
||||||
if let sendAsPeers = interfaceState.sendAsPeers, !sendAsPeers.isEmpty {
|
if let sendAsPeers = interfaceState.sendAsPeers, !sendAsPeers.isEmpty && interfaceState.editMessageState == nil {
|
||||||
hasMenuButton = true
|
hasMenuButton = true
|
||||||
menuButtonExpanded = false
|
menuButtonExpanded = false
|
||||||
isSendAsButton = true
|
isSendAsButton = true
|
||||||
|
@ -111,14 +111,16 @@ final class DocumentPreviewController: UINavigationController, QLPreviewControll
|
|||||||
final class CompactDocumentPreviewController: QLPreviewController, QLPreviewControllerDelegate, QLPreviewControllerDataSource {
|
final class CompactDocumentPreviewController: QLPreviewController, QLPreviewControllerDelegate, QLPreviewControllerDataSource {
|
||||||
private let postbox: Postbox
|
private let postbox: Postbox
|
||||||
private let file: TelegramMediaFile
|
private let file: TelegramMediaFile
|
||||||
|
private let canShare: Bool
|
||||||
|
|
||||||
private var item: DocumentPreviewItem?
|
private var item: DocumentPreviewItem?
|
||||||
|
|
||||||
private var tempFile: TempBoxFile?
|
private var tempFile: TempBoxFile?
|
||||||
|
|
||||||
init(theme: PresentationTheme, strings: PresentationStrings, postbox: Postbox, file: TelegramMediaFile) {
|
init(theme: PresentationTheme, strings: PresentationStrings, postbox: Postbox, file: TelegramMediaFile, canShare: Bool = true) {
|
||||||
self.postbox = postbox
|
self.postbox = postbox
|
||||||
self.file = file
|
self.file = file
|
||||||
|
self.canShare = canShare
|
||||||
|
|
||||||
super.init(nibName: nil, bundle: nil)
|
super.init(nibName: nil, bundle: nil)
|
||||||
|
|
||||||
@ -144,6 +146,7 @@ final class CompactDocumentPreviewController: QLPreviewController, QLPreviewCont
|
|||||||
if let tempFile = self.tempFile {
|
if let tempFile = self.tempFile {
|
||||||
TempBox.shared.dispose(tempFile)
|
TempBox.shared.dispose(tempFile)
|
||||||
}
|
}
|
||||||
|
self.timer?.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func cancelPressed() {
|
@objc private func cancelPressed() {
|
||||||
@ -174,9 +177,51 @@ final class CompactDocumentPreviewController: QLPreviewController, QLPreviewCont
|
|||||||
func previewControllerDidDismiss(_ controller: QLPreviewController) {
|
func previewControllerDidDismiss(_ controller: QLPreviewController) {
|
||||||
//self.cancelPressed()
|
//self.cancelPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var toolbars: [UIView] = []
|
||||||
|
private var observations : [NSKeyValueObservation] = []
|
||||||
|
|
||||||
|
private var initialized = false
|
||||||
|
private var timer: SwiftSignalKit.Timer?
|
||||||
|
override func viewDidLayoutSubviews() {
|
||||||
|
super.viewDidLayoutSubviews()
|
||||||
|
|
||||||
|
if !self.canShare && !self.initialized {
|
||||||
|
self.initialized = true
|
||||||
|
|
||||||
|
self.timer = SwiftSignalKit.Timer(timeout: 0.01, repeat: true, completion: { [weak self] in
|
||||||
|
self?.tick()
|
||||||
|
}, queue: Queue.mainQueue())
|
||||||
|
self.timer?.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func tick() {
|
||||||
|
self.navigationItem.rightBarButtonItems?[0] = UIBarButtonItem()
|
||||||
|
self.navigationItem.setRightBarButton(UIBarButtonItem(), animated: false)
|
||||||
|
|
||||||
|
self.navigationController?.toolbar.isHidden = true
|
||||||
|
|
||||||
|
self.toolbars = self.toolbarsInSubviews(forView: self.view)
|
||||||
|
|
||||||
|
for toolbar in self.toolbars {
|
||||||
|
toolbar.isHidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func toolbarsInSubviews(forView view: UIView) -> [UIView] {
|
||||||
|
var toolbars: [UIView] = []
|
||||||
|
for subview in view.subviews {
|
||||||
|
if subview is UIToolbar {
|
||||||
|
toolbars.append(subview)
|
||||||
|
}
|
||||||
|
toolbars.append(contentsOf: toolbarsInSubviews(forView: subview))
|
||||||
|
}
|
||||||
|
return toolbars
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func presentDocumentPreviewController(rootController: UIViewController, theme: PresentationTheme, strings: PresentationStrings, postbox: Postbox, file: TelegramMediaFile) {
|
func presentDocumentPreviewController(rootController: UIViewController, theme: PresentationTheme, strings: PresentationStrings, postbox: Postbox, file: TelegramMediaFile, canShare: Bool) {
|
||||||
if #available(iOSApplicationExtension 9.0, iOS 9.0, *) {
|
if #available(iOSApplicationExtension 9.0, iOS 9.0, *) {
|
||||||
let navigationBar = UINavigationBar.appearance(whenContainedInInstancesOf: [QLPreviewController.self])
|
let navigationBar = UINavigationBar.appearance(whenContainedInInstancesOf: [QLPreviewController.self])
|
||||||
navigationBar.barTintColor = theme.rootController.navigationBar.opaqueBackgroundColor
|
navigationBar.barTintColor = theme.rootController.navigationBar.opaqueBackgroundColor
|
||||||
@ -194,5 +239,5 @@ func presentDocumentPreviewController(rootController: UIViewController, theme: P
|
|||||||
navigationBar.titleTextAttributes = [NSAttributedString.Key.font: Font.semibold(17.0), NSAttributedString.Key.foregroundColor: theme.rootController.navigationBar.primaryTextColor]
|
navigationBar.titleTextAttributes = [NSAttributedString.Key.font: Font.semibold(17.0), NSAttributedString.Key.foregroundColor: theme.rootController.navigationBar.primaryTextColor]
|
||||||
}
|
}
|
||||||
|
|
||||||
rootController.present(CompactDocumentPreviewController(theme: theme, strings: strings, postbox: postbox, file: file), animated: true, completion: nil)
|
rootController.present(CompactDocumentPreviewController(theme: theme, strings: strings, postbox: postbox, file: file, canShare: canShare), animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
|||||||
params.present(controller, nil)
|
params.present(controller, nil)
|
||||||
} else if let rootController = params.navigationController?.view.window?.rootViewController {
|
} else if let rootController = params.navigationController?.view.window?.rootViewController {
|
||||||
let proceed = {
|
let proceed = {
|
||||||
presentDocumentPreviewController(rootController: rootController, theme: presentationData.theme, strings: presentationData.strings, postbox: params.context.account.postbox, file: file)
|
presentDocumentPreviewController(rootController: rootController, theme: presentationData.theme, strings: presentationData.strings, postbox: params.context.account.postbox, file: file, canShare: !params.message.isCopyProtected())
|
||||||
}
|
}
|
||||||
if file.mimeType.contains("image/svg") {
|
if file.mimeType.contains("image/svg") {
|
||||||
let presentationData = params.context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = params.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
@ -393,10 +393,12 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
|
|||||||
|
|
||||||
if strongSelf.displayData != displayData {
|
if strongSelf.displayData != displayData {
|
||||||
strongSelf.displayData = displayData
|
strongSelf.displayData = displayData
|
||||||
|
|
||||||
|
var canShare = true
|
||||||
if let (_, valueOrLoading, _) = value, case let .state(value) = valueOrLoading, let source = value.item.playbackData?.source {
|
if let (_, valueOrLoading, _) = value, case let .state(value) = valueOrLoading, let source = value.item.playbackData?.source {
|
||||||
switch source {
|
switch source {
|
||||||
case let .telegramFile(fileReference):
|
case let .telegramFile(fileReference, isCopyProtected):
|
||||||
|
canShare = !isCopyProtected
|
||||||
strongSelf.currentFileReference = fileReference
|
strongSelf.currentFileReference = fileReference
|
||||||
if let size = fileReference.media.size {
|
if let size = fileReference.media.size {
|
||||||
strongSelf.scrubberNode.bufferingStatus = strongSelf.postbox.mediaBox.resourceRangesStatus(fileReference.media.resource)
|
strongSelf.scrubberNode.bufferingStatus = strongSelf.postbox.mediaBox.resourceRangesStatus(fileReference.media.resource)
|
||||||
@ -411,6 +413,8 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
|
|||||||
strongSelf.scrubberNode.bufferingStatus = nil
|
strongSelf.scrubberNode.bufferingStatus = nil
|
||||||
}
|
}
|
||||||
strongSelf.updateLabels(transition: .immediate)
|
strongSelf.updateLabels(transition: .immediate)
|
||||||
|
|
||||||
|
strongSelf.shareNode.isHidden = !canShare
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ final class MessageMediaPlaylistItem: SharedMediaPlaylistItem {
|
|||||||
var playbackData: SharedMediaPlaybackData? {
|
var playbackData: SharedMediaPlaybackData? {
|
||||||
if let file = extractFileMedia(self.message) {
|
if let file = extractFileMedia(self.message) {
|
||||||
let fileReference = FileMediaReference.message(message: MessageReference(self.message), media: file)
|
let fileReference = FileMediaReference.message(message: MessageReference(self.message), media: file)
|
||||||
let source = SharedMediaPlaybackDataSource.telegramFile(fileReference)
|
let source = SharedMediaPlaybackDataSource.telegramFile(reference: fileReference, isCopyProtected: self.message.isCopyProtected())
|
||||||
for attribute in file.attributes {
|
for attribute in file.attributes {
|
||||||
switch attribute {
|
switch attribute {
|
||||||
case let .Audio(isVoice, _, _, _, _):
|
case let .Audio(isVoice, _, _, _, _):
|
||||||
|
@ -227,13 +227,13 @@ final class SharedMediaPlayer {
|
|||||||
switch playbackData.type {
|
switch playbackData.type {
|
||||||
case .voice, .music:
|
case .voice, .music:
|
||||||
switch playbackData.source {
|
switch playbackData.source {
|
||||||
case let .telegramFile(fileReference):
|
case let .telegramFile(fileReference, _):
|
||||||
strongSelf.playbackItem = .audio(MediaPlayer(audioSessionManager: strongSelf.audioSession, postbox: strongSelf.account.postbox, resourceReference: fileReference.resourceReference(fileReference.media.resource), streamable: playbackData.type == .music ? .conservative : .none, video: false, preferSoftwareDecoding: false, enableSound: true, baseRate: rateValue, fetchAutomatically: true, playAndRecord: controlPlaybackWithProximity))
|
strongSelf.playbackItem = .audio(MediaPlayer(audioSessionManager: strongSelf.audioSession, postbox: strongSelf.account.postbox, resourceReference: fileReference.resourceReference(fileReference.media.resource), streamable: playbackData.type == .music ? .conservative : .none, video: false, preferSoftwareDecoding: false, enableSound: true, baseRate: rateValue, fetchAutomatically: true, playAndRecord: controlPlaybackWithProximity))
|
||||||
}
|
}
|
||||||
case .instantVideo:
|
case .instantVideo:
|
||||||
if let mediaManager = strongSelf.mediaManager, let item = item as? MessageMediaPlaylistItem {
|
if let mediaManager = strongSelf.mediaManager, let item = item as? MessageMediaPlaylistItem {
|
||||||
switch playbackData.source {
|
switch playbackData.source {
|
||||||
case let .telegramFile(fileReference):
|
case let .telegramFile(fileReference, _):
|
||||||
let videoNode = OverlayInstantVideoNode(postbox: strongSelf.account.postbox, audioSession: strongSelf.audioSession, manager: mediaManager.universalVideoManager, content: NativeVideoContent(id: .message(item.message.stableId, fileReference.media.fileId), fileReference: fileReference, enableSound: false, baseRate: rateValue), close: { [weak mediaManager] in
|
let videoNode = OverlayInstantVideoNode(postbox: strongSelf.account.postbox, audioSession: strongSelf.audioSession, manager: mediaManager.universalVideoManager, content: NativeVideoContent(id: .message(item.message.stableId, fileReference.media.fileId), fileReference: fileReference, enableSound: false, baseRate: rateValue), close: { [weak mediaManager] in
|
||||||
mediaManager?.setPlaylist(nil, type: .voice, control: .playback(.pause))
|
mediaManager?.setPlaylist(nil, type: .voice, control: .playback(.pause))
|
||||||
})
|
})
|
||||||
@ -483,7 +483,7 @@ final class SharedMediaPlayer {
|
|||||||
let fetchedCurrentSignal: Signal<Never, NoError>
|
let fetchedCurrentSignal: Signal<Never, NoError>
|
||||||
let fetchedNextSignal: Signal<Never, NoError>
|
let fetchedNextSignal: Signal<Never, NoError>
|
||||||
switch current {
|
switch current {
|
||||||
case let .telegramFile(file):
|
case let .telegramFile(file, _):
|
||||||
fetchedCurrentSignal = self.account.postbox.mediaBox.resourceData(file.media.resource)
|
fetchedCurrentSignal = self.account.postbox.mediaBox.resourceData(file.media.resource)
|
||||||
|> mapToSignal { data -> Signal<Void, NoError> in
|
|> mapToSignal { data -> Signal<Void, NoError> in
|
||||||
if data.complete {
|
if data.complete {
|
||||||
@ -496,7 +496,7 @@ final class SharedMediaPlayer {
|
|||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
}
|
}
|
||||||
switch next {
|
switch next {
|
||||||
case let .telegramFile(file):
|
case let .telegramFile(file, _):
|
||||||
fetchedNextSignal = fetchedMediaResource(mediaBox: self.account.postbox.mediaBox, reference: file.resourceReference(file.media.resource))
|
fetchedNextSignal = fetchedMediaResource(mediaBox: self.account.postbox.mediaBox, reference: file.resourceReference(file.media.resource))
|
||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
|> `catch` { _ -> Signal<Never, NoError> in
|
|> `catch` { _ -> Signal<Never, NoError> in
|
||||||
|
Loading…
x
Reference in New Issue
Block a user