mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
aca9fbcae8
commit
13014b2964
@ -8002,6 +8002,8 @@ Sorry for the inconvenience.";
|
||||
"PrivacySettings.LoginEmail" = "Login Email";
|
||||
"PrivacySettings.LoginEmailInfo" = "Change your email address for Telegram login codes.";
|
||||
"Login.EmailChanged" = "Your email has been changed.";
|
||||
"PrivacySettings.LoginEmailAlertText" = "This email address will be used every time you login to your Telegram account from a new device.";
|
||||
"PrivacySettings.LoginEmailAlertChange" = "Change Email";
|
||||
|
||||
"Login.InvalidEmailAddressError" = "An error occurred. Please try again.";
|
||||
"Login.InvalidEmailError" = "Please enter a valid e-mail address.";
|
||||
|
@ -153,6 +153,7 @@ public struct ChatAvailableMessageActionOptions: OptionSet {
|
||||
public static let unsendPersonal = ChatAvailableMessageActionOptions(rawValue: 1 << 7)
|
||||
public static let sendScheduledNow = ChatAvailableMessageActionOptions(rawValue: 1 << 8)
|
||||
public static let editScheduledTime = ChatAvailableMessageActionOptions(rawValue: 1 << 9)
|
||||
public static let externalShare = ChatAvailableMessageActionOptions(rawValue: 1 << 10)
|
||||
}
|
||||
|
||||
public struct ChatAvailableMessageActions {
|
||||
|
@ -245,6 +245,9 @@ public final class ContextActionNode: ASDisplayNode, ContextActionNodeProtocol {
|
||||
if !iconSize.width.isZero {
|
||||
rightTextInset = max(iconSize.width, standardIconWidth) + iconSideInset + sideInset
|
||||
}
|
||||
if let iconSize = self.titleIconNode.image?.size {
|
||||
rightTextInset += iconSize.width + 10.0
|
||||
}
|
||||
|
||||
let badgeTextSize = self.badgeTextNode.updateLayout(CGSize(width: constrainedWidth, height: .greatestFiniteMagnitude))
|
||||
let badgeInset: CGFloat = 4.0
|
||||
|
@ -692,6 +692,8 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
hasCaption = true
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
hasCaption = file.mimeType.hasPrefix("image/")
|
||||
} else if media is TelegramMediaInvoice {
|
||||
hasCaption = true
|
||||
}
|
||||
}
|
||||
if hasCaption {
|
||||
@ -1305,7 +1307,16 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
}
|
||||
}
|
||||
}
|
||||
let shareController = ShareController(context: strongSelf.context, subject: subject, preferredAction: preferredAction, forceTheme: forceTheme)
|
||||
|
||||
var hasExternalShare = true
|
||||
for media in currentMessage.media {
|
||||
if let invoice = media as? TelegramMediaInvoice, let _ = invoice.extendedMedia {
|
||||
hasExternalShare = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
let shareController = ShareController(context: strongSelf.context, subject: subject, preferredAction: preferredAction, externalShare: hasExternalShare, forceTheme: forceTheme)
|
||||
shareController.dismissed = { [weak self] _ in
|
||||
self?.interacting?(false)
|
||||
}
|
||||
|
@ -148,6 +148,41 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
}
|
||||
}
|
||||
shareController.completed = { [weak self] peerIds in
|
||||
let _ = (context.engine.data.get(
|
||||
EngineDataList(
|
||||
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
|
||||
)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerList in
|
||||
if let strongSelf = self {
|
||||
let peers = peerList.compactMap { $0 }
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
let text: String
|
||||
var savedMessages = false
|
||||
if peerIds.count == 1, let peerId = peerIds.first, peerId == strongSelf.context.account.peerId {
|
||||
text = presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One
|
||||
savedMessages = true
|
||||
} else {
|
||||
if peers.count == 1, let peer = peers.first {
|
||||
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
text = presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string
|
||||
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
|
||||
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
text = presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
|
||||
} else if let peer = peers.first {
|
||||
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
text = presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
|
||||
} else {
|
||||
text = ""
|
||||
}
|
||||
}
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
strongSelf.present(shareController, nil)
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +294,10 @@ open class ManagedAnimationNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
public func trackTo(item: ManagedAnimationItem) {
|
||||
public func trackTo(item: ManagedAnimationItem, immediately: Bool = false) {
|
||||
if immediately {
|
||||
self.trackStack.removeAll()
|
||||
}
|
||||
self.trackStack.append(item)
|
||||
self.didTryAdvancingState = false
|
||||
self.updateAnimation()
|
||||
|
@ -565,7 +565,7 @@ class PrivacyAndSecurityControllerImpl: ItemListController, ASAuthorizationContr
|
||||
}
|
||||
}
|
||||
|
||||
public func privacyAndSecurityController(context: AccountContext, initialSettings: AccountPrivacySettings? = nil, updatedSettings: ((AccountPrivacySettings?) -> Void)? = nil, updatedBlockedPeers: ((BlockedPeersContext?) -> Void)? = nil, updatedHasTwoStepAuth: ((Bool) -> Void)? = nil, focusOnItemTag: PrivacyAndSecurityEntryTag? = nil, activeSessionsContext: ActiveSessionsContext? = nil, webSessionsContext: WebSessionsContext? = nil, blockedPeersContext: BlockedPeersContext? = nil, hasTwoStepAuth: Bool? = nil, loginEmailPattern: Signal<String?, NoError>? = nil) -> ViewController {
|
||||
public func privacyAndSecurityController(context: AccountContext, initialSettings: AccountPrivacySettings? = nil, updatedSettings: ((AccountPrivacySettings?) -> Void)? = nil, updatedBlockedPeers: ((BlockedPeersContext?) -> Void)? = nil, updatedHasTwoStepAuth: ((Bool) -> Void)? = nil, focusOnItemTag: PrivacyAndSecurityEntryTag? = nil, activeSessionsContext: ActiveSessionsContext? = nil, webSessionsContext: WebSessionsContext? = nil, blockedPeersContext: BlockedPeersContext? = nil, hasTwoStepAuth: Bool? = nil, loginEmailPattern: Signal<String?, NoError>? = nil, updatedTwoStepAuthData: (() -> Void)? = nil) -> ViewController {
|
||||
let statePromise = ValuePromise(PrivacyAndSecurityControllerState(), ignoreRepeated: true)
|
||||
let stateValue = Atomic(value: PrivacyAndSecurityControllerState())
|
||||
let updateState: ((PrivacyAndSecurityControllerState) -> PrivacyAndSecurityControllerState) -> Void = { f in
|
||||
@ -1005,8 +1005,8 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
||||
if let emailPattern = emailPattern {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let controller = textAlertController(
|
||||
context: context, title: emailPattern, text: "This email address will be used every time you login to your Telegram account from a new device.", actions: [
|
||||
TextAlertAction(type: .genericAction, title: "Change Email", action: {
|
||||
context: context, title: emailPattern, text: presentationData.strings.PrivacySettings_LoginEmailAlertText, actions: [
|
||||
TextAlertAction(type: .genericAction, title: presentationData.strings.PrivacySettings_LoginEmailAlertChange, action: {
|
||||
setupEmailImpl?(emailPattern)
|
||||
}),
|
||||
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {
|
||||
@ -1092,8 +1092,10 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
||||
|
||||
let emailChangeCompletion: (AuthorizationSequenceCodeEntryController?) -> Void = { codeController in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
codeController?.animateSuccess()
|
||||
|
||||
updatedTwoStepAuthData?()
|
||||
|
||||
Queue.mainQueue().after(0.75) {
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
let controllers = navigationController.viewControllers.filter { controller in
|
||||
@ -1105,9 +1107,11 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
||||
}
|
||||
navigationController.setViewControllers(controllers, animated: true)
|
||||
|
||||
navigationController.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .emoji(name: "IntroLetter", text: presentationData.strings.Login_EmailChanged), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
|
||||
return false
|
||||
}))
|
||||
Queue.mainQueue().after(0.1, {
|
||||
navigationController.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .emoji(name: "IntroLetter", text: presentationData.strings.Login_EmailChanged), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
|
||||
return false
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1115,6 +1119,8 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
||||
setupEmailImpl = { emailPattern in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
var dismissEmailControllerImpl: (() -> Void)?
|
||||
var presentControllerImpl: ((ViewController) -> Void)?
|
||||
|
||||
let emailController = AuthorizationSequenceEmailEntryController(presentationData: presentationData, mode: emailPattern != nil ? .change : .setup, back: {
|
||||
dismissEmailControllerImpl?()
|
||||
})
|
||||
@ -1124,9 +1130,15 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
||||
actionsDisposable.add((sendLoginEmailChangeCode(account: context.account, email: email)
|
||||
|> deliverOnMainQueue).start(next: { data in
|
||||
var dismissCodeControllerImpl: (() -> Void)?
|
||||
var presentControllerImpl: ((ViewController) -> Void)?
|
||||
|
||||
let codeController = AuthorizationSequenceCodeEntryController(presentationData: presentationData, openUrl: { _ in }, back: {
|
||||
dismissCodeControllerImpl?()
|
||||
})
|
||||
|
||||
presentControllerImpl = { [weak codeController] c in
|
||||
codeController?.present(c, in: .window(.root), with: nil)
|
||||
}
|
||||
|
||||
codeController.loginWithCode = { [weak codeController] code in
|
||||
actionsDisposable.add((verifyLoginEmailChange(account: context.account, code: .emailCode(code))
|
||||
@ -1248,6 +1260,10 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
||||
emailController.updateData(appleSignInAllowed: true)
|
||||
pushControllerImpl?(emailController, true)
|
||||
|
||||
presentControllerImpl = { [weak emailController] c in
|
||||
emailController?.present(c, in: .window(.root), with: nil)
|
||||
}
|
||||
|
||||
dismissEmailControllerImpl = { [weak emailController] in
|
||||
emailController?.dismiss()
|
||||
}
|
||||
|
@ -8970,6 +8970,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
items.append(.custom(ChatSendAsPeerTitleContextItem(text: strongSelf.presentationInterfaceState.strings.Conversation_SendMesageAs.uppercased()), false))
|
||||
items.append(.custom(ChatSendAsPeerListContextItem(context: strongSelf.context, chatPeerId: peerId, peers: peers, selectedPeerId: myPeerId, isPremium: isPremium, presentToast: { [weak self] peer in
|
||||
if let strongSelf = self {
|
||||
let hapticFeedback = HapticFeedback()
|
||||
hapticFeedback.impact()
|
||||
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: strongSelf.presentationData.strings.Conversation_SendMesageAsPremiumInfo, action: strongSelf.presentationData.strings.EmojiInput_PremiumEmojiToast_Action), elevatedLayout: false, action: { [weak self] action in
|
||||
guard let strongSelf = self else {
|
||||
return true
|
||||
|
@ -1700,6 +1700,7 @@ func chatAvailableMessageActionsImpl(engine: TelegramEngine, accountPeerId: Peer
|
||||
var hadBanPeerId = false
|
||||
var disableDelete = false
|
||||
var isCopyProtected = false
|
||||
var isShareProtected = false
|
||||
|
||||
func getPeer(_ peerId: PeerId) -> Peer? {
|
||||
if let maybePeer = peerMap[peerId], let peer = maybePeer {
|
||||
@ -1732,7 +1733,9 @@ func chatAvailableMessageActionsImpl(engine: TelegramEngine, accountPeerId: Peer
|
||||
isCopyProtected = true
|
||||
}
|
||||
for media in message.media {
|
||||
if let file = media as? TelegramMediaFile, file.isSticker {
|
||||
if let invoice = media as? TelegramMediaInvoice, let _ = invoice.extendedMedia {
|
||||
isShareProtected = true
|
||||
} else if let file = media as? TelegramMediaFile, file.isSticker {
|
||||
for case let .Sticker(_, packReference, _) in file.attributes {
|
||||
if let _ = packReference {
|
||||
optionsMap[id]!.insert(.viewStickerPack)
|
||||
@ -1917,8 +1920,12 @@ func chatAvailableMessageActionsImpl(engine: TelegramEngine, accountPeerId: Peer
|
||||
optionsMap[id]!.insert(.deleteLocally)
|
||||
}
|
||||
}
|
||||
|
||||
if !isShareProtected {
|
||||
optionsMap[id]!.insert(.externalShare)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !optionsMap.isEmpty {
|
||||
var reducedOptions = optionsMap.values.first!
|
||||
for value in optionsMap.values {
|
||||
|
@ -438,7 +438,11 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
} else if let fetchStatus = self.fetchStatus, case .Local = fetchStatus {
|
||||
var videoContentMatch = true
|
||||
if let content = self.videoContent, case let .message(stableId, mediaId) = content.nativeId {
|
||||
videoContentMatch = self.message?.stableId == stableId && self.media?.id == mediaId
|
||||
var media = self.media
|
||||
if let invoice = media as? TelegramMediaInvoice, let extendedMedia = invoice.extendedMedia, case let .full(fullMedia) = extendedMedia {
|
||||
media = fullMedia
|
||||
}
|
||||
videoContentMatch = self.message?.stableId == stableId && media?.id == mediaId
|
||||
}
|
||||
self.activateLocalContent((self.automaticPlayback ?? false) && videoContentMatch ? .automaticPlayback : .default)
|
||||
} else {
|
||||
@ -1490,6 +1494,11 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
|
||||
let formatting = DataSizeStringFormatting(strings: strings, decimalSeparator: decimalSeparator)
|
||||
|
||||
var media = self.media
|
||||
if let invoice = media as? TelegramMediaInvoice, let extendedMedia = invoice.extendedMedia, case let .full(fullMedia) = extendedMedia {
|
||||
media = fullMedia
|
||||
}
|
||||
|
||||
switch fetchStatus {
|
||||
case let .Fetching(_, progress):
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
@ -1502,8 +1511,8 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
} else {
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true)
|
||||
}
|
||||
|
||||
if let file = self.media as? TelegramMediaFile {
|
||||
|
||||
if let file = media as? TelegramMediaFile {
|
||||
if file.isVideoSticker {
|
||||
state = .none
|
||||
badgeContent = nil
|
||||
@ -1617,7 +1626,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
}
|
||||
case .Remote, .Paused:
|
||||
state = .download(messageTheme.mediaOverlayControlColors.foregroundColor)
|
||||
if let file = self.media as? TelegramMediaFile, !file.isVideoSticker {
|
||||
if let file = media as? TelegramMediaFile, !file.isVideoSticker {
|
||||
do {
|
||||
let durationString = file.isAnimated ? gifTitle : stringForDuration(playerDuration > 0 ? playerDuration : (file.duration ?? 0), position: playerPosition)
|
||||
if wideLayout {
|
||||
|
@ -172,7 +172,7 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
||||
} else {
|
||||
self.deleteButton.isEnabled = !actions.disableDelete
|
||||
}
|
||||
self.shareButton.isImplicitlyDisabled = actions.options.intersection([.forward]).isEmpty
|
||||
self.shareButton.isImplicitlyDisabled = actions.options.intersection(.forward).isEmpty || actions.options.intersection(.externalShare).isEmpty
|
||||
self.reportButton.isEnabled = !actions.options.intersection([.report]).isEmpty
|
||||
|
||||
if self.peerMedia {
|
||||
|
@ -6414,7 +6414,17 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
self?.blockedPeers.set(.single(blockedPeersContext))
|
||||
}, updatedHasTwoStepAuth: { [weak self] hasTwoStepAuthValue in
|
||||
self?.hasTwoStepAuth.set(.single(hasTwoStepAuthValue))
|
||||
}, focusOnItemTag: nil, activeSessionsContext: settings.activeSessionsContext, webSessionsContext: settings.webSessionsContext, blockedPeersContext: blockedPeersContext, hasTwoStepAuth: hasTwoStepAuth, loginEmailPattern: loginEmailPattern))
|
||||
}, focusOnItemTag: nil, activeSessionsContext: settings.activeSessionsContext, webSessionsContext: settings.webSessionsContext, blockedPeersContext: blockedPeersContext, hasTwoStepAuth: hasTwoStepAuth, loginEmailPattern: loginEmailPattern, updatedTwoStepAuthData: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.twoStepAuthData.set(
|
||||
strongSelf.context.engine.auth.twoStepAuthData()
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<TwoStepAuthData?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
)
|
||||
}
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user