mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
699287d011
@ -8952,3 +8952,7 @@ Sorry for the inconvenience.";
|
||||
|
||||
"GroupPermission.NotAvailableInDiscussionGroups" = "This permission is not available in discussion groups.";
|
||||
"GroupPermission.NotAvailableInGeoGroups" = "This permission is not available in location-based groups.";
|
||||
|
||||
"Conversation.ShareLinkTooltip.Chat.One" = "Link shared with **%@**";
|
||||
"Conversation.ShareLinkTooltip.TwoChats.One" = "Link shared with **%@** and **%@**";
|
||||
"Conversation.ShareLinkTooltip.ManyChats.One" = "Link shared with **%@** and %@ others";
|
||||
|
@ -600,7 +600,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value).start()
|
||||
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_mute_for", scale: 0.066, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedFor(mutedForTimeIntervalString(strings: presentationData.strings, value: value)).string, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_mute_for", scale: 0.066, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedFor(mutedForTimeIntervalString(strings: presentationData.strings, value: value)).string, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
}
|
||||
|
||||
@ -643,7 +643,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor
|
||||
], title: nil, text: presentationData.strings.PeerInfo_TooltipUnmuted, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
], title: nil, text: presentationData.strings.PeerInfo_TooltipUnmuted, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
} else if !isSoundEnabled {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeerInfo_EnableSound, icon: { theme in
|
||||
@ -653,7 +653,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
|
||||
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .default).start()
|
||||
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_sound_on", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipSoundEnabled, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_sound_on", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipSoundEnabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
} else {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeerInfo_DisableSound, icon: { theme in
|
||||
@ -663,7 +663,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
|
||||
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .none).start()
|
||||
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_sound_off", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipSoundDisabled, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
chatListController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_sound_off", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipSoundDisabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
}
|
||||
|
||||
@ -714,7 +714,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor
|
||||
], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
}
|
||||
})
|
||||
}, updatePeerDisplayPreviews: { peerId, displayPreviews in
|
||||
@ -744,7 +744,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor
|
||||
], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
|
||||
c.setItems(.single(ContextController.Items(content: .list(items))), minHeight: nil)
|
||||
@ -799,7 +799,7 @@ private func openCustomMute(context: AccountContext, peerId: EnginePeer.Id, thre
|
||||
|
||||
let timeString = stringForPreciseRelativeTimestamp(strings: presentationData.strings, relativeTimestamp: Int32(Date().timeIntervalSince1970) + value, relativeTo: Int32(Date().timeIntervalSince1970), dateTimeFormat: presentationData.dateTimeFormat)
|
||||
|
||||
baseController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_mute_for", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedUntil(timeString).string, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
baseController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_mute_for", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedUntil(timeString).string, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
}
|
||||
})
|
||||
baseController.view.endEditing(true)
|
||||
|
@ -1361,7 +1361,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
self.tabContainerNode.presentPremiumTip = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_reorder", scale: 0.05, colors: [:], title: nil, text: strongSelf.presentationData.strings.ChatListFolderSettings_SubscribeToMoveAll, customUndoText: strongSelf.presentationData.strings.ChatListFolderSettings_SubscribeToMoveAllAction), elevatedLayout: false, position: .top, animateInAsReplacement: false, action: { action in
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_reorder", scale: 0.05, colors: [:], title: nil, text: strongSelf.presentationData.strings.ChatListFolderSettings_SubscribeToMoveAll, customUndoText: strongSelf.presentationData.strings.ChatListFolderSettings_SubscribeToMoveAllAction, timeout: nil), elevatedLayout: false, position: .top, animateInAsReplacement: false, action: { action in
|
||||
if case .undo = action {
|
||||
let context = strongSelf.context
|
||||
var replaceImpl: ((ViewController) -> Void)?
|
||||
@ -1613,12 +1613,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
}
|
||||
|
||||
private static var sharedPreviousPowerSavingEnabled: Bool?
|
||||
public static var sharedPreviousPowerSavingEnabled: Bool?
|
||||
|
||||
override public func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
if !self.didAppear {
|
||||
if self.powerSavingMonitoringDisposable == nil {
|
||||
self.powerSavingMonitoringDisposable = (self.context.sharedContext.automaticMediaDownloadSettings
|
||||
|> mapToSignal { settings -> Signal<Bool, NoError> in
|
||||
return automaticEnergyUsageShouldBeOn(settings: settings)
|
||||
@ -1644,7 +1644,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|
||||
self.dismissAllUndoControllers()
|
||||
//TODO:localize
|
||||
self.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "lowbattery_30", scale: 1.0, colors: [:], title: "Power Saving mode enabled", text: "\(batteryPercentage)% battery remaining.", customUndoText: "Disable"), elevatedLayout: false, action: { [weak self] action in
|
||||
self.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "lowbattery_30", scale: 1.0, colors: [:], title: "Power Saving mode enabled", text: "\(batteryPercentage)% battery remaining.", customUndoText: "Disable", timeout: 5.0), elevatedLayout: false, action: { [weak self] action in
|
||||
if case .undo = action, let self {
|
||||
let _ = updateMediaDownloadSettingsInteractively(accountManager: self.context.sharedContext.accountManager, { settings in
|
||||
var settings = settings
|
||||
|
@ -612,7 +612,7 @@ public func chatListFilterPresetListController(context: AccountContext, mode: Ch
|
||||
updatedFilterOrder.set(.single(previousOrder))
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_reorder", scale: 0.05, colors: [:], title: nil, text: presentationData.strings.ChatListFolderSettings_SubscribeToMoveAll, customUndoText: presentationData.strings.ChatListFolderSettings_SubscribeToMoveAllAction), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_reorder", scale: 0.05, colors: [:], title: nil, text: presentationData.strings.ChatListFolderSettings_SubscribeToMoveAll, customUndoText: presentationData.strings.ChatListFolderSettings_SubscribeToMoveAllAction, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
if case .undo = action {
|
||||
pushControllerImpl?(PremiumIntroScreen(context: context, source: .folders))
|
||||
}
|
||||
|
@ -1337,7 +1337,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
switch result {
|
||||
case .generic:
|
||||
controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil, timeout: nil), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
case let .limitExceeded(limit, premiumLimit):
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let text: String
|
||||
@ -1346,7 +1346,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
} else {
|
||||
text = presentationData.strings.Premium_MaxSavedGifsText("\(premiumLimit)").string
|
||||
}
|
||||
controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text, customUndoText: nil), elevatedLayout: true, animateInAsReplacement: false, action: { action in
|
||||
controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text, customUndoText: nil, timeout: nil), elevatedLayout: true, animateInAsReplacement: false, action: { action in
|
||||
if case .info = action {
|
||||
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .savedGifs)
|
||||
controllerInteraction?.pushController(controller)
|
||||
@ -1549,7 +1549,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
switch result {
|
||||
case .generic:
|
||||
controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil, timeout: nil), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
case let .limitExceeded(limit, premiumLimit):
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let text: String
|
||||
@ -1558,7 +1558,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
} else {
|
||||
text = presentationData.strings.Premium_MaxSavedGifsText("\(premiumLimit)").string
|
||||
}
|
||||
controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text, customUndoText: nil), elevatedLayout: true, animateInAsReplacement: false, action: { action in
|
||||
controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text, customUndoText: nil, timeout: nil), elevatedLayout: true, animateInAsReplacement: false, action: { action in
|
||||
if case .info = action {
|
||||
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .savedGifs)
|
||||
controllerInteraction?.pushController(controller)
|
||||
|
@ -76,6 +76,7 @@ swift_library(
|
||||
"//submodules/PremiumUI:PremiumUI",
|
||||
"//submodules/Components/ReactionImageComponent:ReactionImageComponent",
|
||||
"//submodules/Components/LottieAnimationComponent:LottieAnimationComponent",
|
||||
"//submodules/TelegramUI/Components/SendInviteLinkScreen",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -14,6 +14,7 @@ import ItemListAvatarAndNameInfoItem
|
||||
import Emoji
|
||||
import LocalizedPeerData
|
||||
import Markdown
|
||||
import SendInviteLinkScreen
|
||||
|
||||
private let rankMaxLength: Int32 = 16
|
||||
|
||||
@ -975,10 +976,13 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: adminId),
|
||||
TelegramEngine.EngineData.Item.Peer.Presence(id: adminId)
|
||||
),
|
||||
context.engine.data.subscribe(
|
||||
TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: peerId)
|
||||
)
|
||||
)
|
||||
|> deliverOnMainQueue
|
||||
|> map { presentationData, state, peerInfoData -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
|> map { presentationData, state, peerInfoData, exportedInvitation -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let channelPeer = peerInfoData.0.flatMap { $0 }
|
||||
let adminPeer = peerInfoData.1.flatMap { $0 }
|
||||
let adminPresence = peerInfoData.2
|
||||
@ -1011,6 +1015,15 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
||||
updateState { current in
|
||||
return current.withUpdatedUpdating(false)
|
||||
}
|
||||
|
||||
if let adminPeer, let exportedInvitation, let link = exportedInvitation.link {
|
||||
let inviteScreen = SendInviteLinkScreen(context: context, link: link, peers: [adminPeer])
|
||||
pushControllerImpl?(inviteScreen)
|
||||
|
||||
dismissImpl?()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
var text = presentationData.strings.Login_UnknownError
|
||||
@ -1193,6 +1206,15 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
||||
}
|
||||
updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(engine: context.engine, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(rights: updateFlags), rank: updateRank) |> deliverOnMainQueue).start(error: { error in
|
||||
if case let .addMemberError(addMemberError) = error, let admin = adminPeer {
|
||||
if let exportedInvitation, let link = exportedInvitation.link {
|
||||
let inviteScreen = SendInviteLinkScreen(context: context, link: link, peers: [admin])
|
||||
pushControllerImpl?(inviteScreen)
|
||||
|
||||
dismissImpl?()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var text = presentationData.strings.Login_UnknownError
|
||||
switch addMemberError {
|
||||
case .tooMuchJoined:
|
||||
|
@ -318,7 +318,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat
|
||||
|
||||
if case let .channel(channel) = groupPeer, channel.flags.contains(.isForum) {
|
||||
let text = presentationData.strings.PeerInfo_TopicsLimitedDiscussionGroups
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_topics", scale: 0.066, colors: [:], title: nil, text: text, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_topics", scale: 0.066, colors: [:], title: nil, text: text, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ import ItemListPeerItem
|
||||
import ItemListPeerActionItem
|
||||
import InviteLinksUI
|
||||
import UndoUI
|
||||
import SendInviteLinkScreen
|
||||
|
||||
private final class ChannelMembersControllerArguments {
|
||||
let context: AccountContext
|
||||
@ -510,16 +511,18 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
|
||||
let contactsPromise = Promise<[RenderedChannelParticipant]?>(nil)
|
||||
|
||||
let arguments = ChannelMembersControllerArguments(context: context, addMember: {
|
||||
actionsDisposable.add((peersPromise.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { members in
|
||||
actionsDisposable.add((combineLatest(
|
||||
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: peerId)),
|
||||
peersPromise.get() |> take(1)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { exportedInvitation, members in
|
||||
let disabledIds = members?.compactMap({$0.peer.id}) ?? []
|
||||
let contactsController = context.sharedContext.makeContactMultiselectionController(ContactMultiselectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, mode: .peerSelection(searchChatList: false, searchGroups: false, searchChannels: false), options: [], filters: [.excludeSelf, .disable(disabledIds)]))
|
||||
|
||||
addMembersDisposable.set((contactsController.result
|
||||
addMembersDisposable.set((
|
||||
contactsController.result
|
||||
|> deliverOnMainQueue
|
||||
|> castError(AddChannelMemberError.self)
|
||||
|> mapToSignal { [weak contactsController] result -> Signal<Never, AddChannelMemberError> in
|
||||
|> mapToSignal { [weak contactsController] result -> Signal<[(PeerId, AddChannelMemberError)], NoError> in
|
||||
contactsController?.displayProgress = true
|
||||
|
||||
var contacts: [ContactListPeerId] = []
|
||||
@ -527,7 +530,7 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
|
||||
contacts = peerIdsValue
|
||||
}
|
||||
|
||||
let signal = context.peerChannelMemberCategoriesContextsManager.addMembers(engine: context.engine, peerId: peerId, memberIds: contacts.compactMap({ contact -> PeerId? in
|
||||
let signal = context.peerChannelMemberCategoriesContextsManager.addMembersAllowPartial(engine: context.engine, peerId: peerId, memberIds: contacts.compactMap({ contact -> PeerId? in
|
||||
switch contact {
|
||||
case let .peer(contactId):
|
||||
return contactId
|
||||
@ -537,17 +540,43 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
|
||||
}))
|
||||
|
||||
return signal
|
||||
|> ignoreValues
|
||||
|> deliverOnMainQueue
|
||||
|> afterCompleted {
|
||||
contactsController?.dismiss()
|
||||
}
|
||||
}).start(error: { [weak contactsController] error in
|
||||
}).start(next: { [weak contactsController] failedPeerIds in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
let text: String
|
||||
switch error {
|
||||
|
||||
if failedPeerIds.isEmpty {
|
||||
contactsController?.dismiss()
|
||||
} else {
|
||||
if let exportedInvitation, let link = exportedInvitation.link {
|
||||
let _ = (context.engine.data.get(
|
||||
EngineDataList(failedPeerIds.compactMap { item -> EnginePeer.Id? in
|
||||
return item.0
|
||||
}.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { peerItems in
|
||||
let peers = peerItems.compactMap { $0 }
|
||||
if !peers.isEmpty, let contactsController, let navigationController = contactsController.navigationController as? NavigationController {
|
||||
var viewControllers = navigationController.viewControllers
|
||||
if let index = viewControllers.firstIndex(where: { $0 === contactsController }) {
|
||||
let inviteScreen = SendInviteLinkScreen(context: context, link: link, peers: peers)
|
||||
viewControllers.remove(at: index)
|
||||
viewControllers.append(inviteScreen)
|
||||
navigationController.setViewControllers(viewControllers, animated: true)
|
||||
}
|
||||
} else {
|
||||
contactsController?.dismiss()
|
||||
}
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
contactsController?.dismiss()
|
||||
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
let text: String
|
||||
switch failedPeerIds[0].1 {
|
||||
case .limitExceeded:
|
||||
text = presentationData.strings.Channel_ErrorAddTooMuch
|
||||
case .tooMuchJoined:
|
||||
@ -557,13 +586,13 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
|
||||
case .restricted:
|
||||
text = presentationData.strings.Channel_ErrorAddBlocked
|
||||
case .notMutualContact:
|
||||
if case let .channel(peer) = peer, case .broadcast = peer.info {
|
||||
if case let .channel(peer) = peer, case .broadcast = peer.info {
|
||||
text = presentationData.strings.Channel_AddUserLeftError
|
||||
} else {
|
||||
text = presentationData.strings.GroupInfo_AddUserLeftError
|
||||
}
|
||||
case let .bot(memberId):
|
||||
guard case let .channel(peer) = peer else {
|
||||
guard case let .channel(peer) = peer else {
|
||||
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||
contactsController?.dismiss()
|
||||
return
|
||||
@ -589,10 +618,11 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
|
||||
text = presentationData.strings.Channel_TooMuchBots
|
||||
case .kicked:
|
||||
text = presentationData.strings.Channel_AddUserKickedError
|
||||
}
|
||||
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||
contactsController?.dismiss()
|
||||
})
|
||||
}
|
||||
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||
contactsController?.dismiss()
|
||||
})
|
||||
}
|
||||
}))
|
||||
|
||||
presentControllerImpl?(contactsController, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
@ -774,7 +804,7 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
|
||||
case .notAllowed:
|
||||
text = presentationData.strings.PeerInfo_HideMembersLimitedRights
|
||||
}
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_topics", scale: 0.066, colors: [:], title: nil, text: text, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_topics", scale: 0.066, colors: [:], title: nil, text: text, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
getControllerImpl = { [weak controller] in
|
||||
return controller
|
||||
|
@ -277,7 +277,7 @@ public func energySavingSettingsScreen(context: AccountContext) -> ViewControlle
|
||||
} else {
|
||||
text = "Turn off Power Saving Mode or charge your phone to change these settings."
|
||||
}
|
||||
displayTooltipImpl?(.universal(animation: "lowbattery_30", scale: 1.0, colors: [:], title: nil, text: text, customUndoText: nil))
|
||||
displayTooltipImpl?(.universal(animation: "lowbattery_30", scale: 1.0, colors: [:], title: nil, text: text, customUndoText: nil, timeout: 5.0))
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -1178,7 +1178,7 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
||||
|
||||
if stickerSettings.dynamicPackOrder {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_reorder", scale: 0.05, colors: [:], title: presentationData.strings.StickerPacksSettings_DynamicOrderOff, text: presentationData.strings.StickerPacksSettings_DynamicOrderOffInfo, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_reorder", scale: 0.05, colors: [:], title: presentationData.strings.StickerPacksSettings_DynamicOrderOff, text: presentationData.strings.StickerPacksSettings_DynamicOrderOffInfo, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
return false }), nil)
|
||||
|
||||
arguments.toggleDynamicPackOrder(false)
|
||||
|
@ -105,6 +105,8 @@ private final class BadgeNode: ASDisplayNode {
|
||||
|
||||
self.addSubnode(self.backgroundNode)
|
||||
self.addSubnode(self.textNode)
|
||||
|
||||
self.isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
func updateTheme(fillColor: UIColor, strokeColor: UIColor, textColor: UIColor) {
|
||||
|
@ -2008,7 +2008,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
|
||||
if self.context.sharedContext.currentStickerSettings.with({ $0 }).dynamicPackOrder {
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_reorder", scale: 0.05, colors: [:], title: presentationData.strings.StickerPacksSettings_DynamicOrderOff, text: presentationData.strings.StickerPacksSettings_DynamicOrderOffInfo, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
self.controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_reorder", scale: 0.05, colors: [:], title: presentationData.strings.StickerPacksSettings_DynamicOrderOff, text: presentationData.strings.StickerPacksSettings_DynamicOrderOffInfo, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
return false
|
||||
}), nil)
|
||||
|
||||
@ -2120,7 +2120,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
}
|
||||
switch result {
|
||||
case .generic:
|
||||
strongSelf.controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
strongSelf.controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
case let .limitExceeded(limit, premiumLimit):
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let text: String
|
||||
@ -2129,7 +2129,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
} else {
|
||||
text = presentationData.strings.Premium_MaxSavedGifsText("\(premiumLimit)").string
|
||||
}
|
||||
strongSelf.controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
strongSelf.controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
guard let strongSelf = self else {
|
||||
return false
|
||||
}
|
||||
|
@ -498,9 +498,17 @@ private final class SendInviteLinkScreenComponent: Component {
|
||||
controller.dismiss()
|
||||
} else {
|
||||
let _ = enqueueMessagesToMultiplePeers(account: component.context.account, peerIds: Array(self.selectedItems), threadIds: [:], messages: [.message(text: component.link, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
|
||||
//TODO:localize
|
||||
let text: String
|
||||
if component.peers.count == 1 {
|
||||
text = environment.strings.Conversation_ShareLinkTooltip_Chat_One(component.peers[0].displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: "")).string
|
||||
} else if component.peers.count == 2 {
|
||||
text = environment.strings.Conversation_ShareLinkTooltip_TwoChats_One(component.peers[0].displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: ""), component.peers[1].displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: "")).string
|
||||
} else {
|
||||
text = environment.strings.Conversation_ShareLinkTooltip_ManyChats_One(component.peers[0].displayTitle(strings: environment.strings, displayOrder: .firstLast).replacingOccurrences(of: "*", with: ""), "\(component.peers.count - 1)").string
|
||||
}
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: .peers(context: component.context, peers: Array(component.peers.prefix(3)), title: nil, text: "Invite link sent.", customUndoText: nil), elevatedLayout: false, action: { _ in return false }), in: .window(.root))
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: false, text: text), elevatedLayout: false, action: { _ in return false }), in: .window(.root))
|
||||
|
||||
controller.dismiss()
|
||||
}
|
||||
|
@ -547,6 +547,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
private var currentSpeechHolder: SpeechSynthesizerHolder?
|
||||
|
||||
private var powerSavingMonitoringDisposable: Disposable?
|
||||
|
||||
public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, attachBotStart: ChatControllerInitialAttachBotStart? = nil, botAppStart: ChatControllerInitialBotAppStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false), peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, chatListFilter: Int32? = nil, chatNavigationStack: [ChatNavigationStackItem] = []) {
|
||||
let _ = ChatControllerCount.modify { value in
|
||||
return value + 1
|
||||
@ -6016,6 +6018,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.preloadAttachBotIconsDisposables?.dispose()
|
||||
self.keepMessageCountersSyncrhonizedDisposable?.dispose()
|
||||
self.translationStateDisposable?.dispose()
|
||||
self.powerSavingMonitoringDisposable?.dispose()
|
||||
}
|
||||
deallocate()
|
||||
}
|
||||
@ -8680,7 +8683,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
if bannedMediaInput {
|
||||
strongSelf.controllerInteraction?.displayUndo(.universal(animation: "premium_unlock", scale: 1.0, colors: ["__allcolors__": UIColor(white: 1.0, alpha: 1.0)], title: nil, text: strongSelf.restrictedSendingContentsText(), customUndoText: nil))
|
||||
strongSelf.controllerInteraction?.displayUndo(.universal(animation: "premium_unlock", scale: 1.0, colors: ["__allcolors__": UIColor(white: 1.0, alpha: 1.0)], title: nil, text: strongSelf.restrictedSendingContentsText(), customUndoText: nil, timeout: nil))
|
||||
return
|
||||
}
|
||||
|
||||
@ -8822,7 +8825,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
switch displayType {
|
||||
case .tooltip:
|
||||
if displayToast {
|
||||
strongSelf.controllerInteraction?.displayUndo(.universal(animation: "premium_unlock", scale: 1.0, colors: ["__allcolors__": UIColor(white: 1.0, alpha: 1.0)], title: nil, text: banDescription, customUndoText: nil))
|
||||
strongSelf.controllerInteraction?.displayUndo(.universal(animation: "premium_unlock", scale: 1.0, colors: ["__allcolors__": UIColor(white: 1.0, alpha: 1.0)], title: nil, text: banDescription, customUndoText: nil, timeout: nil))
|
||||
} else {
|
||||
var rect: CGRect?
|
||||
let isStickers: Bool = subject == .stickers
|
||||
@ -8992,7 +8995,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
if bannedMediaInput {
|
||||
strongSelf.controllerInteraction?.displayUndo(.universal(animation: "premium_unlock", scale: 1.0, colors: ["__allcolors__": UIColor(white: 1.0, alpha: 1.0)], title: nil, text: strongSelf.restrictedSendingContentsText(), customUndoText: nil))
|
||||
strongSelf.controllerInteraction?.displayUndo(.universal(animation: "premium_unlock", scale: 1.0, colors: ["__allcolors__": UIColor(white: 1.0, alpha: 1.0)], title: nil, text: strongSelf.restrictedSendingContentsText(), customUndoText: nil, timeout: nil))
|
||||
return
|
||||
}
|
||||
|
||||
@ -11065,6 +11068,47 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.attachBotStart = nil
|
||||
self.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload, justInstalled: attachBotStart.justInstalled)
|
||||
}
|
||||
|
||||
if self.powerSavingMonitoringDisposable == nil {
|
||||
self.powerSavingMonitoringDisposable = (self.context.sharedContext.automaticMediaDownloadSettings
|
||||
|> mapToSignal { settings -> Signal<Bool, NoError> in
|
||||
return automaticEnergyUsageShouldBeOn(settings: settings)
|
||||
}
|
||||
|> distinctUntilChanged).start(next: { [weak self] isPowerSavingEnabled in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
var previousValueValue: Bool?
|
||||
|
||||
previousValueValue = ChatListControllerImpl.sharedPreviousPowerSavingEnabled
|
||||
ChatListControllerImpl.sharedPreviousPowerSavingEnabled = isPowerSavingEnabled
|
||||
|
||||
/*#if DEBUG
|
||||
previousValueValue = false
|
||||
#endif*/
|
||||
|
||||
if isPowerSavingEnabled != previousValueValue && previousValueValue != nil && isPowerSavingEnabled {
|
||||
let batteryLevel = UIDevice.current.batteryLevel
|
||||
if batteryLevel > 0.0 && self.view.window != nil {
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let batteryPercentage = Int(batteryLevel * 100.0)
|
||||
|
||||
self.dismissAllUndoControllers()
|
||||
//TODO:localize
|
||||
self.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "lowbattery_30", scale: 1.0, colors: [:], title: "Power Saving mode enabled", text: "\(batteryPercentage)% battery remaining.", customUndoText: "Disable", timeout: 5.0), elevatedLayout: false, action: { [weak self] action in
|
||||
if case .undo = action, let self {
|
||||
let _ = updateMediaDownloadSettingsInteractively(accountManager: self.context.sharedContext.accountManager, { settings in
|
||||
var settings = settings
|
||||
settings.energyUsageSettings.activationThreshold = 0
|
||||
return settings
|
||||
}).start()
|
||||
}
|
||||
return false
|
||||
}), in: .current)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override public func viewWillDisappear(_ animated: Bool) {
|
||||
@ -14308,12 +14352,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return transformEnqueueMessages(messages, silentPosting: silentPosting)
|
||||
}
|
||||
|
||||
private func displayPremiumStickerTooltip(file: TelegramMediaFile, message: Message) {
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: self.context.currentAppConfiguration.with { $0 })
|
||||
guard !premiumConfiguration.isPremiumDisabled else {
|
||||
return
|
||||
}
|
||||
|
||||
@discardableResult private func dismissAllUndoControllers() -> UndoOverlayController? {
|
||||
var currentOverlayController: UndoOverlayController?
|
||||
|
||||
self.window?.forEachController({ controller in
|
||||
@ -14328,6 +14367,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return true
|
||||
})
|
||||
|
||||
return currentOverlayController
|
||||
}
|
||||
|
||||
private func displayPremiumStickerTooltip(file: TelegramMediaFile, message: Message) {
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: self.context.currentAppConfiguration.with { $0 })
|
||||
guard !premiumConfiguration.isPremiumDisabled else {
|
||||
return
|
||||
}
|
||||
|
||||
let currentOverlayController: UndoOverlayController? = self.dismissAllUndoControllers()
|
||||
|
||||
if let currentOverlayController = currentOverlayController {
|
||||
if case .sticker = currentOverlayController.content {
|
||||
return
|
||||
|
@ -428,18 +428,26 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
if let sponsorInfo = adAttribute.sponsorInfo {
|
||||
subItems.append(.action(ContextMenuActionItem(text: sponsorInfo, textColor: .primary, textLayout: .multiline, textFont: .custom(font: Font.regular(floor(presentationData.listsFontSize.baseDisplaySize * 0.8)), height: nil, verticalOffset: nil), badge: nil, icon: { theme in
|
||||
return nil
|
||||
}, iconSource: nil, action: { c, _ in
|
||||
}, iconSource: nil, action: { [weak controllerInteraction] c, _ in
|
||||
c.dismiss(completion: {
|
||||
UIPasteboard.general.string = sponsorInfo
|
||||
|
||||
//TODO:localize
|
||||
let content: UndoOverlayContent = .copy(text: "Text copied")
|
||||
controllerInteraction?.displayUndo(content)
|
||||
})
|
||||
})))
|
||||
}
|
||||
if let additionalInfo = adAttribute.additionalInfo {
|
||||
subItems.append(.action(ContextMenuActionItem(text: additionalInfo, textColor: .primary, textLayout: .multiline, textFont: .custom(font: Font.regular(floor(presentationData.listsFontSize.baseDisplaySize * 0.8)), height: nil, verticalOffset: nil), badge: nil, icon: { theme in
|
||||
return nil
|
||||
}, iconSource: nil, action: { c, _ in
|
||||
}, iconSource: nil, action: { [weak controllerInteraction] c, _ in
|
||||
c.dismiss(completion: {
|
||||
UIPasteboard.general.string = additionalInfo
|
||||
|
||||
//TODO:localize
|
||||
let content: UndoOverlayContent = .copy(text: "Text copied")
|
||||
controllerInteraction?.displayUndo(content)
|
||||
})
|
||||
})))
|
||||
}
|
||||
@ -1519,7 +1527,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
Queue.mainQueue().after(0.2) {
|
||||
switch result {
|
||||
case .generic:
|
||||
controllerInteraction.presentControllerInCurrent(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
controllerInteraction.presentControllerInCurrent(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
case let .limitExceeded(limit, premiumLimit):
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let text: String
|
||||
@ -1528,7 +1536,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
} else {
|
||||
text = presentationData.strings.Premium_MaxSavedGifsText("\(premiumLimit)").string
|
||||
}
|
||||
controllerInteraction.presentControllerInCurrent(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
controllerInteraction.presentControllerInCurrent(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
if case .info = action {
|
||||
let controller = PremiumIntroScreen(context: context, source: .savedGifs)
|
||||
controllerInteraction.navigationController()?.pushViewController(controller)
|
||||
|
@ -364,7 +364,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
self.hapticFeedback?.impact(.medium)
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let tipController = UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_voiceToText", scale: 0.065, colors: [:], title: nil, text: presentationData.strings.Message_AudioTranscription_SubscribeToPremium, customUndoText: presentationData.strings.Message_AudioTranscription_SubscribeToPremiumAction), elevatedLayout: false, position: .top, animateInAsReplacement: false, action: { action in
|
||||
let tipController = UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_voiceToText", scale: 0.065, colors: [:], title: nil, text: presentationData.strings.Message_AudioTranscription_SubscribeToPremium, customUndoText: presentationData.strings.Message_AudioTranscription_SubscribeToPremiumAction, timeout: nil), elevatedLayout: false, position: .top, animateInAsReplacement: false, action: { action in
|
||||
if case .undo = action {
|
||||
var replaceImpl: ((ViewController) -> Void)?
|
||||
let controller = context.sharedContext.makePremiumDemoController(context: context, subject: .voiceToText, action: {
|
||||
|
@ -1525,7 +1525,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
self.hapticFeedback?.impact(.medium)
|
||||
|
||||
let presentationData = item.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let tipController = UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_voiceToText", scale: 0.065, colors: [:], title: nil, text: presentationData.strings.Message_AudioTranscription_SubscribeToPremium, customUndoText: presentationData.strings.Message_AudioTranscription_SubscribeToPremiumAction), elevatedLayout: false, position: .top, animateInAsReplacement: false, action: { action in
|
||||
let tipController = UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_voiceToText", scale: 0.065, colors: [:], title: nil, text: presentationData.strings.Message_AudioTranscription_SubscribeToPremium, customUndoText: presentationData.strings.Message_AudioTranscription_SubscribeToPremiumAction, timeout: nil), elevatedLayout: false, position: .top, animateInAsReplacement: false, action: { action in
|
||||
if case .undo = action {
|
||||
let context = item.context
|
||||
var replaceImpl: ((ViewController) -> Void)?
|
||||
|
@ -793,7 +793,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
if peer.id == antiSpamBotConfiguration.antiSpamBotId {
|
||||
self.dismissAllTooltips()
|
||||
|
||||
self.presentController(UndoOverlayController(presentationData: self.presentationData, content: .universal(animation: "anim_antispam", scale: 0.066, colors: [:], title: self.presentationData.strings.Group_AdminLog_AntiSpamTitle, text: self.presentationData.strings.Group_AdminLog_AntiSpamText, customUndoText: nil), elevatedLayout: true, action: { [weak self] action in
|
||||
self.presentController(UndoOverlayController(presentationData: self.presentationData, content: .universal(animation: "anim_antispam", scale: 0.066, colors: [:], title: self.presentationData.strings.Group_AdminLog_AntiSpamTitle, text: self.presentationData.strings.Group_AdminLog_AntiSpamText, customUndoText: nil, timeout: nil), elevatedLayout: true, action: { [weak self] action in
|
||||
if let strongSelf = self {
|
||||
if case .info = action {
|
||||
let _ = strongSelf.getNavigationController()?.popViewController(animated: true)
|
||||
@ -927,7 +927,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
|> deliverOnMainQueue).start(), forKey: message.id)
|
||||
|
||||
Queue.mainQueue().after(0.2, {
|
||||
strongSelf.presentController(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_antispam", scale: 0.066, colors: [:], title: nil, text: strongSelf.presentationData.strings.Group_AdminLog_AntiSpamFalsePositiveReportedText, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), .current, nil)
|
||||
strongSelf.presentController(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_antispam", scale: 0.066, colors: [:], title: nil, text: strongSelf.presentationData.strings.Group_AdminLog_AntiSpamFalsePositiveReportedText, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), .current, nil)
|
||||
})
|
||||
}
|
||||
})), at: 0
|
||||
|
@ -932,7 +932,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
guard let controller = strongSelf.interfaceInteraction?.chatController() as? ChatControllerImpl else {
|
||||
return
|
||||
}
|
||||
controller.controllerInteraction?.displayUndo(.universal(animation: "premium_unlock", scale: 1.0, colors: ["__allcolors__": UIColor(white: 1.0, alpha: 1.0)], title: nil, text: controller.restrictedSendingContentsText(), customUndoText: nil))
|
||||
controller.controllerInteraction?.displayUndo(.universal(animation: "premium_unlock", scale: 1.0, colors: ["__allcolors__": UIColor(white: 1.0, alpha: 1.0)], title: nil, text: controller.restrictedSendingContentsText(), customUndoText: nil, timeout: nil))
|
||||
} else {
|
||||
strongSelf.ensureFocused()
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
switch result {
|
||||
case .generic:
|
||||
interfaceInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
interfaceInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
case let .limitExceeded(limit, premiumLimit):
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let text: String
|
||||
@ -213,7 +213,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
|
||||
} else {
|
||||
text = presentationData.strings.Premium_MaxSavedGifsText("\(premiumLimit)").string
|
||||
}
|
||||
interfaceInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
interfaceInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
if case .info = action {
|
||||
let controller = PremiumIntroScreen(context: context, source: .savedGifs)
|
||||
interfaceInteraction?.getNavigationController()?.pushViewController(controller)
|
||||
|
@ -2243,7 +2243,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
case .discussion:
|
||||
text = self.presentationData.strings.PeerInfo_TopicsLimitedDiscussionGroups
|
||||
}
|
||||
self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_topics", scale: 0.066, colors: [:], title: nil, text: text, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_topics", scale: 0.066, colors: [:], title: nil, text: text, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
)
|
||||
|
||||
@ -4302,7 +4302,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor
|
||||
], title: nil, text: self.presentationData.strings.PeerInfo_TooltipUnmuted, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
], title: nil, text: self.presentationData.strings.PeerInfo_TooltipUnmuted, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
} else {
|
||||
self.state = self.state.withHighlightedButton(.mute)
|
||||
if let (layout, navigationHeight) = self.validLayout {
|
||||
@ -4341,7 +4341,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: strongSelf.chatLocation.threadId, muteInterval: value).start()
|
||||
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_mute_for", scale: 0.066, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedFor(mutedForTimeIntervalString(strings: strongSelf.presentationData.strings, value: value)).string, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_mute_for", scale: 0.066, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedFor(mutedForTimeIntervalString(strings: strongSelf.presentationData.strings, value: value)).string, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
}
|
||||
|
||||
@ -4387,7 +4387,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor
|
||||
], title: nil, text: self.presentationData.strings.PeerInfo_TooltipUnmuted, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
], title: nil, text: self.presentationData.strings.PeerInfo_TooltipUnmuted, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
} else if !isSoundEnabled {
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.PeerInfo_EnableSound, icon: { theme in
|
||||
@ -4400,7 +4400,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: strongSelf.chatLocation.threadId, sound: .default).start()
|
||||
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_sound_on", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipSoundEnabled, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_sound_on", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipSoundEnabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
} else {
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.PeerInfo_DisableSound, icon: { theme in
|
||||
@ -4413,7 +4413,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: strongSelf.chatLocation.threadId, sound: .none).start()
|
||||
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_sound_off", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipSoundDisabled, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_sound_off", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipSoundDisabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
}
|
||||
|
||||
@ -4488,7 +4488,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor
|
||||
], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
}
|
||||
})
|
||||
}, updatePeerDisplayPreviews: { peerId, displayPreviews in
|
||||
@ -4522,7 +4522,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor
|
||||
], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
|
||||
var tip: ContextController.Tip?
|
||||
@ -5375,7 +5375,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
let timeString = stringForPreciseRelativeTimestamp(strings: strongSelf.presentationData.strings, relativeTimestamp: Int32(Date().timeIntervalSince1970) + value, relativeTo: Int32(Date().timeIntervalSince1970), dateTimeFormat: strongSelf.presentationData.dateTimeFormat)
|
||||
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_mute_for", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedUntil(timeString).string, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_mute_for", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedUntil(timeString).string, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
}
|
||||
})
|
||||
self.controller?.view.endEditing(true)
|
||||
|
@ -41,7 +41,7 @@ public enum UndoOverlayContent {
|
||||
case inviteRequestSent(title: String, text: String)
|
||||
case image(image: UIImage, title: String?, text: String, round: Bool, undoText: String?)
|
||||
case notificationSoundAdded(title: String, text: String, action: (() -> Void)?)
|
||||
case universal(animation: String, scale: CGFloat, colors: [String: UIColor], title: String?, text: String, customUndoText: String?)
|
||||
case universal(animation: String, scale: CGFloat, colors: [String: UIColor], title: String?, text: String, customUndoText: String?, timeout: Double?)
|
||||
case peers(context: AccountContext, peers: [EnginePeer], title: String?, text: String, customUndoText: String?)
|
||||
}
|
||||
|
||||
|
@ -840,7 +840,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
case let .universal(animation, scale, colors, title, text, customUndoText):
|
||||
case let .universal(animation, scale, colors, title, text, customUndoText, timeout):
|
||||
self.avatarNode = nil
|
||||
self.iconNode = nil
|
||||
self.iconCheckNode = nil
|
||||
@ -865,7 +865,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
if text.contains("](") {
|
||||
isUserInteractionEnabled = true
|
||||
}
|
||||
self.originalRemainingSeconds = isUserInteractionEnabled ? 5 : 3
|
||||
self.originalRemainingSeconds = timeout ?? (isUserInteractionEnabled ? 5 : 3)
|
||||
|
||||
self.textNode.maximumNumberOfLines = 5
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user