mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
b920e3e2c9
@ -5932,3 +5932,29 @@ Sorry for the inconvenience.";
|
|||||||
|
|
||||||
"Conversation.AudioRateTooltipSpeedUp" = "The audio will now play 2 times faster.";
|
"Conversation.AudioRateTooltipSpeedUp" = "The audio will now play 2 times faster.";
|
||||||
"Conversation.AudioRateTooltipNormal" = "The audio will now play at normal speed.";
|
"Conversation.AudioRateTooltipNormal" = "The audio will now play at normal speed.";
|
||||||
|
|
||||||
|
"ChatImport.Title" = "Import Chat";
|
||||||
|
"ChatImport.SelectionErrorNotAdmin" = "You need to be an admin of the group to import messages into it.";
|
||||||
|
"ChatImport.SelectionErrorGroupGeneric" = "You can't import history into this group.";
|
||||||
|
"ChatImport.SelectionConfirmationGroupWithTitle" = "Are you sure you want to import messages from **%1$@** into **%2$@**?";
|
||||||
|
"ChatImport.SelectionConfirmationGroupWithoutTitle" = "Are you sure you want to import messages into **%@**?";
|
||||||
|
"ChatImport.SelectionConfirmationAlertTitle" = "Import Messages";
|
||||||
|
"ChatImport.SelectionConfirmationAlertImportAction" = "Import";
|
||||||
|
"ChatImport.CreateGroupAlertTitle" = "Create Group and Import Messages";
|
||||||
|
"ChatImport.CreateGroupAlertText" = "Are you sure you want to create group **%@** and import messages from another messaging app?";
|
||||||
|
"ChatImport.CreateGroupAlertImportAction" = "Create and Import";
|
||||||
|
"ChatImport.UserErrorNotMutual" = "You can only import messages into private chats with users who added you in their contact list.";
|
||||||
|
"ChatImport.SelectionConfirmationUserWithTitle" = "Are you sure you want to import messages from **%1$@** into the chat with **%2$@**?";
|
||||||
|
"ChatImport.SelectionConfirmationUserWithoutTitle" = "Are you sure you want to import messages into the chat with **%@**?";
|
||||||
|
|
||||||
|
"PeerSelection.CreateNewGroup" = "Create a New Group";
|
||||||
|
"Message.ImportedDateFormat" = "%1$@, %2$@ Imported %3$@";
|
||||||
|
|
||||||
|
"ChatImportActivity.Title" = "Importing Chat";
|
||||||
|
"ChatImportActivity.OpenApp" = "Open Telegram";
|
||||||
|
"ChatImportActivity.Retry" = "Retry";
|
||||||
|
"ChatImportActivity.InProgress" = "Please keep this window open\nduring the import.";
|
||||||
|
"ChatImportActivity.ErrorNotAdmin" = "You need to be an admin.";
|
||||||
|
"ChatImportActivity.ErrorInvalidChatType" = "You can't import this history in this type of chat.";
|
||||||
|
"ChatImportActivity.ErrorGeneric" = "An error occurred.";
|
||||||
|
"ChatImportActivity.Success" = "This chat has been imported\nsuccessfully.";
|
||||||
|
@ -24,6 +24,7 @@ swift_library(
|
|||||||
"//submodules/MimeTypes:MimeTypes",
|
"//submodules/MimeTypes:MimeTypes",
|
||||||
"//submodules/ConfettiEffect:ConfettiEffect",
|
"//submodules/ConfettiEffect:ConfettiEffect",
|
||||||
"//submodules/TelegramUniversalVideoContent:TelegramUniversalVideoContent",
|
"//submodules/TelegramUniversalVideoContent:TelegramUniversalVideoContent",
|
||||||
|
"//submodules/SolidRoundedButtonNode:SolidRoundedButtonNode",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -15,6 +15,7 @@ import ZIPFoundation
|
|||||||
import MimeTypes
|
import MimeTypes
|
||||||
import ConfettiEffect
|
import ConfettiEffect
|
||||||
import TelegramUniversalVideoContent
|
import TelegramUniversalVideoContent
|
||||||
|
import SolidRoundedButtonNode
|
||||||
|
|
||||||
public final class ChatImportActivityScreen: ViewController {
|
public final class ChatImportActivityScreen: ViewController {
|
||||||
enum ImportError {
|
enum ImportError {
|
||||||
@ -46,6 +47,7 @@ public final class ChatImportActivityScreen: ViewController {
|
|||||||
|
|
||||||
private let statusButtonText: ImmediateTextNode
|
private let statusButtonText: ImmediateTextNode
|
||||||
private let statusButton: HighlightableButtonNode
|
private let statusButton: HighlightableButtonNode
|
||||||
|
private let doneButton: SolidRoundedButtonNode
|
||||||
|
|
||||||
private var validLayout: (ContainerViewLayout, CGFloat)?
|
private var validLayout: (ContainerViewLayout, CGFloat)?
|
||||||
|
|
||||||
@ -100,6 +102,8 @@ public final class ChatImportActivityScreen: ViewController {
|
|||||||
|
|
||||||
self.statusButton = HighlightableButtonNode()
|
self.statusButton = HighlightableButtonNode()
|
||||||
|
|
||||||
|
self.doneButton = SolidRoundedButtonNode(title: self.presentationData.strings.ChatImportActivity_OpenApp, theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: self.presentationData.theme.list.itemCheckColors.foregroundColor), height: 50.0, cornerRadius: 10.0, gloss: false)
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||||
@ -129,6 +133,7 @@ public final class ChatImportActivityScreen: ViewController {
|
|||||||
self.addSubnode(self.statusText)
|
self.addSubnode(self.statusText)
|
||||||
self.addSubnode(self.statusButtonText)
|
self.addSubnode(self.statusButtonText)
|
||||||
self.addSubnode(self.statusButton)
|
self.addSubnode(self.statusButton)
|
||||||
|
self.addSubnode(self.doneButton)
|
||||||
|
|
||||||
self.statusButton.addTarget(self, action: #selector(self.statusButtonPressed), forControlEvents: .touchUpInside)
|
self.statusButton.addTarget(self, action: #selector(self.statusButtonPressed), forControlEvents: .touchUpInside)
|
||||||
self.statusButton.highligthedChanged = { [weak self] highlighted in
|
self.statusButton.highligthedChanged = { [weak self] highlighted in
|
||||||
@ -167,6 +172,18 @@ public final class ChatImportActivityScreen: ViewController {
|
|||||||
self.addSubnode(videoNode)
|
self.addSubnode(videoNode)
|
||||||
videoNode.canAttachContent = true
|
videoNode.canAttachContent = true
|
||||||
videoNode.play()
|
videoNode.play()
|
||||||
|
|
||||||
|
self.doneButton.pressed = { [weak self] in
|
||||||
|
guard let strongSelf = self, let controller = strongSelf.controller else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let application = UIApplication.value(forKeyPath: #keyPath(UIApplication.shared)) as? UIApplication {
|
||||||
|
let selector = NSSelectorFromString("openURL:")
|
||||||
|
let url = URL(string: "tg://localpeer?id=\(controller.peerId.toInt64())")!
|
||||||
|
application.perform(selector, with: url)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,8 +200,6 @@ public final class ChatImportActivityScreen: ViewController {
|
|||||||
let isFirstLayout = self.validLayout == nil
|
let isFirstLayout = self.validLayout == nil
|
||||||
self.validLayout = (layout, navigationHeight)
|
self.validLayout = (layout, navigationHeight)
|
||||||
|
|
||||||
//TODO:localize
|
|
||||||
|
|
||||||
let iconSize = CGSize(width: 170.0, height: 170.0)
|
let iconSize = CGSize(width: 170.0, height: 170.0)
|
||||||
let radialStatusSize = CGSize(width: 186.0, height: 186.0)
|
let radialStatusSize = CGSize(width: 186.0, height: 186.0)
|
||||||
let maxIconStatusSpacing: CGFloat = 62.0
|
let maxIconStatusSpacing: CGFloat = 62.0
|
||||||
@ -210,28 +225,28 @@ public final class ChatImportActivityScreen: ViewController {
|
|||||||
|
|
||||||
switch self.state {
|
switch self.state {
|
||||||
case .progress, .done:
|
case .progress, .done:
|
||||||
self.statusButtonText.attributedText = NSAttributedString(string: "Done", font: Font.semibold(17.0), textColor: self.presentationData.theme.list.itemAccentColor)
|
self.statusButtonText.attributedText = NSAttributedString(string: self.presentationData.strings.Common_Done, font: Font.semibold(17.0), textColor: self.presentationData.theme.list.itemAccentColor)
|
||||||
case .error:
|
case .error:
|
||||||
self.statusButtonText.attributedText = NSAttributedString(string: "Retry", font: Font.semibold(17.0), textColor: self.presentationData.theme.list.itemAccentColor)
|
self.statusButtonText.attributedText = NSAttributedString(string: self.presentationData.strings.ChatImportActivity_Retry, font: Font.semibold(17.0), textColor: self.presentationData.theme.list.itemAccentColor)
|
||||||
}
|
}
|
||||||
let statusButtonTextSize = self.statusButtonText.updateLayout(CGSize(width: layout.size.width - 16.0 * 2.0, height: .greatestFiniteMagnitude))
|
let statusButtonTextSize = self.statusButtonText.updateLayout(CGSize(width: layout.size.width - 16.0 * 2.0, height: .greatestFiniteMagnitude))
|
||||||
|
|
||||||
switch self.state {
|
switch self.state {
|
||||||
case .progress:
|
case .progress:
|
||||||
self.statusText.attributedText = NSAttributedString(string: "Please keep this window open\nduring the import.", font: Font.regular(17.0), textColor: self.presentationData.theme.list.itemSecondaryTextColor)
|
self.statusText.attributedText = NSAttributedString(string: self.presentationData.strings.ChatImportActivity_InProgress, font: Font.regular(17.0), textColor: self.presentationData.theme.list.itemSecondaryTextColor)
|
||||||
case let .error(error):
|
case let .error(error):
|
||||||
let errorText: String
|
let errorText: String
|
||||||
switch error {
|
switch error {
|
||||||
case .chatAdminRequired:
|
case .chatAdminRequired:
|
||||||
errorText = "You need to be an admin."
|
errorText = self.presentationData.strings.ChatImportActivity_ErrorNotAdmin
|
||||||
case .invalidChatType:
|
case .invalidChatType:
|
||||||
errorText = "You can't import this history in this type of chat."
|
errorText = self.presentationData.strings.ChatImportActivity_ErrorGeneric
|
||||||
case .generic:
|
case .generic:
|
||||||
errorText = "An error occurred."
|
errorText = self.presentationData.strings.ChatImportActivity_ErrorInvalidChatType
|
||||||
}
|
}
|
||||||
self.statusText.attributedText = NSAttributedString(string: errorText, font: Font.regular(17.0), textColor: self.presentationData.theme.list.itemDestructiveColor)
|
self.statusText.attributedText = NSAttributedString(string: errorText, font: Font.regular(17.0), textColor: self.presentationData.theme.list.itemDestructiveColor)
|
||||||
case .done:
|
case .done:
|
||||||
self.statusText.attributedText = NSAttributedString(string: "This chat has been imported\nsuccessfully.", font: Font.semibold(17.0), textColor: self.presentationData.theme.list.itemPrimaryTextColor)
|
self.statusText.attributedText = NSAttributedString(string: self.presentationData.strings.ChatImportActivity_Success, font: Font.semibold(17.0), textColor: self.presentationData.theme.list.itemPrimaryTextColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
let statusTextSize = self.statusText.updateLayout(CGSize(width: layout.size.width - 16.0 * 2.0, height: .greatestFiniteMagnitude))
|
let statusTextSize = self.statusText.updateLayout(CGSize(width: layout.size.width - 16.0 * 2.0, height: .greatestFiniteMagnitude))
|
||||||
@ -240,7 +255,7 @@ public final class ChatImportActivityScreen: ViewController {
|
|||||||
var hideIcon = false
|
var hideIcon = false
|
||||||
if case .compact = layout.metrics.heightClass, layout.size.width > layout.size.height {
|
if case .compact = layout.metrics.heightClass, layout.size.width > layout.size.height {
|
||||||
hideIcon = true
|
hideIcon = true
|
||||||
contentHeight = radialStatusSize.height + maxProgressTextSpacing + progressTextSize.height + progressStatusSpacing + 100.0
|
contentHeight = radialStatusSize.height + maxProgressTextSpacing + progressTextSize.height + progressStatusSpacing + 140.0
|
||||||
} else {
|
} else {
|
||||||
contentHeight = iconSize.height + maxIconStatusSpacing + radialStatusSize.height + maxProgressTextSpacing + progressTextSize.height + progressStatusSpacing + 100.0
|
contentHeight = iconSize.height + maxIconStatusSpacing + radialStatusSize.height + maxProgressTextSpacing + progressTextSize.height + progressStatusSpacing + 100.0
|
||||||
}
|
}
|
||||||
@ -268,14 +283,30 @@ public final class ChatImportActivityScreen: ViewController {
|
|||||||
self.statusText.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - statusTextSize.width) / 2.0), y: self.progressText.frame.maxY + progressStatusSpacing), size: statusTextSize)
|
self.statusText.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - statusTextSize.width) / 2.0), y: self.progressText.frame.maxY + progressStatusSpacing), size: statusTextSize)
|
||||||
self.statusButtonText.isHidden = true
|
self.statusButtonText.isHidden = true
|
||||||
self.statusButton.isHidden = true
|
self.statusButton.isHidden = true
|
||||||
|
self.doneButton.isHidden = true
|
||||||
self.progressText.isHidden = false
|
self.progressText.isHidden = false
|
||||||
} else {
|
} else if case .error = self.state {
|
||||||
self.statusText.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - statusTextSize.width) / 2.0), y: self.progressText.frame.minY), size: statusTextSize)
|
self.statusText.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - statusTextSize.width) / 2.0), y: self.progressText.frame.minY), size: statusTextSize)
|
||||||
self.statusButtonText.isHidden = false
|
self.statusButtonText.isHidden = false
|
||||||
self.statusButton.isHidden = false
|
self.statusButton.isHidden = false
|
||||||
|
self.doneButton.isHidden = true
|
||||||
|
self.progressText.isHidden = true
|
||||||
|
} else {
|
||||||
|
self.statusText.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - statusTextSize.width) / 2.0), y: self.progressText.frame.minY), size: statusTextSize)
|
||||||
|
self.statusButtonText.isHidden = true
|
||||||
|
self.statusButton.isHidden = true
|
||||||
|
self.doneButton.isHidden = false
|
||||||
self.progressText.isHidden = true
|
self.progressText.isHidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let buttonSideInset: CGFloat = 40.0
|
||||||
|
let buttonWidth = min(layout.size.width - buttonSideInset * 2.0, horizontalContainerFillingSizeForLayout(layout: layout, sideInset: buttonSideInset))
|
||||||
|
|
||||||
|
let buttonHeight = self.doneButton.updateLayout(width: buttonWidth, transition: .immediate)
|
||||||
|
|
||||||
|
let doneButtonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonWidth) / 2.0), y: self.statusText.frame.maxY + statusButtonSpacing + 10.0), size: CGSize(width: buttonWidth, height: buttonHeight))
|
||||||
|
self.doneButton.frame = doneButtonFrame
|
||||||
|
|
||||||
let statusButtonTextFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - statusButtonTextSize.width) / 2.0), y: self.statusText.frame.maxY + statusButtonSpacing), size: statusButtonTextSize)
|
let statusButtonTextFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - statusButtonTextSize.width) / 2.0), y: self.statusText.frame.maxY + statusButtonSpacing), size: statusButtonTextSize)
|
||||||
self.statusButtonText.frame = statusButtonTextFrame
|
self.statusButtonText.frame = statusButtonTextFrame
|
||||||
self.statusButton.frame = statusButtonTextFrame.insetBy(dx: -10.0, dy: -10.0)
|
self.statusButton.frame = statusButtonTextFrame.insetBy(dx: -10.0, dy: -10.0)
|
||||||
@ -351,7 +382,7 @@ public final class ChatImportActivityScreen: ViewController {
|
|||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private var presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
fileprivate let cancel: () -> Void
|
fileprivate let cancel: () -> Void
|
||||||
private var peerId: PeerId
|
fileprivate var peerId: PeerId
|
||||||
private let archive: Archive
|
private let archive: Archive
|
||||||
private let mainEntry: TempBoxFile
|
private let mainEntry: TempBoxFile
|
||||||
private let mainEntrySize: Int
|
private let mainEntrySize: Int
|
||||||
@ -397,8 +428,7 @@ public final class ChatImportActivityScreen: ViewController {
|
|||||||
|
|
||||||
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData, hideBackground: true, hideBadge: true))
|
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData, hideBackground: true, hideBadge: true))
|
||||||
|
|
||||||
//TODO:localize
|
self.title = self.presentationData.strings.ChatImportActivity_Title
|
||||||
self.title = "Importing Chat"
|
|
||||||
|
|
||||||
self.navigationItem.setLeftBarButton(UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false)
|
self.navigationItem.setLeftBarButton(UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false)
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH
|
|||||||
offsetId = start.id == Int32.max ? start.id : (start.id + 1)
|
offsetId = start.id == Int32.max ? start.id : (start.id + 1)
|
||||||
addOffset = 0
|
addOffset = 0
|
||||||
maxId = start.id == Int32.max ? start.id : (start.id + 1)
|
maxId = start.id == Int32.max ? start.id : (start.id + 1)
|
||||||
minId = end.id
|
minId = end.id == 1 ? 0 : end.id
|
||||||
|
|
||||||
let rangeStartId = end.id
|
let rangeStartId = end.id
|
||||||
let rangeEndId = min(start.id, Int32.max - 1)
|
let rangeEndId = min(start.id, Int32.max - 1)
|
||||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -2968,6 +2968,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
|||||||
|
|
||||||
if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty {
|
if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty {
|
||||||
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame)
|
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame)
|
||||||
|
} else if let forwardInfo = item.content.firstMessage.forwardInfo, forwardInfo.flags.contains(.isImported), forwardInfo.author == nil {
|
||||||
|
item.controllerInteraction.displayImportedMessageTooltip(avatarNode)
|
||||||
} else {
|
} else {
|
||||||
if item.message.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId), let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil {
|
if item.message.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId), let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil {
|
||||||
if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) {
|
if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) {
|
||||||
|
@ -90,8 +90,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||||||
var chatListcategories: [ChatListNodeAdditionalCategory] = []
|
var chatListcategories: [ChatListNodeAdditionalCategory] = []
|
||||||
|
|
||||||
if let _ = createNewGroup {
|
if let _ = createNewGroup {
|
||||||
//TODO:localize
|
chatListcategories.append(ChatListNodeAdditionalCategory(id: 0, icon: PresentationResourcesItemList.createGroupIcon(self.presentationData.theme), title: self.presentationData.strings.PeerSelection_CreateNewGroup, appearance: .action))
|
||||||
chatListcategories.append(ChatListNodeAdditionalCategory(id: 0, icon: PresentationResourcesItemList.createGroupIcon(self.presentationData.theme), title: "Create a New Group", appearance: .action))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.chatListNode = ChatListNode(context: context, groupId: .root, previewing: false, fillPreloadItems: false, mode: .peers(filter: filter, isSelecting: false, additionalCategories: chatListcategories, chatListFilters: nil), theme: self.presentationData.theme, fontSize: presentationData.listsFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: presentationData.disableAnimations)
|
self.chatListNode = ChatListNode(context: context, groupId: .root, previewing: false, fillPreloadItems: false, mode: .peers(filter: filter, isSelecting: false, additionalCategories: chatListcategories, chatListFilters: nil), theme: self.presentationData.theme, fontSize: presentationData.listsFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: presentationData.disableAnimations)
|
||||||
|
@ -387,12 +387,6 @@ public class ShareRootControllerImpl {
|
|||||||
context.account.resetStateManagement()
|
context.account.resetStateManagement()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if let application = UIApplication.value(forKeyPath: #keyPath(UIApplication.shared)) as? UIApplication {
|
|
||||||
let selector = NSSelectorFromString("openURL:")
|
|
||||||
let url = URL(string: "tg://open")!
|
|
||||||
application.perform(selector, with: url)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if let strongSelf = self, let inputItems = strongSelf.getExtensionContext()?.inputItems, inputItems.count == 1, let item = inputItems[0] as? NSExtensionItem, let attachments = item.attachments {
|
if let strongSelf = self, let inputItems = strongSelf.getExtensionContext()?.inputItems, inputItems.count == 1, let item = inputItems[0] as? NSExtensionItem, let attachments = item.attachments {
|
||||||
for attachment in attachments {
|
for attachment in attachments {
|
||||||
if attachment.hasItemConformingToTypeIdentifier(kUTTypeFileURL as String) {
|
if attachment.hasItemConformingToTypeIdentifier(kUTTypeFileURL as String) {
|
||||||
@ -505,8 +499,7 @@ public class ShareRootControllerImpl {
|
|||||||
|
|
||||||
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: presentationData))
|
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: presentationData))
|
||||||
|
|
||||||
//TODO:localize
|
self.title = presentationData.strings.ChatImport_Title
|
||||||
self.title = "Import Chat"
|
|
||||||
self.navigationItem.setLeftBarButton(UIBarButtonItem(title: presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false)
|
self.navigationItem.setLeftBarButton(UIBarButtonItem(title: presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,10 +535,9 @@ public class ShareRootControllerImpl {
|
|||||||
|> deliverOnMainQueue).start(next: { parseInfo in
|
|> deliverOnMainQueue).start(next: { parseInfo in
|
||||||
switch parseInfo {
|
switch parseInfo {
|
||||||
case let .group(groupTitle):
|
case let .group(groupTitle):
|
||||||
//TODO:localize
|
|
||||||
var attemptSelectionImpl: ((Peer) -> Void)?
|
var attemptSelectionImpl: ((Peer) -> Void)?
|
||||||
var createNewGroupImpl: (() -> Void)?
|
var createNewGroupImpl: (() -> Void)?
|
||||||
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyGroups, .onlyManageable, .excludeDisabled, .doNotSearchMessages], hasContactSelector: false, hasGlobalSearch: false, title: "Import Chat", attemptSelection: { peer in
|
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyGroups, .onlyManageable, .excludeDisabled, .doNotSearchMessages], hasContactSelector: false, hasGlobalSearch: false, title: presentationData.strings.ChatImport_Title, attemptSelection: { peer in
|
||||||
attemptSelectionImpl?(peer)
|
attemptSelectionImpl?(peer)
|
||||||
}, createNewGroup: {
|
}, createNewGroup: {
|
||||||
createNewGroupImpl?()
|
createNewGroupImpl?()
|
||||||
@ -573,17 +565,17 @@ public class ShareRootControllerImpl {
|
|||||||
if let channel = peer as? TelegramChannel {
|
if let channel = peer as? TelegramChannel {
|
||||||
if channel.hasPermission(.changeInfo), (channel.flags.contains(.isCreator) || channel.adminRights != nil) {
|
if channel.hasPermission(.changeInfo), (channel.flags.contains(.isCreator) || channel.adminRights != nil) {
|
||||||
} else {
|
} else {
|
||||||
errorText = "You need to be an admin of the group to import messages into it."
|
errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
|
||||||
}
|
}
|
||||||
} else if let group = peer as? TelegramGroup {
|
} else if let group = peer as? TelegramGroup {
|
||||||
switch group.role {
|
switch group.role {
|
||||||
case .creator:
|
case .creator:
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
errorText = "You need to be an admin of the group to import messages into it."
|
errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errorText = "You can't import history into this group."
|
errorText = presentationData.strings.ChatImport_SelectionErrorGroupGeneric
|
||||||
}
|
}
|
||||||
|
|
||||||
if let errorText = errorText {
|
if let errorText = errorText {
|
||||||
@ -595,12 +587,12 @@ public class ShareRootControllerImpl {
|
|||||||
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
|
||||||
let text: String
|
let text: String
|
||||||
if let groupTitle = groupTitle {
|
if let groupTitle = groupTitle {
|
||||||
text = "Are you sure you want to import messages from **\(groupTitle)** into **\(peer.debugDisplayTitle)**?"
|
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithTitle(groupTitle, peer.debugDisplayTitle).0
|
||||||
} else {
|
} else {
|
||||||
text = "Are you sure you want to import messages into **\(peer.debugDisplayTitle)**?"
|
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithoutTitle(peer.debugDisplayTitle).0
|
||||||
}
|
}
|
||||||
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: "Import Messages", text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
}), TextAlertAction(type: .defaultAction, title: "Import", action: {
|
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
|
||||||
beginWithPeer(peer.id)
|
beginWithPeer(peer.id)
|
||||||
})], parseMarkdown: true)
|
})], parseMarkdown: true)
|
||||||
strongSelf.mainWindow?.present(controller, on: .root)
|
strongSelf.mainWindow?.present(controller, on: .root)
|
||||||
@ -615,7 +607,7 @@ public class ShareRootControllerImpl {
|
|||||||
} else {
|
} else {
|
||||||
resolvedGroupTitle = "Group"
|
resolvedGroupTitle = "Group"
|
||||||
}
|
}
|
||||||
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: "Create Group and Import Messages", text: "Are you sure you want to create group **\(resolvedGroupTitle)** and import messages from another messaging app?", actions: [TextAlertAction(type: .defaultAction, title: "Create and Import", action: {
|
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_CreateGroupAlertTitle, text: presentationData.strings.ChatImport_CreateGroupAlertText(resolvedGroupTitle).0, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_CreateGroupAlertImportAction, action: {
|
||||||
var signal: Signal<PeerId?, NoError> = createSupergroup(account: context.account, title: resolvedGroupTitle, description: nil, isForHistoryImport: true)
|
var signal: Signal<PeerId?, NoError> = createSupergroup(account: context.account, title: resolvedGroupTitle, description: nil, isForHistoryImport: true)
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { _ -> Signal<PeerId?, NoError> in
|
|> `catch` { _ -> Signal<PeerId?, NoError> in
|
||||||
@ -649,7 +641,6 @@ public class ShareRootControllerImpl {
|
|||||||
if let peerId = peerId {
|
if let peerId = peerId {
|
||||||
beginWithPeer(peerId)
|
beginWithPeer(peerId)
|
||||||
} else {
|
} else {
|
||||||
//TODO:localize
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
@ -661,9 +652,8 @@ public class ShareRootControllerImpl {
|
|||||||
case let .privateChat(title):
|
case let .privateChat(title):
|
||||||
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
//TODO:localize
|
|
||||||
var attemptSelectionImpl: ((Peer) -> Void)?
|
var attemptSelectionImpl: ((Peer) -> Void)?
|
||||||
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyPrivateChats, .excludeDisabled, .doNotSearchMessages], hasChatListSelector: false, hasContactSelector: true, hasGlobalSearch: false, title: "Import Chat", attemptSelection: { peer in
|
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyPrivateChats, .excludeDisabled, .doNotSearchMessages], hasChatListSelector: false, hasContactSelector: true, hasGlobalSearch: false, title: presentationData.strings.ChatImport_Title, attemptSelection: { peer in
|
||||||
attemptSelectionImpl?(peer)
|
attemptSelectionImpl?(peer)
|
||||||
}, pretendPresentedInModal: true))
|
}, pretendPresentedInModal: true))
|
||||||
|
|
||||||
@ -696,7 +686,7 @@ public class ShareRootControllerImpl {
|
|||||||
case .generic:
|
case .generic:
|
||||||
errorText = presentationData.strings.Login_UnknownError
|
errorText = presentationData.strings.Login_UnknownError
|
||||||
case .userIsNotMutualContact:
|
case .userIsNotMutualContact:
|
||||||
errorText = "You can only import messages into private chats with users who added you in their contact list."
|
errorText = presentationData.strings.ChatImport_UserErrorNotMutual
|
||||||
}
|
}
|
||||||
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
|
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
|
||||||
})])
|
})])
|
||||||
@ -707,12 +697,12 @@ public class ShareRootControllerImpl {
|
|||||||
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
|
||||||
let text: String
|
let text: String
|
||||||
if let title = title {
|
if let title = title {
|
||||||
text = "Are you sure you want to import messages from **\(title)** into the chat with **\(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))**?"
|
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithTitle(title, peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0
|
||||||
} else {
|
} else {
|
||||||
text = "Are you sure you want to import messages into the chat with **\(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))**?"
|
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithoutTitle(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0
|
||||||
}
|
}
|
||||||
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: "Import Messages", text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
}), TextAlertAction(type: .defaultAction, title: "Import", action: {
|
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
|
||||||
beginWithPeer(peer.id)
|
beginWithPeer(peer.id)
|
||||||
})], parseMarkdown: true)
|
})], parseMarkdown: true)
|
||||||
strongSelf.mainWindow?.present(controller, on: .root)
|
strongSelf.mainWindow?.present(controller, on: .root)
|
||||||
@ -721,10 +711,9 @@ public class ShareRootControllerImpl {
|
|||||||
|
|
||||||
navigationController.viewControllers = [controller]
|
navigationController.viewControllers = [controller]
|
||||||
case let .unknown(peerTitle):
|
case let .unknown(peerTitle):
|
||||||
//TODO:localize
|
|
||||||
var attemptSelectionImpl: ((Peer) -> Void)?
|
var attemptSelectionImpl: ((Peer) -> Void)?
|
||||||
var createNewGroupImpl: (() -> Void)?
|
var createNewGroupImpl: (() -> Void)?
|
||||||
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.excludeDisabled, .doNotSearchMessages], hasContactSelector: true, hasGlobalSearch: false, title: "Import Chat", attemptSelection: { peer in
|
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.excludeDisabled, .doNotSearchMessages], hasContactSelector: true, hasGlobalSearch: false, title: presentationData.strings.ChatImport_Title, attemptSelection: { peer in
|
||||||
attemptSelectionImpl?(peer)
|
attemptSelectionImpl?(peer)
|
||||||
}, createNewGroup: {
|
}, createNewGroup: {
|
||||||
createNewGroupImpl?()
|
createNewGroupImpl?()
|
||||||
@ -759,7 +748,7 @@ public class ShareRootControllerImpl {
|
|||||||
case .generic:
|
case .generic:
|
||||||
errorText = presentationData.strings.Login_UnknownError
|
errorText = presentationData.strings.Login_UnknownError
|
||||||
case .userIsNotMutualContact:
|
case .userIsNotMutualContact:
|
||||||
errorText = "You can only import messages into private chats with users who added you in their contact list."
|
errorText = presentationData.strings.ChatImport_UserErrorNotMutual
|
||||||
}
|
}
|
||||||
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
|
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
|
||||||
})])
|
})])
|
||||||
@ -773,18 +762,18 @@ public class ShareRootControllerImpl {
|
|||||||
if let channel = peer as? TelegramChannel {
|
if let channel = peer as? TelegramChannel {
|
||||||
if channel.hasPermission(.changeInfo), (channel.flags.contains(.isCreator) || channel.adminRights != nil) {
|
if channel.hasPermission(.changeInfo), (channel.flags.contains(.isCreator) || channel.adminRights != nil) {
|
||||||
} else {
|
} else {
|
||||||
errorText = "You need to be an admin of the group to import messages into it."
|
errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
|
||||||
}
|
}
|
||||||
} else if let group = peer as? TelegramGroup {
|
} else if let group = peer as? TelegramGroup {
|
||||||
switch group.role {
|
switch group.role {
|
||||||
case .creator:
|
case .creator:
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
errorText = "You need to be an admin of the group to import messages into it."
|
errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
|
||||||
}
|
}
|
||||||
} else if let _ = peer as? TelegramUser {
|
} else if let _ = peer as? TelegramUser {
|
||||||
} else {
|
} else {
|
||||||
errorText = "You can't import history into this group."
|
errorText = presentationData.strings.ChatImport_SelectionErrorGroupGeneric
|
||||||
}
|
}
|
||||||
|
|
||||||
if let errorText = errorText {
|
if let errorText = errorText {
|
||||||
@ -797,24 +786,24 @@ public class ShareRootControllerImpl {
|
|||||||
if let user = peer as? TelegramUser {
|
if let user = peer as? TelegramUser {
|
||||||
let text: String
|
let text: String
|
||||||
if let title = peerTitle {
|
if let title = peerTitle {
|
||||||
text = "Are you sure you want to import messages from **\(title)** into the chat with **\(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))**?"
|
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithTitle(title, peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0
|
||||||
} else {
|
} else {
|
||||||
text = "Are you sure you want to import messages into the chat with **\(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))**?"
|
text = presentationData.strings.ChatImport_SelectionConfirmationUserWithoutTitle(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).0
|
||||||
}
|
}
|
||||||
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: "Import Messages", text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
}), TextAlertAction(type: .defaultAction, title: "Import", action: {
|
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
|
||||||
beginWithPeer(peer.id)
|
beginWithPeer(peer.id)
|
||||||
})], parseMarkdown: true)
|
})], parseMarkdown: true)
|
||||||
strongSelf.mainWindow?.present(controller, on: .root)
|
strongSelf.mainWindow?.present(controller, on: .root)
|
||||||
} else {
|
} else {
|
||||||
let text: String
|
let text: String
|
||||||
if let groupTitle = peerTitle {
|
if let groupTitle = peerTitle {
|
||||||
text = "Are you sure you want to import messages from **\(groupTitle)** into **\(peer.debugDisplayTitle)**?"
|
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithTitle(groupTitle, peer.debugDisplayTitle).0
|
||||||
} else {
|
} else {
|
||||||
text = "Are you sure you want to import messages into **\(peer.debugDisplayTitle)**?"
|
text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithoutTitle(peer.debugDisplayTitle).0
|
||||||
}
|
}
|
||||||
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: "Import Messages", text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
}), TextAlertAction(type: .defaultAction, title: "Import", action: {
|
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
|
||||||
beginWithPeer(peer.id)
|
beginWithPeer(peer.id)
|
||||||
})], parseMarkdown: true)
|
})], parseMarkdown: true)
|
||||||
strongSelf.mainWindow?.present(controller, on: .root)
|
strongSelf.mainWindow?.present(controller, on: .root)
|
||||||
@ -831,7 +820,7 @@ public class ShareRootControllerImpl {
|
|||||||
} else {
|
} else {
|
||||||
resolvedGroupTitle = "Group"
|
resolvedGroupTitle = "Group"
|
||||||
}
|
}
|
||||||
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: "Create Group and Import Messages", text: "Are you sure you want to create group **\(resolvedGroupTitle)** and import messages from another messaging app?", actions: [TextAlertAction(type: .defaultAction, title: "Create and Import", action: {
|
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_CreateGroupAlertTitle, text: presentationData.strings.ChatImport_CreateGroupAlertText(resolvedGroupTitle).0, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_CreateGroupAlertImportAction, action: {
|
||||||
var signal: Signal<PeerId?, NoError> = createSupergroup(account: context.account, title: resolvedGroupTitle, description: nil, isForHistoryImport: true)
|
var signal: Signal<PeerId?, NoError> = createSupergroup(account: context.account, title: resolvedGroupTitle, description: nil, isForHistoryImport: true)
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { _ -> Signal<PeerId?, NoError> in
|
|> `catch` { _ -> Signal<PeerId?, NoError> in
|
||||||
@ -865,7 +854,6 @@ public class ShareRootControllerImpl {
|
|||||||
if let peerId = peerId {
|
if let peerId = peerId {
|
||||||
beginWithPeer(peerId)
|
beginWithPeer(peerId)
|
||||||
} else {
|
} else {
|
||||||
//TODO:localize
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
|
@ -42,9 +42,7 @@ func stringForMessageTimestampStatus(accountPeerId: PeerId, message: Message, da
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let forwardInfo = message.forwardInfo, forwardInfo.flags.contains(.isImported) {
|
if let forwardInfo = message.forwardInfo, forwardInfo.flags.contains(.isImported) {
|
||||||
//TODO:localize
|
dateText = strings.Message_ImportedDateFormat(dateStringForDay(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: forwardInfo.date), stringForMessageTimestamp(timestamp: forwardInfo.date, dateTimeFormat: dateTimeFormat), dateText).0
|
||||||
|
|
||||||
dateText = dateStringForDay(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: forwardInfo.date) + ", " + stringForMessageTimestamp(timestamp: forwardInfo.date, dateTimeFormat: dateTimeFormat) + " Imported " + dateText
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var authorTitle: String?
|
var authorTitle: String?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user