diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 02f74c54cc..d79dde626e 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -10641,10 +10641,6 @@ Sorry for the inconvenience."; "Story.ViewList.TitleReactions" = "Reactions"; -"Wallpaper.ApplyForChannel" = "Apply For This Channel"; - -"Notification.ChannelChangedWallpaper" = "Channel set a new wallpaper"; - "Chat.Giveaway.Message.WinnersSelectedTitle.One" = "Winner Selected!"; "Chat.Giveaway.Message.WinnersSelectedTitle.Many" = "Winners Selected!"; "Chat.Giveaway.Message.WinnersSelectedText_1" = "**%@** winner of the [Giveaway]() was randomly selected by Telegram."; @@ -10751,3 +10747,15 @@ Sorry for the inconvenience."; "ChannelBoost.CustomWallpaper" = "Set Custom Channel Background"; "ChannelBoost.EnableCustomWallpaperLevelText" = "Your channel needs **Level %1$@** to set custom channel background."; + +"WallpaperPreview.ChannelHeader" = "All subscribers will see this wallpaper"; +"WallpaperPreview.ChannelTopText" = "Details to follow shortly.\nStay tuned!"; +"WallpaperPreview.ChannelReplyText" = "Breaking News"; + +"Wallpaper.ApplyForChannel" = "Apply Background"; +"Notification.ChannelChangedWallpaper" = "Channel set a new wallpaper"; + +"Story.MessageReposted.Personal" = "Message reposted to your stories."; +"Story.MessageReposted.Channel" = "Message reposted to **%@**."; + +"Story.Views.Commented" = " • commented"; diff --git a/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift b/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift index 39b3dc725a..2264a7a2b1 100644 --- a/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift +++ b/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift @@ -462,6 +462,11 @@ private final class ContextControllerActionsListActionItemNode: HighlightTrackin } else { minSize.width += sideInset } + if self.item.additionalLeftIcon != nil { + minSize.width += 24.0 + minSize.width += iconSideInset + minSize.width += iconSpacing + } if let forcedHeight { minSize.height = forcedHeight } else { diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyWallpaperPicker.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyWallpaperPicker.swift index a556175eea..38ab335d8c 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyWallpaperPicker.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyWallpaperPicker.swift @@ -2,10 +2,12 @@ import Foundation import UIKit import Display import SwiftSignalKit +import TelegramCore import LegacyComponents import TelegramPresentationData import DeviceAccess import AccountContext +import LocalMediaResources public func legacyWallpaperPicker(context: AccountContext, presentationData: PresentationData, subject: DeviceAccessMediaLibrarySubject = .wallpaper) -> Signal<(LegacyComponentsContext) -> TGMediaAssetsController, Void> { return Signal { subscriber in @@ -45,3 +47,76 @@ public func legacyWallpaperPicker(context: AccountContext, presentationData: Pre } } } + +public class LegacyWallpaperItem: NSObject, TGMediaEditableItem, TGMediaSelectableItem { + public var isVideo: Bool { + return false + } + + public var uniqueIdentifier: String! { + return self.asset.localIdentifier + } + + let asset: PHAsset + let screenImage: UIImage + private(set) var thumbnailResource: TelegramMediaResource? + private(set) var imageResource: TelegramMediaResource? + let dimensions: CGSize + + public init(asset: PHAsset, screenImage: UIImage, dimensions: CGSize) { + self.asset = asset + self.screenImage = screenImage + self.dimensions = dimensions + } + + public var originalSize: CGSize { + return self.dimensions + } + + public func thumbnailImageSignal() -> SSignal! { + return SSignal.complete() +// return SSignal(generator: { subscriber -> SDisposable? in +// let disposable = self.thumbnailImage.start(next: { image in +// subscriber.putNext(image) +// subscriber.putCompletion() +// }) +// +// return SBlockDisposable(block: { +// disposable.dispose() +// }) +// }) + } + + public func screenImageSignal(_ position: TimeInterval) -> SSignal! { + return SSignal.single(self.screenImage) + } + + public var originalImage: Signal { + return fetchPhotoLibraryImage(localIdentifier: self.asset.localIdentifier, thumbnail: false) + |> filter { value in + return !(value?.1 ?? true) + } + |> mapToSignal { result -> Signal in + if let result = result { + return .single(result.0) + } else { + return .complete() + } + } + } + + public func originalImageSignal(_ position: TimeInterval) -> SSignal! { + return SSignal(generator: { subscriber -> SDisposable? in + let disposable = self.originalImage.start(next: { image in + subscriber.putNext(image) + if !image.degraded() { + subscriber.putCompletion() + } + }) + + return SBlockDisposable(block: { + disposable.dispose() + }) + }) + } +} diff --git a/submodules/PremiumUI/Sources/PremiumBoostScreen.swift b/submodules/PremiumUI/Sources/PremiumBoostScreen.swift index 32d839a0a7..6a27077faf 100644 --- a/submodules/PremiumUI/Sources/PremiumBoostScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumBoostScreen.swift @@ -239,7 +239,7 @@ public func PremiumBoostScreen( let controller = context.sharedContext.makePremiumGiftController(context: context) pushController(controller) }), - TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Close, action: {}) + TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Close, action: {}) ], actionLayout: .vertical, parseMarkdown: true diff --git a/submodules/SettingsUI/BUILD b/submodules/SettingsUI/BUILD index 373ff7b42e..b54577ef6d 100644 --- a/submodules/SettingsUI/BUILD +++ b/submodules/SettingsUI/BUILD @@ -119,6 +119,8 @@ swift_library( "//submodules/TelegramUI/Components/Settings/QuickReactionSetupController", "//submodules/TelegramUI/Components/Settings/ThemeCarouselItem", "//submodules/TelegramUI/Components/Settings/ThemeSettingsThemeItem", + "//submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen", + "//submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode", ], visibility = [ "//visibility:public", diff --git a/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift b/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift index 821ea25b20..f908091732 100644 --- a/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift +++ b/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift @@ -12,6 +12,7 @@ import LegacyUI import LegacyMediaPickerUI import LocalMediaResources import ImageBlur +import WallpaperGalleryScreen func presentCustomWallpaperPicker(context: AccountContext, present: @escaping (ViewController) -> Void, push: @escaping (ViewController) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -318,77 +319,3 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa return croppedImage }).start() } - -class LegacyWallpaperItem: NSObject, TGMediaEditableItem, TGMediaSelectableItem { - var isVideo: Bool { - return false - } - - var uniqueIdentifier: String! { - return self.asset.localIdentifier - } - - let asset: PHAsset - let screenImage: UIImage - private(set) var thumbnailResource: TelegramMediaResource? - private(set) var imageResource: TelegramMediaResource? - let dimensions: CGSize - - - init(asset: PHAsset, screenImage: UIImage, dimensions: CGSize) { - self.asset = asset - self.screenImage = screenImage - self.dimensions = dimensions - } - - var originalSize: CGSize { - return self.dimensions - } - - func thumbnailImageSignal() -> SSignal! { - return SSignal.complete() -// return SSignal(generator: { subscriber -> SDisposable? in -// let disposable = self.thumbnailImage.start(next: { image in -// subscriber.putNext(image) -// subscriber.putCompletion() -// }) -// -// return SBlockDisposable(block: { -// disposable.dispose() -// }) -// }) - } - - func screenImageSignal(_ position: TimeInterval) -> SSignal! { - return SSignal.single(self.screenImage) - } - - var originalImage: Signal { - return fetchPhotoLibraryImage(localIdentifier: self.asset.localIdentifier, thumbnail: false) - |> filter { value in - return !(value?.1 ?? true) - } - |> mapToSignal { result -> Signal in - if let result = result { - return .single(result.0) - } else { - return .complete() - } - } - } - - func originalImageSignal(_ position: TimeInterval) -> SSignal! { - return SSignal(generator: { subscriber -> SDisposable? in - let disposable = self.originalImage.start(next: { image in - subscriber.putNext(image) - if !image.degraded() { - subscriber.putCompletion() - } - }) - - return SBlockDisposable(block: { - disposable.dispose() - }) - }) - } -} diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift index 2624de8dd2..f88868b1f0 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift @@ -10,6 +10,7 @@ import TelegramUIPreferences import AccountContext import PresentationDataUtils import MediaResources +import WallpaperGalleryScreen private let randomBackgroundColors: [Int32] = [0x007aff, 0x00c2ed, 0x29b327, 0xeb6ca4, 0xf08200, 0x9472ee, 0xd33213, 0xedb400, 0x6d839e] diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift index 59ab83e09a..a0f2bb1b76 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift @@ -14,6 +14,7 @@ import PresentationDataUtils import WallpaperBackgroundNode import AnimationCache import MultiAnimationRenderer +import WallpaperGalleryScreen private func generateMaskImage(color: UIColor) -> UIImage? { return generateImage(CGSize(width: 1.0, height: 80.0), opaque: false, rotatedContext: { size, context in diff --git a/submodules/SettingsUI/Sources/Themes/ThemeColorsGridController.swift b/submodules/SettingsUI/Sources/Themes/ThemeColorsGridController.swift index acce3f33a9..0e342ae9cb 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeColorsGridController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeColorsGridController.swift @@ -9,6 +9,7 @@ import TelegramPresentationData import TelegramUIPreferences import AccountContext import AttachmentUI +import WallpaperGalleryScreen private func availableGradients(dark: Bool) -> [[UInt32]] { if dark { diff --git a/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerItem.swift index aae0ab87c4..242cffb640 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerItem.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import AsyncDisplayKit import AccountContext import GridMessageSelectionNode +import SettingsThemeWallpaperNode final class ThemeColorsGridControllerItem: GridItem { let context: AccountContext diff --git a/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerNode.swift index 1b6ac7c121..9b4d211761 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeColorsGridControllerNode.swift @@ -9,6 +9,7 @@ import MergeLists import ItemListUI import PresentationDataUtils import AccountContext +import WallpaperGalleryScreen final class ThemeColorsGridControllerInteraction { let openWallpaper: (TelegramWallpaper) -> Void diff --git a/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift b/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift index 227edafcc9..b9f9dbdb53 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift @@ -15,6 +15,7 @@ import SearchUI import HexColor import PresentationDataUtils import MediaPickerUI +import WallpaperGalleryScreen public final class ThemeGridController: ViewController { private var controllerNode: ThemeGridControllerNode { diff --git a/submodules/SettingsUI/Sources/Themes/ThemeGridControllerItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeGridControllerItem.swift index 12117ce26c..1a6813b555 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeGridControllerItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeGridControllerItem.swift @@ -7,6 +7,7 @@ import AsyncDisplayKit import Postbox import AccountContext import GridMessageSelectionNode +import SettingsThemeWallpaperNode final class ThemeGridControllerItem: GridItem { let context: AccountContext diff --git a/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift index 7c69c681d9..ffb747354e 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift @@ -15,6 +15,7 @@ import AccountContext import SearchBarNode import SearchUI import WallpaperResources +import WallpaperGalleryScreen struct ThemeGridControllerNodeState: Equatable { var editing: Bool diff --git a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift index 168b3ca003..f1a854eb17 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift @@ -14,6 +14,7 @@ import LegacyComponents import WallpaperBackgroundNode import AnimationCache import MultiAnimationRenderer +import WallpaperGalleryScreen private func generateMaskImage(color: UIColor) -> UIImage? { return generateImage(CGSize(width: 1.0, height: 80.0), opaque: false, rotatedContext: { size, context in diff --git a/submodules/TelegramUI/BUILD b/submodules/TelegramUI/BUILD index d923db9fe6..58464c12c4 100644 --- a/submodules/TelegramUI/BUILD +++ b/submodules/TelegramUI/BUILD @@ -417,6 +417,7 @@ swift_library( "//submodules/TelegramUI/Components/Chat/ChatQrCodeScreen", "//submodules/UIKitRuntimeUtils", "//submodules/TelegramUI/Components/SavedMessages/SavedMessagesScreen", + "//submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen", ] + select({ "@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets, "//build-system:ios_sim_arm64": [], diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift index b5d9dec5a2..cc79946718 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift @@ -580,7 +580,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { var viewCount: Int? var dateReplies = 0 var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: associatedData.accountPeer, message: message) - if message.isRestricted(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) { + if message.isRestricted(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) || presentationData.isPreview { dateReactionsAndPeers = ([], []) } for attribute in message.attributes { diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index cfe0a75408..bb71033973 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -531,7 +531,6 @@ private final class PeerInfoInteraction { let performBotCommand: (PeerInfoBotCommand) -> Void let editingOpenPublicLinkSetup: () -> Void let editingOpenNameColorSetup: () -> Void - let editingOpenPeerWallpaperSetup: () -> Void let editingOpenInviteLinksSetup: () -> Void let editingOpenDiscussionGroupSetup: () -> Void let editingToggleMessageSignatures: (Bool) -> Void @@ -587,7 +586,6 @@ private final class PeerInfoInteraction { performBotCommand: @escaping (PeerInfoBotCommand) -> Void, editingOpenPublicLinkSetup: @escaping () -> Void, editingOpenNameColorSetup: @escaping () -> Void, - editingOpenPeerWallpaperSetup: @escaping () -> Void, editingOpenInviteLinksSetup: @escaping () -> Void, editingOpenDiscussionGroupSetup: @escaping () -> Void, editingToggleMessageSignatures: @escaping (Bool) -> Void, @@ -642,7 +640,6 @@ private final class PeerInfoInteraction { self.performBotCommand = performBotCommand self.editingOpenPublicLinkSetup = editingOpenPublicLinkSetup self.editingOpenNameColorSetup = editingOpenNameColorSetup - self.editingOpenPeerWallpaperSetup = editingOpenPeerWallpaperSetup self.editingOpenInviteLinksSetup = editingOpenInviteLinksSetup self.editingOpenDiscussionGroupSetup = editingOpenDiscussionGroupSetup self.editingToggleMessageSignatures = editingToggleMessageSignatures @@ -1581,7 +1578,6 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL case .broadcast: let ItemUsername = 1 let ItemPeerColor = 2 - let ItemPeerWallpaper = 3 let ItemInviteLinks = 4 let ItemDiscussionGroup = 5 let ItemSignMessages = 6 @@ -1683,10 +1679,6 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerColor, label: .image(colorImage, colorImage.size), additionalBadgeIcon: boostIcon, text: "Appearance", icon: UIImage(bundleImageName: "Chat/Info/NameColorIcon"), action: { interaction.editingOpenNameColorSetup() })) - - items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerWallpaper, label: .none, text: "Wallpaper", icon: UIImage(bundleImageName: "Settings/Menu/Appearance"), action: { - interaction.editingOpenPeerWallpaperSetup() - })) } if isCreator || (channel.adminRights != nil && channel.hasPermission(.sendSomething)) { @@ -2364,9 +2356,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro editingOpenNameColorSetup: { [weak self] in self?.editingOpenNameColorSetup() }, - editingOpenPeerWallpaperSetup: { [weak self] in - self?.editingOpenPeerWallpaperSetup() - }, editingOpenInviteLinksSetup: { [weak self] in self?.editingOpenInviteLinksSetup() }, @@ -7209,80 +7198,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro self.controller?.push(ChannelAppearanceScreen(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: self.peerId)) } } - - private func editingOpenPeerWallpaperSetup() { -// let link = status.url -// let controller = PremiumLimitScreen(context: context, subject: .storiesChannelBoost(peer: peer, boostSubject: .nameColors, isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, myBoostCount: 0, canBoostAgain: false), count: Int32(status.boosts), action: { -// UIPasteboard.general.string = link -// let presentationData = context.sharedContext.currentPresentationData.with { $0 } -// presentImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.ChannelBoost_BoostLinkCopied), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false })) -// return true -// }, openStats: nil, openGift: premiumConfiguration.giveawayGiftsPurchaseAvailable ? { -// let controller = createGiveawayController(context: context, peerId: peerId, subject: .generic) -// pushImpl?(controller) -// } : nil) -// pushImpl?(controller) - let dismissControllers = { [weak self] in - if let self, let navigationController = self.controller?.navigationController as? NavigationController { - let controllers = navigationController.viewControllers.filter({ controller in - if controller is WallpaperGalleryController || controller is AttachmentController || controller is PeerInfoScreenImpl { - return false - } - return true - }) - navigationController.setViewControllers(controllers, animated: true) - } - } - var openWallpaperPickerImpl: ((Bool) -> Void)? - let openWallpaperPicker: (Bool) -> Void = { [weak self] animateAppearance in - guard let self, let peer = self.data?.peer else { - return - } - let controller = wallpaperMediaPickerController( - context: self.context, - updatedPresentationData: self.controller?.updatedPresentationData, - peer: EnginePeer(peer), - animateAppearance: true, - completion: { [weak self] _, result in - guard let strongSelf = self, let asset = result as? PHAsset else { - return - } - let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset), mode: .peer(EnginePeer(peer), false)) - controller.navigationPresentation = .modal - controller.apply = { [weak self] wallpaper, options, editedImage, cropRect, brightness, forBoth in - if let strongSelf = self { - uploadCustomPeerWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, peerId: peer.id, forBoth: forBoth, completion: { - Queue.mainQueue().after(0.3, { - dismissControllers() - }) - }) - } - } - strongSelf.controller?.push(controller) - }, - openColors: { [weak self] in - guard let strongSelf = self else { - return - } - let controller = standaloneColorPickerController(context: strongSelf.context, peer: EnginePeer(peer), push: { [weak self] controller in - if let strongSelf = self { - strongSelf.controller?.push(controller) - } - }, openGallery: { - openWallpaperPickerImpl?(false) - }) - controller.navigationPresentation = .flatModal - strongSelf.controller?.push(controller) - } - ) - controller.navigationPresentation = .flatModal - self.controller?.push(controller) - } - openWallpaperPickerImpl = openWallpaperPicker - openWallpaperPicker(true) - } - private func editingOpenInviteLinksSetup() { self.controller?.push(inviteLinkListController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: self.peerId, admin: nil)) } diff --git a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/BUILD b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/BUILD index 778642e431..182be8d78c 100644 --- a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/BUILD +++ b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/BUILD @@ -43,6 +43,8 @@ swift_library( "//submodules/TelegramUI/Components/DynamicCornerRadiusView", "//submodules/Components/ComponentDisplayAdapters", "//submodules/WallpaperResources", + "//submodules/MediaPickerUI", + "//submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/ChannelAppearanceScreen.swift b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/ChannelAppearanceScreen.swift index d0ed3b3f60..ec052c8756 100644 --- a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/ChannelAppearanceScreen.swift +++ b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/ChannelAppearanceScreen.swift @@ -1,5 +1,6 @@ import Foundation import UIKit +import Photos import Display import AsyncDisplayKit import SwiftSignalKit @@ -29,6 +30,8 @@ import EmojiStatusComponent import DynamicCornerRadiusView import ComponentDisplayAdapters import WallpaperResources +import MediaPickerUI +import WallpaperGalleryScreen private final class EmojiActionIconComponent: Component { let context: AccountContext @@ -590,6 +593,58 @@ final class ChannelAppearanceScreenComponent: Component { self.environment?.controller()?.push(statsController) } + private func openCustomWallpaperSetup() { + guard let _ = self.component, let contentsData = self.contentsData else { + return + } +// let dismissControllers = { [weak self] in +// if let self, let navigationController = self.controller?.navigationController as? NavigationController { +// let controllers = navigationController.viewControllers.filter({ controller in +// if controller is WallpaperGalleryController || controller is AttachmentController || controller is PeerInfoScreenImpl { +// return false +// } +// return true +// }) +// navigationController.setViewControllers(controllers, animated: true) +// } +// } +// var openWallpaperPickerImpl: ((Bool) -> Void)? + let openWallpaperPicker: (Bool) -> Void = { [weak self] animateAppearance in + guard let self, let component = self.component, let peer = contentsData.peer else { + return + } + let controller = wallpaperMediaPickerController( + context: component.context, + updatedPresentationData: nil, + peer: peer, + animateAppearance: true, + completion: { [weak self] _, result in + guard let self, let component = self.component, let asset = result as? PHAsset else { + return + } + let controller = WallpaperGalleryController(context: component.context, source: .asset(asset), mode: .peer(peer, false)) + controller.navigationPresentation = .modal + controller.apply = { wallpaper, options, editedImage, cropRect, brightness, forBoth in +// if let strongSelf = self { +// uploadCustomPeerWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, peerId: peer.id, forBoth: forBoth, completion: { +// Queue.mainQueue().after(0.3, { +// dismissControllers() +// }) +// }) +// } + } + self.environment?.controller()?.push(controller) + }, + openColors: { + } + ) + controller.navigationPresentation = .flatModal + self.environment?.controller()?.push(controller) + } +// openWallpaperPickerImpl = openWallpaperPicker + openWallpaperPicker(true) + } + private enum EmojiSetupSubject { case reply case profile @@ -1055,7 +1110,7 @@ final class ChannelAppearanceScreenComponent: Component { guard let self else { return } - let _ = self + self.openCustomWallpaperSetup() } ))) ] diff --git a/submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode/BUILD b/submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode/BUILD new file mode 100644 index 0000000000..fcb10d3032 --- /dev/null +++ b/submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode/BUILD @@ -0,0 +1,27 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "SettingsThemeWallpaperNode", + module_name = "SettingsThemeWallpaperNode", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/Display", + "//submodules/AsyncDisplayKit", + "//submodules/SSignalKit/SwiftSignalKit", + "//submodules/Postbox", + "//submodules/TelegramCore", + "//submodules/TelegramPresentationData", + "//submodules/GradientBackground", + "//submodules/WallpaperResources", + "//submodules/AccountContext", + "//submodules/RadialStatusNode", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift b/submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode/Sources/SettingsThemeWallpaperNode.swift similarity index 95% rename from submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift rename to submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode/Sources/SettingsThemeWallpaperNode.swift index c2e0686023..b6916a0fe7 100644 --- a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift +++ b/submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode/Sources/SettingsThemeWallpaperNode.swift @@ -42,17 +42,17 @@ private let blackColorImage: UIImage? = { return context.generateImage() }() -final class SettingsThemeWallpaperNode: ASDisplayNode { - var wallpaper: TelegramWallpaper? +public final class SettingsThemeWallpaperNode: ASDisplayNode { + public var wallpaper: TelegramWallpaper? private var arguments: PatternWallpaperArguments? - let buttonNode = HighlightTrackingButtonNode() - let backgroundNode = ASImageNode() - let imageNode = TransformImageNode() + public let buttonNode = HighlightTrackingButtonNode() + public let backgroundNode = ASImageNode() + public let imageNode = TransformImageNode() private var gradientNode: GradientBackgroundNode? private let statusNode: RadialStatusNode - var pressed: (() -> Void)? + public var pressed: (() -> Void)? private let displayLoading: Bool private var isSelected: Bool = false @@ -60,7 +60,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { private let isLoadedDisposable = MetaDisposable() - init(displayLoading: Bool = false, overlayBackgroundColor: UIColor = UIColor(white: 0.0, alpha: 0.3)) { + public init(displayLoading: Bool = false, overlayBackgroundColor: UIColor = UIColor(white: 0.0, alpha: 0.3)) { self.displayLoading = displayLoading self.imageNode.contentAnimations = [.subsequentUpdates] @@ -83,7 +83,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { self.isLoadedDisposable.dispose() } - func setSelected(_ selected: Bool, animated: Bool = false) { + public func setSelected(_ selected: Bool, animated: Bool = false) { if self.isSelected != selected { self.isSelected = selected @@ -110,11 +110,11 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { } } - func setOverlayBackgroundColor(_ color: UIColor) { + public func setOverlayBackgroundColor(_ color: UIColor) { self.statusNode.backgroundNodeColor = color } - func setWallpaper(context: AccountContext, wallpaper: TelegramWallpaper, selected: Bool, size: CGSize, cornerRadius: CGFloat = 0.0, synchronousLoad: Bool = false) { + public func setWallpaper(context: AccountContext, wallpaper: TelegramWallpaper, selected: Bool, size: CGSize, cornerRadius: CGFloat = 0.0, synchronousLoad: Bool = false) { self.buttonNode.frame = CGRect(origin: CGPoint(), size: size) self.backgroundNode.frame = CGRect(origin: CGPoint(), size: size) self.imageNode.frame = CGRect(origin: CGPoint(), size: size) diff --git a/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/BUILD b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/BUILD new file mode 100644 index 0000000000..8fdf112188 --- /dev/null +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/BUILD @@ -0,0 +1,38 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "WallpaperGalleryScreen", + module_name = "WallpaperGalleryScreen", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/AsyncDisplayKit", + "//submodules/Display", + "//submodules/Postbox", + "//submodules/TelegramCore", + "//submodules/SSignalKit/SwiftSignalKit", + "//submodules/TelegramPresentationData", + "//submodules/AccountContext", + "//submodules/PresentationDataUtils", + "//submodules/WallpaperBackgroundNode", + "//submodules/ComponentFlow", + "//submodules/SolidRoundedButtonNode", + "//submodules/AppBundle", + "//submodules/PremiumUI", + "//submodules/WallpaperResources", + "//submodules/HexColor", + "//submodules/MergeLists", + "//submodules/ShareController", + "//submodules/GalleryUI", + "//submodules/CounterContollerTitleView", + "//submodules/LegacyMediaPickerUI", + "//submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/SettingsUI/Sources/BlurredImageNode.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/BlurredImageNode.swift similarity index 91% rename from submodules/SettingsUI/Sources/BlurredImageNode.swift rename to submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/BlurredImageNode.swift index e9f0b77b39..722ed4ffee 100644 --- a/submodules/SettingsUI/Sources/BlurredImageNode.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/BlurredImageNode.swift @@ -56,8 +56,8 @@ private class BlurLayer: CALayer { } } -class BlurView: UIView { - override class var layerClass : AnyClass { +public class BlurView: UIView { + public override class var layerClass : AnyClass { return BlurLayer.self } @@ -71,7 +71,7 @@ class BlurView: UIView { return Queue(name: nil, qos: .userInteractive) }() - open var blurRadius: CGFloat { + public var blurRadius: CGFloat { set { self.blurLayer.blurRadius = newValue } get { return self.blurLayer.blurRadius } } @@ -104,7 +104,7 @@ class BlurView: UIView { } } - override func display(_ layer: CALayer) { + public override func display(_ layer: CALayer) { let blurRadius = self.blurLayer.presentationRadius if let image = self.image { self.draw(image, blurRadius: blurRadius) @@ -112,19 +112,19 @@ class BlurView: UIView { } } -final class BlurredImageNode: ASDisplayNode { - var image: UIImage? { +public final class BlurredImageNode: ASDisplayNode { + public var image: UIImage? { didSet { self.blurView.image = self.image self.blurView.layer.setNeedsDisplay() } } - var blurView: BlurView { + public var blurView: BlurView { return (self.view as? BlurView)! } - override init() { + public override init() { super.init() self.setViewBlock({ diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperColorPanelNode.swift similarity index 94% rename from submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift rename to submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperColorPanelNode.swift index bc19dd7e5d..b4f8d02740 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperColorPanelNode.swift @@ -313,15 +313,26 @@ private class ColorInputFieldNode: ASDisplayNode, UITextFieldDelegate { } } -struct WallpaperColorPanelNodeState: Equatable { - var selection: Int? - var colors: [HSBColor] - var maximumNumberOfColors: Int - var rotateAvailable: Bool - var rotation: Int32 - var preview: Bool - var simpleGradientGeneration: Bool - var suggestedNewColor: HSBColor? +public struct WallpaperColorPanelNodeState: Equatable { + public var selection: Int? + public var colors: [HSBColor] + public var maximumNumberOfColors: Int + public var rotateAvailable: Bool + public var rotation: Int32 + public var preview: Bool + public var simpleGradientGeneration: Bool + public var suggestedNewColor: HSBColor? + + public init(selection: Int? = nil, colors: [HSBColor], maximumNumberOfColors: Int, rotateAvailable: Bool, rotation: Int32, preview: Bool, simpleGradientGeneration: Bool, suggestedNewColor: HSBColor? = nil) { + self.selection = selection + self.colors = colors + self.maximumNumberOfColors = maximumNumberOfColors + self.rotateAvailable = rotateAvailable + self.rotation = rotation + self.preview = preview + self.simpleGradientGeneration = simpleGradientGeneration + self.suggestedNewColor = suggestedNewColor + } } private final class ColorSampleItemNode: ASImageNode { @@ -377,7 +388,7 @@ private final class ColorSampleItemNode: ASImageNode { } } -final class WallpaperColorPanelNode: ASDisplayNode { +public final class WallpaperColorPanelNode: ASDisplayNode { private var theme: PresentationTheme private var state: WallpaperColorPanelNodeState @@ -394,16 +405,16 @@ final class WallpaperColorPanelNode: ASDisplayNode { private var sampleItemNodes: [ColorSampleItemNode] = [] private let multiColorFieldNode: ColorInputFieldNode - var colorsChanged: (([HSBColor], Int, Bool) -> Void)? - var colorSelected: (() -> Void)? - var rotate: (() -> Void)? + public var colorsChanged: (([HSBColor], Int, Bool) -> Void)? + public var colorSelected: (() -> Void)? + public var rotate: (() -> Void)? - var colorAdded: (() -> Void)? - var colorRemoved: (() -> Void)? + public var colorAdded: (() -> Void)? + public var colorRemoved: (() -> Void)? private var validLayout: (CGSize, CGFloat)? - init(theme: PresentationTheme, strings: PresentationStrings) { + public init(theme: PresentationTheme, strings: PresentationStrings) { self.theme = theme self.backgroundNode = NavigationBackgroundNode(color: theme.chat.inputPanel.panelBackgroundColor) @@ -512,7 +523,7 @@ final class WallpaperColorPanelNode: ASDisplayNode { } } - func updateTheme(_ theme: PresentationTheme) { + public func updateTheme(_ theme: PresentationTheme) { self.theme = theme self.backgroundNode.updateColor(color: self.theme.chat.inputPanel.panelBackgroundColor, transition: .immediate) self.topSeparatorNode.backgroundColor = self.theme.chat.inputPanel.panelSeparatorColor @@ -520,7 +531,7 @@ final class WallpaperColorPanelNode: ASDisplayNode { self.multiColorFieldNode.updateTheme(theme) } - func updateState(_ f: (WallpaperColorPanelNodeState) -> WallpaperColorPanelNodeState, updateLayout: Bool = true, animated: Bool = true) { + public func updateState(_ f: (WallpaperColorPanelNodeState) -> WallpaperColorPanelNodeState, updateLayout: Bool = true, animated: Bool = true) { var updateLayout = updateLayout let previousColors = self.state.colors let previousPreview = self.state.preview @@ -560,7 +571,7 @@ final class WallpaperColorPanelNode: ASDisplayNode { } } - func updateLayout(size: CGSize, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) { + public func updateLayout(size: CGSize, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) { self.validLayout = (size, bottomInset) let condensedLayout = size.width < 375.0 @@ -724,7 +735,7 @@ final class WallpaperColorPanelNode: ASDisplayNode { }) } - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if let result = super.hitTest(point, with: event) { return result } diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperColorPickerNode.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperColorPickerNode.swift similarity index 97% rename from submodules/SettingsUI/Sources/Themes/WallpaperColorPickerNode.swift rename to submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperColorPickerNode.swift index 50e51a2aef..ec5198f61f 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperColorPickerNode.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperColorPickerNode.swift @@ -266,50 +266,50 @@ private final class WallpaperColorBrightnessNode: ASDisplayNode { } } -struct HSBColor: Equatable { - static func == (lhs: HSBColor, rhs: HSBColor) -> Bool { +public struct HSBColor: Equatable { + public static func == (lhs: HSBColor, rhs: HSBColor) -> Bool { return lhs.values.h == rhs.values.h && lhs.values.s == rhs.values.s && lhs.values.b == rhs.values.b } - let values: (h: CGFloat, s: CGFloat, b: CGFloat) - let backingColor: UIColor + public let values: (h: CGFloat, s: CGFloat, b: CGFloat) + public let backingColor: UIColor - var hue: CGFloat { + public var hue: CGFloat { return self.values.h } - var saturation: CGFloat { + public var saturation: CGFloat { return self.values.s } - var brightness: CGFloat { + public var brightness: CGFloat { return self.values.b } - var rgb: UInt32 { + public var rgb: UInt32 { return self.color.argb } - init(values: (h: CGFloat, s: CGFloat, b: CGFloat)) { + public init(values: (h: CGFloat, s: CGFloat, b: CGFloat)) { self.values = values self.backingColor = UIColor(hue: values.h, saturation: values.s, brightness: values.b, alpha: 1.0) } - init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat) { + public init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat) { self.values = (h: hue, s: saturation, b: brightness) self.backingColor = UIColor(hue: self.values.h, saturation: self.values.s, brightness: self.values.b, alpha: 1.0) } - init(color: UIColor) { + public init(color: UIColor) { self.values = color.hsb self.backingColor = color } - init(rgb: UInt32) { + public init(rgb: UInt32) { self.init(color: UIColor(rgb: rgb)) } - var color: UIColor { + public var color: UIColor { return self.backingColor } } diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperCropNode.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperCropNode.swift similarity index 100% rename from submodules/SettingsUI/Sources/Themes/WallpaperCropNode.swift rename to submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperCropNode.swift diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryController.swift similarity index 99% rename from submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift rename to submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryController.swift index 15813a0268..47df37785d 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryController.swift @@ -401,7 +401,7 @@ public class WallpaperGalleryController: ViewController { self.colorsPanelNode?.updateTheme(self.presentationData.theme) } - func dismiss(forceAway: Bool) { + public func dismiss(forceAway: Bool) { // let completion: () -> Void = { [weak self] in // self?.presentingViewController?.dismiss(animated: false, completion: nil) // } diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryItem.swift similarity index 96% rename from submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift rename to submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryItem.swift index b3561b5e4e..5bd41a827d 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryItem.swift @@ -1370,7 +1370,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { let editFrame = CGRect(origin: CGPoint(x: layout.size.width - 16.0 - 28.0 + offset.x - 46.0, y: 16.0), size: CGSize(width: 28.0, height: 28.0)) let centerOffset: CGFloat = 32.0 - + if let entry = self.entry { switch entry { case .asset: @@ -1451,6 +1451,11 @@ final class WallpaperGalleryItemNode: GalleryItemNode { } } + if let mode = self.mode, case let .peer(peer, _) = mode, case .channel = peer { + motionAlpha = 0.0 + blurFrame = centerButtonFrame + } + transition.updateFrame(node: self.patternButtonNode, frame: patternFrame) transition.updateAlpha(node: self.patternButtonNode, alpha: patternAlpha * alpha) @@ -1487,13 +1492,29 @@ final class WallpaperGalleryItemNode: GalleryItemNode { } var items: [ListViewItem] = [] - let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)) + var peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)) let otherPeerId = self.context.account.peerId var peers = SimpleDictionary() - let messages = SimpleDictionary() - peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil) - peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil) + var messages = SimpleDictionary() + let replyAuthor = self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName + + var messageAuthor: Peer = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil) + let otherAuthor = TelegramUser(id: otherPeerId, accessHash: nil, firstName: replyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil) + peers[otherPeerId] = otherAuthor + + var messageAttributes: [MessageAttribute] = [] + if let mode = self.mode, case let .peer(peer, _) = mode, case .channel = peer { + peerId = peer.id + messageAuthor = peer._asPeer() + + let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3) + messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: messageAuthor, text: self.presentationData.strings.WallpaperPreview_ChannelReplyText, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:]) + messageAttributes = [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false)] + } + + peers[peerId] = messageAuthor + var topMessageText = "" var bottomMessageText = "" var serviceMessageText: String? @@ -1566,10 +1587,16 @@ final class WallpaperGalleryItemNode: GalleryItemNode { } if let mode = self.mode, case let .peer(peer, existing) = mode { - topMessageText = presentationData.strings.WallpaperPreview_ChatTopText - bottomMessageText = presentationData.strings.WallpaperPreview_ChatBottomText - if !existing { - serviceMessageText = presentationData.strings.WallpaperPreview_NotAppliedInfo(peer.compactDisplayTitle).string + if case .channel = peer { + topMessageText = presentationData.strings.WallpaperPreview_ChannelTopText + bottomMessageText = "" + serviceMessageText = presentationData.strings.WallpaperPreview_ChannelHeader + } else { + topMessageText = presentationData.strings.WallpaperPreview_ChatTopText + bottomMessageText = presentationData.strings.WallpaperPreview_ChatBottomText + if !existing { + serviceMessageText = presentationData.strings.WallpaperPreview_NotAppliedInfo(peer.compactDisplayTitle).string + } } } @@ -1579,10 +1606,13 @@ final class WallpaperGalleryItemNode: GalleryItemNode { let theme = self.presentationData.theme - let message1 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: bottomMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:]) - items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message1], theme: theme, strings: self.presentationData.strings, wallpaper: currentWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.nativeNode, availableReactions: nil, accountPeer: nil, isCentered: false)) + if !bottomMessageText.isEmpty { + let message1 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: bottomMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:]) + items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message1], theme: theme, strings: self.presentationData.strings, wallpaper: currentWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.nativeNode, availableReactions: nil, accountPeer: nil, isCentered: false)) + } + - let message2 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: topMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:]) + let message2 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: topMessageText, attributes: messageAttributes, media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:]) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message2], theme: theme, strings: self.presentationData.strings, wallpaper: currentWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.nativeNode, availableReactions: nil, accountPeer: nil, isCentered: false)) if let serviceMessageText { diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryToolbarNode.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryToolbarNode.swift similarity index 91% rename from submodules/SettingsUI/Sources/Themes/WallpaperGalleryToolbarNode.swift rename to submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryToolbarNode.swift index 851d9e7198..268b1abd5c 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryToolbarNode.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryToolbarNode.swift @@ -5,12 +5,12 @@ import Display import TelegramPresentationData import ManagedAnimationNode -enum WallpaperGalleryToolbarCancelButtonType { +public enum WallpaperGalleryToolbarCancelButtonType { case cancel case discard } -enum WallpaperGalleryToolbarDoneButtonType { +public enum WallpaperGalleryToolbarDoneButtonType { case set case setPeer(String, Bool) case setChannel @@ -19,7 +19,7 @@ enum WallpaperGalleryToolbarDoneButtonType { case none } -protocol WallpaperGalleryToolbar: ASDisplayNode { +public protocol WallpaperGalleryToolbar: ASDisplayNode { var cancelButtonType: WallpaperGalleryToolbarCancelButtonType { get set } var doneButtonType: WallpaperGalleryToolbarDoneButtonType { get set } @@ -31,7 +31,7 @@ protocol WallpaperGalleryToolbar: ASDisplayNode { func updateLayout(size: CGSize, layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) } -final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar { +public final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar { class ButtonNode: ASDisplayNode { private let doneButton = HighlightTrackingButtonNode() private var doneButtonBackgroundNode: ASDisplayNode @@ -205,18 +205,18 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar private var theme: PresentationTheme private let strings: PresentationStrings - var cancelButtonType: WallpaperGalleryToolbarCancelButtonType { + public var cancelButtonType: WallpaperGalleryToolbarCancelButtonType { didSet { self.updateThemeAndStrings(theme: self.theme, strings: self.strings) } } - var doneButtonType: WallpaperGalleryToolbarDoneButtonType { + public var doneButtonType: WallpaperGalleryToolbarDoneButtonType { didSet { self.updateThemeAndStrings(theme: self.theme, strings: self.strings) } } - var dark: Bool = false { + public var dark: Bool = false { didSet { self.applyButton.dark = self.dark self.applyForBothButton.dark = self.dark @@ -226,10 +226,10 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar private let applyButton = ButtonNode() private let applyForBothButton = ButtonNode() - var cancel: (() -> Void)? - var done: ((Bool) -> Void)? + public var cancel: (() -> Void)? + public var done: ((Bool) -> Void)? - init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) { + public init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) { self.theme = theme self.strings = strings self.cancelButtonType = cancelButtonType @@ -256,13 +256,13 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar } } - func setDoneEnabled(_ enabled: Bool) { + public func setDoneEnabled(_ enabled: Bool) { self.applyButton.setEnabled(enabled) self.applyForBothButton.setEnabled(enabled) } private var isSolid = false - func setDoneIsSolid(_ isSolid: Bool, transition: ContainedViewLayoutTransition) { + public func setDoneIsSolid(_ isSolid: Bool, transition: ContainedViewLayoutTransition) { guard self.isSolid != isSolid else { return } @@ -272,7 +272,7 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar self.applyForBothButton.setIsSolid(isSolid, transition: transition) } - func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) { + public func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) { self.theme = theme let applyTitle: String @@ -303,7 +303,7 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar self.applyForBothButton.isLocked = applyForBothLocked } - func updateLayout(size: CGSize, layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { + public func updateLayout(size: CGSize, layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { let inset: CGFloat = 16.0 let buttonHeight: CGFloat = 50.0 @@ -329,16 +329,16 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar } } -final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolbar { +public final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolbar { private var theme: PresentationTheme private let strings: PresentationStrings - var cancelButtonType: WallpaperGalleryToolbarCancelButtonType { + public var cancelButtonType: WallpaperGalleryToolbarCancelButtonType { didSet { self.updateThemeAndStrings(theme: self.theme, strings: self.strings) } } - var doneButtonType: WallpaperGalleryToolbarDoneButtonType { + public var doneButtonType: WallpaperGalleryToolbarDoneButtonType { didSet { self.updateThemeAndStrings(theme: self.theme, strings: self.strings) } @@ -352,10 +352,10 @@ final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolb private let separatorNode = ASDisplayNode() private let topSeparatorNode = ASDisplayNode() - var cancel: (() -> Void)? - var done: ((Bool) -> Void)? + public var cancel: (() -> Void)? + public var done: ((Bool) -> Void)? - init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) { + public init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) { self.theme = theme self.strings = strings self.cancelButtonType = cancelButtonType @@ -404,12 +404,12 @@ final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolb self.doneButton.addTarget(self, action: #selector(self.donePressed), forControlEvents: .touchUpInside) } - func setDoneEnabled(_ enabled: Bool) { + public func setDoneEnabled(_ enabled: Bool) { self.doneButton.alpha = enabled ? 1.0 : 0.4 self.doneButton.isUserInteractionEnabled = enabled } - func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) { + public func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) { self.theme = theme self.backgroundNode.updateColor(color: theme.rootController.tabBar.backgroundColor, transition: .immediate) self.separatorNode.backgroundColor = theme.rootController.tabBar.separatorColor @@ -440,7 +440,7 @@ final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolb self.doneButton.setTitle(doneTitle, with: Font.regular(17.0), with: theme.list.itemPrimaryTextColor, for: []) } - func updateLayout(size: CGSize, layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { + public func updateLayout(size: CGSize, layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { self.cancelButton.frame = CGRect(origin: CGPoint(), size: CGSize(width: floor(size.width / 2.0), height: size.height)) self.cancelHighlightBackgroundNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: floor(size.width / 2.0), height: size.height)) self.doneButton.frame = CGRect(origin: CGPoint(x: floor(size.width / 2.0), y: 0.0), size: CGSize(width: size.width - floor(size.width / 2.0), height: size.height)) diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperOptionButtonNode.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperOptionButtonNode.swift similarity index 97% rename from submodules/SettingsUI/Sources/Themes/WallpaperOptionButtonNode.swift rename to submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperOptionButtonNode.swift index 281dc08339..4129277be3 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperOptionButtonNode.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperOptionButtonNode.swift @@ -6,7 +6,7 @@ import SwiftSignalKit import CheckNode import AnimationUI -enum WallpaperOptionButtonValue { +public enum WallpaperOptionButtonValue { case check(Bool) case color(Bool, UIColor) case colors(Bool, [UIColor]) @@ -270,7 +270,7 @@ final class WallpaperNavigationButtonNode: HighlightTrackingButtonNode { } -final class WallpaperOptionButtonNode: HighlightTrackingButtonNode { +public final class WallpaperOptionButtonNode: HighlightTrackingButtonNode { let backgroundNode: WallpaperOptionBackgroundNode private let checkNode: CheckNode @@ -281,7 +281,7 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode { private var textSize: CGSize? private var _value: WallpaperOptionButtonValue - override var isSelected: Bool { + public override var isSelected: Bool { get { switch self._value { case let .check(selected), let .color(selected, _), let .colors(selected, _): @@ -301,13 +301,13 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode { } } - var title: String { + public var title: String { didSet { self.textNode.attributedText = NSAttributedString(string: title, font: Font.medium(13), textColor: .white) } } - init(title: String, value: WallpaperOptionButtonValue) { + public init(title: String, value: WallpaperOptionButtonValue) { self._value = value self.title = title @@ -368,12 +368,12 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode { } } - var buttonColor: UIColor = UIColor(rgb: 0x000000, alpha: 0.3) { + public var buttonColor: UIColor = UIColor(rgb: 0x000000, alpha: 0.3) { didSet { } } - var color: UIColor? { + public var color: UIColor? { get { switch self._value { case let .color(_, color): @@ -395,7 +395,7 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode { } } - var colors: [UIColor]? { + public var colors: [UIColor]? { get { switch self._value { case let .colors(_, colors): @@ -429,7 +429,7 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode { } } - func setSelected(_ selected: Bool, animated: Bool = false) { + public func setSelected(_ selected: Bool, animated: Bool = false) { switch self._value { case .check: self._value = .check(selected) @@ -441,7 +441,7 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode { self.checkNode.setSelected(selected, animated: animated) } - func setEnabled(_ enabled: Bool) { + public func setEnabled(_ enabled: Bool) { let alpha: CGFloat = enabled ? 1.0 : 0.4 self.checkNode.alpha = alpha self.colorNode.alpha = alpha @@ -449,13 +449,13 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode { self.isUserInteractionEnabled = enabled } - override func measure(_ constrainedSize: CGSize) -> CGSize { + public override func measure(_ constrainedSize: CGSize) -> CGSize { let size = self.textNode.updateLayout(constrainedSize) self.textSize = size return CGSize(width: ceil(size.width) + 48.0, height: 30.0) } - override func layout() { + public override func layout() { super.layout() self.backgroundNode.frame = self.bounds diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift similarity index 96% rename from submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift rename to submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift index c4be43adef..508c0bb11b 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift @@ -9,6 +9,7 @@ import LegacyComponents import AccountContext import MergeLists import Postbox +import SettingsThemeWallpaperNode private let itemSize = CGSize(width: 88.0, height: 88.0) private let inset: CGFloat = 12.0 @@ -172,24 +173,24 @@ private final class WallpaperPatternItemNode : ListViewItemNode { } } -final class WallpaperPatternPanelNode: ASDisplayNode { +public final class WallpaperPatternPanelNode: ASDisplayNode { private let context: AccountContext private var theme: PresentationTheme private let backgroundNode: NavigationBackgroundNode private let topSeparatorNode: ASDisplayNode - let scrollNode: ASScrollNode + public let scrollNode: ASScrollNode private let titleNode: ImmediateTextNode private let labelNode: ImmediateTextNode private var sliderView: TGPhotoEditorSliderView? private var disposable: Disposable? - var wallpapers: [TelegramWallpaper] = [] + public var wallpapers: [TelegramWallpaper] = [] private var currentWallpaper: TelegramWallpaper? - var serviceBackgroundColor: UIColor = UIColor(rgb: 0x748698) { + public var serviceBackgroundColor: UIColor = UIColor(rgb: 0x748698) { didSet { guard let nodes = self.scrollNode.subnodes else { return @@ -200,7 +201,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode { } } - var backgroundColors: ([HSBColor], Int32?, Int32?)? = nil { + public var backgroundColors: ([HSBColor], Int32?, Int32?)? = nil { didSet { var updated = false if oldValue?.0 != self.backgroundColors?.0 || oldValue?.1 != self.backgroundColors?.1 { @@ -223,11 +224,11 @@ final class WallpaperPatternPanelNode: ASDisplayNode { private var validLayout: (CGSize, CGFloat)? - var patternChanged: ((TelegramWallpaper?, Int32?, Bool) -> Void)? + public var patternChanged: ((TelegramWallpaper?, Int32?, Bool) -> Void)? private let allowDark: Bool - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + public init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { self.context = context self.theme = theme self.allowDark = theme.overallDarkAppearance @@ -287,7 +288,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode { self.disposable?.dispose() } - override func didLoad() { + public override func didLoad() { super.didLoad() self.scrollNode.view.showsHorizontalScrollIndicator = false @@ -320,7 +321,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode { self.sliderView = sliderView } - func updateWallpapers() { + public func updateWallpapers() { guard let subnodes = self.scrollNode.subnodes else { return } @@ -386,7 +387,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode { self.layoutItemNodes(transition: .immediate) } - func updateTheme(_ theme: PresentationTheme) { + public func updateTheme(_ theme: PresentationTheme) { self.theme = theme self.backgroundNode.updateColor(color: self.theme.chat.inputPanel.panelBackgroundColor, transition: .immediate) @@ -416,7 +417,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode { } } - func didAppear(initialWallpaper: TelegramWallpaper? = nil, intensity: Int32? = nil) { + public func didAppear(initialWallpaper: TelegramWallpaper? = nil, intensity: Int32? = nil) { let wallpaper: TelegramWallpaper? if self.wallpapers.isEmpty { @@ -482,7 +483,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode { } } - func updateLayout(size: CGSize, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) { + public func updateLayout(size: CGSize, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) { self.validLayout = (size, bottomInset) let backgroundFrame = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height + bottomInset) diff --git a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift index 8a4af47593..2883eb6582 100644 --- a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift +++ b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift @@ -2578,119 +2578,123 @@ final class ShareWithPeersScreenComponent: Component { } } - let presentAlert: ([String]) -> Void = { usernames in - let usernamesString = String(usernames.map { "@\($0)" }.joined(separator: ", ")) - let alertController = textAlertController( - context: component.context, - forceTheme: defaultDarkColorPresentationTheme, - title: environment.strings.Story_Privacy_MentionRestrictedTitle, - text: environment.strings.Story_Privacy_MentionRestrictedText(usernamesString).string, - actions: [ - TextAlertAction(type: .defaultAction, title: environment.strings.Story_Privacy_MentionRestrictedProceed, action: { - proceed() - }), - TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {}) - ], - actionLayout: .vertical - ) - controller.present(alertController, in: .window(.root)) - } - - func matchingUsername(user: TelegramUser, usernames: Set) -> String? { - for username in user.usernames { - if usernames.contains(username.username) { - return username.username - } + if let sendAsPeerId = self.sendAsPeerId, sendAsPeerId.isGroupOrChannel { + proceed() + } else { + let presentAlert: ([String]) -> Void = { usernames in + let usernamesString = String(usernames.map { "@\($0)" }.joined(separator: ", ")) + let alertController = textAlertController( + context: component.context, + forceTheme: defaultDarkColorPresentationTheme, + title: environment.strings.Story_Privacy_MentionRestrictedTitle, + text: environment.strings.Story_Privacy_MentionRestrictedText(usernamesString).string, + actions: [ + TextAlertAction(type: .defaultAction, title: environment.strings.Story_Privacy_MentionRestrictedProceed, action: { + proceed() + }), + TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {}) + ], + actionLayout: .vertical + ) + controller.present(alertController, in: .window(.root)) } - if let username = user.username { - if usernames.contains(username) { - return username + + func matchingUsername(user: TelegramUser, usernames: Set) -> String? { + for username in user.usernames { + if usernames.contains(username.username) { + return username.username + } } + if let username = user.username { + if usernames.contains(username) { + return username + } + } + return nil } - return nil - } - - let context = component.context - let selectedPeerIds = self.selectedPeers - - if case .stories = component.stateContext.subject { - if component.mentions.isEmpty { - proceed() - } else if case .nobody = base { - if selectedPeerIds.isEmpty { - presentAlert(component.mentions) - } else { - let _ = (context.account.postbox.transaction { transaction in - var filteredMentions = Set(component.mentions) - for peerId in selectedPeerIds { - if let peer = transaction.getPeer(peerId) { - if let user = peer as? TelegramUser { - if let username = matchingUsername(user: user, usernames: filteredMentions) { - filteredMentions.remove(username) - } - } else { - if let username = peer.addressName { - filteredMentions.remove(username) + + let context = component.context + let selectedPeerIds = self.selectedPeers + + if case .stories = component.stateContext.subject { + if component.mentions.isEmpty { + proceed() + } else if case .nobody = base { + if selectedPeerIds.isEmpty { + presentAlert(component.mentions) + } else { + let _ = (context.account.postbox.transaction { transaction in + var filteredMentions = Set(component.mentions) + for peerId in selectedPeerIds { + if let peer = transaction.getPeer(peerId) { + if let user = peer as? TelegramUser { + if let username = matchingUsername(user: user, usernames: filteredMentions) { + filteredMentions.remove(username) + } + } else { + if let username = peer.addressName { + filteredMentions.remove(username) + } } } } + return Array(filteredMentions) + } + |> deliverOnMainQueue).start(next: { mentions in + if mentions.isEmpty { + proceed() + } else { + presentAlert(mentions) + } + }) + } + } else if case .contacts = base { + let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: false)) + |> map { contacts -> [String] in + var filteredMentions = Set(component.mentions) + let peers = contacts.peers + for peer in peers { + if selectedPeerIds.contains(peer.id) { + continue + } + if case let .user(user) = peer, let username = matchingUsername(user: user, usernames: filteredMentions) { + filteredMentions.remove(username) + } } return Array(filteredMentions) } - |> deliverOnMainQueue).start(next: { mentions in + |> deliverOnMainQueue).start(next: { mentions in if mentions.isEmpty { proceed() } else { presentAlert(mentions) } }) - } - } else if case .contacts = base { - let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: false)) - |> map { contacts -> [String] in - var filteredMentions = Set(component.mentions) - let peers = contacts.peers - for peer in peers { - if selectedPeerIds.contains(peer.id) { - continue + } else if case .closeFriends = base { + let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: false)) + |> map { contacts -> [String] in + var filteredMentions = Set(component.mentions) + let peers = contacts.peers + for peer in peers { + if case let .user(user) = peer, user.flags.contains(.isCloseFriend), let username = matchingUsername(user: user, usernames: filteredMentions) { + filteredMentions.remove(username) + } } - if case let .user(user) = peer, let username = matchingUsername(user: user, usernames: filteredMentions) { - filteredMentions.remove(username) + return Array(filteredMentions) + } + |> deliverOnMainQueue).start(next: { mentions in + if mentions.isEmpty { + proceed() + } else { + presentAlert(mentions) } - } - return Array(filteredMentions) + }) + } else { + proceed() } - |> deliverOnMainQueue).start(next: { mentions in - if mentions.isEmpty { - proceed() - } else { - presentAlert(mentions) - } - }) - } else if case .closeFriends = base { - let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: false)) - |> map { contacts -> [String] in - var filteredMentions = Set(component.mentions) - let peers = contacts.peers - for peer in peers { - if case let .user(user) = peer, user.flags.contains(.isCloseFriend), let username = matchingUsername(user: user, usernames: filteredMentions) { - filteredMentions.remove(username) - } - } - return Array(filteredMentions) - } - |> deliverOnMainQueue).start(next: { mentions in - if mentions.isEmpty { - proceed() - } else { - presentAlert(mentions) - } - }) } else { proceed() } - } else { - proceed() } } )), diff --git a/submodules/TelegramUI/Components/Stories/ForwardInfoPanelComponent/Sources/ForwardInfoPanelComponent.swift b/submodules/TelegramUI/Components/Stories/ForwardInfoPanelComponent/Sources/ForwardInfoPanelComponent.swift index 922c35d720..c1f065c7f1 100644 --- a/submodules/TelegramUI/Components/Stories/ForwardInfoPanelComponent/Sources/ForwardInfoPanelComponent.swift +++ b/submodules/TelegramUI/Components/Stories/ForwardInfoPanelComponent/Sources/ForwardInfoPanelComponent.swift @@ -96,6 +96,7 @@ public final class ForwardInfoPanelComponent: Component { iconView.alpha = 0.55 iconView.tintColor = .white self.addSubview(iconView) + self.iconView = iconView } if let image = iconView.image { iconView.frame = CGRect(origin: CGPoint(x: sideInset + UIScreenPixel, y: 5.0), size: image.size) diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift index f023035b61..130f03e06c 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryChatContent.swift @@ -112,6 +112,10 @@ public final class StoryContentContextImpl: StoryContentContext { } } } + } else if case let .channelMessage(_, messageId) = mediaArea { + if let peer = transaction.getPeer(messageId.peerId) { + peers[peer.id] = peer + } } } } @@ -216,6 +220,17 @@ public final class StoryContentContextImpl: StoryContentContext { guard let media = item.media else { return nil } + + var forwardInfo = item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, peers: peers) } + if forwardInfo == nil { + for mediaArea in item.mediaAreas { + if case let .channelMessage(_, messageId) = mediaArea, let peer = peers[messageId.peerId] { + forwardInfo = .known(peer: EnginePeer(peer), storyId: 0, isModified: false) + break + } + } + } + return EngineStoryItem( id: item.id, timestamp: item.timestamp, @@ -248,7 +263,7 @@ public final class StoryContentContextImpl: StoryContentContext { isEdited: item.isEdited, isMy: item.isMy, myReaction: item.myReaction, - forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, peers: peers) } + forwardInfo: forwardInfo ) } var totalCount = peerStoryItemsView.items.count @@ -1131,6 +1146,10 @@ public final class SingleStoryContentContextImpl: StoryContentContext { } } } + } else if case let .channelMessage(_, messageId) = mediaArea { + if let peer = transaction.getPeer(messageId.peerId) { + peers[peer.id] = peer + } } } } @@ -1186,6 +1205,16 @@ public final class SingleStoryContentContextImpl: StoryContentContext { } if let item, case let .item(itemValue) = item, let media = itemValue.media { + var forwardInfo = itemValue.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, peers: peers) } + if forwardInfo == nil { + for mediaArea in itemValue.mediaAreas { + if case let .channelMessage(_, messageId) = mediaArea, let peer = peers[messageId.peerId] { + forwardInfo = .known(peer: EnginePeer(peer), storyId: 0, isModified: false) + break + } + } + } + let mappedItem = EngineStoryItem( id: itemValue.id, timestamp: itemValue.timestamp, @@ -1218,7 +1247,7 @@ public final class SingleStoryContentContextImpl: StoryContentContext { isEdited: itemValue.isEdited, isMy: itemValue.isMy, myReaction: itemValue.myReaction, - forwardInfo: itemValue.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, peers: peers) } + forwardInfo: forwardInfo ) let mainItem = StoryContentItem( @@ -2073,13 +2102,22 @@ public final class RepostStoriesContentContextImpl: StoryContentContext { private var currentForwardInfoStories: [StoryId: Promise] = [:] - init(context: AccountContext, peerId: EnginePeer.Id, focusedId initialFocusedId: Int32?, items: [EngineStoryItem]) { + init( + context: AccountContext, + originalPeerId: EnginePeer.Id, + originalStory: EngineStoryItem, + peerId: EnginePeer.Id, + focusedId initialFocusedId: Int32?, + items: [EngineStoryItem] + ) { self.context = context self.peerId = peerId self.currentFocusedId = initialFocusedId self.currentFocusedIdUpdatedPromise.set(.single(Void())) + let originalStoryId = StoryId(peerId: originalPeerId, id: originalStory.id) + let inputKeys: [PostboxViewKey] = [ PostboxViewKey.basicPeer(peerId), PostboxViewKey.cachedPeerData(peerId: peerId), @@ -2098,53 +2136,43 @@ public final class RepostStoriesContentContextImpl: StoryContentContext { var forwardInfoStories: [StoryId: EngineStoryItem?] = [:] var allEntityFiles: [MediaId: TelegramMediaFile] = [:] - if let itemsView = views.views[PostboxViewKey.storyItems(peerId: peerId)] as? StoryItemsView { - for item in itemsView.items { - if let item = item.value.get(Stories.StoredItem.self), case let .item(itemValue) = item { - if let views = itemValue.views { - for peerId in views.seenPeerIds { - if let peer = transaction.getPeer(peerId) { - peers[peer.id] = peer - } - } - } - if let forwardInfo = itemValue.forwardInfo, case let .known(peerId, id, _) = forwardInfo { - if let peer = transaction.getPeer(peerId) { - peers[peer.id] = peer - } - let storyId = StoryId(peerId: peerId, id: id) - if let story = getCachedStory(storyId: storyId, transaction: transaction) { - forwardInfoStories[storyId] = story - } else { - forwardInfoStories.updateValue(nil, forKey: storyId) - } - } - for entity in itemValue.entities { - if case let .CustomEmoji(_, fileId) = entity.type { - let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId) - if allEntityFiles[mediaId] == nil { - if let file = transaction.getMedia(mediaId) as? TelegramMediaFile { - allEntityFiles[file.fileId] = file - } - } - } - } - for mediaArea in itemValue.mediaAreas { - if case let .reaction(_, reaction, _) = mediaArea { - if case let .custom(fileId) = reaction { - let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId) - if allEntityFiles[mediaId] == nil { - if let file = transaction.getMedia(mediaId) as? TelegramMediaFile { - allEntityFiles[file.fileId] = file - } - } - } + for item in items { + if let forwardInfo = item.forwardInfo, case let .known(peer, id, _) = forwardInfo { + let storyId = StoryId(peerId: peer.id, id: id) + if storyId == originalStoryId { + forwardInfoStories[storyId] = originalStory + } else { + forwardInfoStories.updateValue(nil, forKey: storyId) + } + } + for entity in item.entities { + if case let .CustomEmoji(_, fileId) = entity.type { + let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId) + if allEntityFiles[mediaId] == nil { + if let file = transaction.getMedia(mediaId) as? TelegramMediaFile { + allEntityFiles[file.fileId] = file } } } } + for mediaArea in item.mediaAreas { + if case let .reaction(_, reaction, _) = mediaArea { + if case let .custom(fileId) = reaction { + let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId) + if allEntityFiles[mediaId] == nil { + if let file = transaction.getMedia(mediaId) as? TelegramMediaFile { + allEntityFiles[file.fileId] = file + } + } + } + } else if case let .channelMessage(_, messageId) = mediaArea { + if let peer = transaction.getPeer(messageId.peerId) { + peers[peer.id] = peer + } + } + } } - + return (views, peers, globalNotificationSettings, allEntityFiles, forwardInfoStories) } } @@ -2163,7 +2191,6 @@ public final class RepostStoriesContentContextImpl: StoryContentContext { if let presencesView = views.views[PostboxViewKey.peerPresences(peerIds: Set([peerId]))] as? PeerPresencesView { peerPresence = presencesView.presences[peerId] } - for (storyId, story) in forwardInfoStories { let promise: Promise var added = false @@ -2174,7 +2201,9 @@ public final class RepostStoriesContentContextImpl: StoryContentContext { self.currentForwardInfoStories[storyId] = promise added = true } - if let story { + if storyId == originalStoryId { + promise.set(.single(originalStory)) + } else if let story { promise.set(.single(story)) } else if added { promise.set(self.context.engine.messages.getStory(peerId: storyId.peerId, id: storyId.id)) @@ -2274,7 +2303,6 @@ public final class RepostStoriesContentContextImpl: StoryContentContext { let mappedFocusedIndex = mappedItems.firstIndex(where: { $0.id == mappedItems[focusedIndex].id }) - do { let mappedItem = mappedItems[focusedIndex] @@ -2416,6 +2444,8 @@ public final class RepostStoriesContentContextImpl: StoryContentContext { } private let context: AccountContext + private let originalPeerId: EnginePeer.Id + private let originalStory: EngineStoryItem private let viewListContext: EngineStoryViewListContext private let readGlobally: Bool @@ -2449,11 +2479,15 @@ public final class RepostStoriesContentContextImpl: StoryContentContext { public init( context: AccountContext, + originalPeerId: EnginePeer.Id, + originalStory: EngineStoryItem, focusedStoryId: StoryId, viewListContext: EngineStoryViewListContext, readGlobally: Bool ) { self.context = context + self.originalPeerId = originalPeerId + self.originalStory = originalStory self.focusedItem = (focusedStoryId.peerId, focusedStoryId.id) self.viewListContext = viewListContext self.readGlobally = readGlobally @@ -2530,7 +2564,7 @@ public final class RepostStoriesContentContextImpl: StoryContentContext { if let currentState = self.currentState, let existingContext = currentState.findPeerContext(id: currentStoryItems[centralIndex].peer.id) { centralPeerContext = existingContext } else { - centralPeerContext = PeerContext(context: self.context, peerId: currentStoryItems[centralIndex].peer.id, focusedId: nil, items: [currentStoryItems[centralIndex].story]) + centralPeerContext = PeerContext(context: self.context, originalPeerId: self.originalPeerId, originalStory: self.originalStory, peerId: currentStoryItems[centralIndex].peer.id, focusedId: nil, items: [currentStoryItems[centralIndex].story]) } var previousPeerContext: PeerContext? @@ -2538,7 +2572,7 @@ public final class RepostStoriesContentContextImpl: StoryContentContext { if let currentState = self.currentState, let existingContext = currentState.findPeerContext(id: currentStoryItems[centralIndex - 1].peer.id) { previousPeerContext = existingContext } else { - previousPeerContext = PeerContext(context: self.context, peerId: currentStoryItems[centralIndex - 1].peer.id, focusedId: nil, items: [currentStoryItems[centralIndex - 1].story]) + previousPeerContext = PeerContext(context: self.context, originalPeerId: self.originalPeerId, originalStory: self.originalStory, peerId: currentStoryItems[centralIndex - 1].peer.id, focusedId: nil, items: [currentStoryItems[centralIndex - 1].story]) } } @@ -2547,7 +2581,7 @@ public final class RepostStoriesContentContextImpl: StoryContentContext { if let currentState = self.currentState, let existingContext = currentState.findPeerContext(id: currentStoryItems[centralIndex + 1].peer.id) { nextPeerContext = existingContext } else { - nextPeerContext = PeerContext(context: self.context, peerId: currentStoryItems[centralIndex + 1].peer.id, focusedId: nil, items: [currentStoryItems[centralIndex + 1].story]) + nextPeerContext = PeerContext(context: self.context, originalPeerId: self.originalPeerId, originalStory: self.originalStory, peerId: currentStoryItems[centralIndex + 1].peer.id, focusedId: nil, items: [currentStoryItems[centralIndex + 1].story]) } } diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift index 5ebe263fe9..42c75a2a00 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift @@ -68,7 +68,7 @@ final class StoryContentCaptionComponent: Component { let longTapAction: (Action) -> Void let textSelectionAction: (NSAttributedString, TextSelectionAction) -> Void let controller: () -> ViewController? - let openStory: (EnginePeer, EngineStoryItem) -> Void + let openStory: (EnginePeer, EngineStoryItem?) -> Void init( externalState: ExternalState, @@ -85,7 +85,7 @@ final class StoryContentCaptionComponent: Component { longTapAction: @escaping (Action) -> Void, textSelectionAction: @escaping (NSAttributedString, TextSelectionAction) -> Void, controller: @escaping () -> ViewController?, - openStory: @escaping (EnginePeer, EngineStoryItem) -> Void + openStory: @escaping (EnginePeer, EngineStoryItem?) -> Void ) { self.externalState = externalState self.context = context @@ -692,9 +692,9 @@ final class StoryContentCaptionComponent: Component { } } }) - text = nil + text = "" } else { - text = nil + text = "" } case let .unknown(name, _): authorName = name @@ -727,8 +727,8 @@ final class StoryContentCaptionComponent: Component { effectAlignment: .center, minSize: nil, action: { [weak self] in - if let self, case let .known(peer, _, _) = forwardInfo, let story = self.forwardInfoStory { - self.component?.openStory(peer, story) + if let self, case let .known(peer, _, _) = forwardInfo { + self.component?.openStory(peer, self.forwardInfoStory) } else if let controller = self?.component?.controller() as? StoryContainerScreen { let tooltipController = TooltipController(content: .text(component.strings.Story_ForwardAuthorHiddenTooltip), baseFontSize: 17.0, isBlurred: true, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true) controller.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceNodeAndRect: { [weak self, weak controller] in diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index 54a1789cbc..010cfcfaf2 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -4246,46 +4246,55 @@ public final class StoryItemSetContainerComponent: Component { guard let self, let component = self.component else { return } - let context = component.context - let peerId = component.slice.peer.id - let currentResult: ResolvedUrl = .story(peerId: peerId, id: component.slice.item.storyItem.id) - - self.sendMessageContext.openResolved(view: self, result: .story(peerId: peer.id, id: story.id), completion: { [weak self] in - guard let self, let controller = self.component?.controller() as? StoryContainerScreen else { - return - } - if let nextController = controller.navigationController?.viewControllers.last as? StoryContainerScreen { - nextController.customBackAction = { [weak nextController] in - context.sharedContext.openResolvedUrl( - currentResult, - context: context, - urlContext: .generic, - navigationController: nextController?.navigationController as? NavigationController, - forceExternal: false, - openPeer: { _, _ in - }, - sendFile: nil, - sendSticker: nil, - requestMessageActionUrlAuth: nil, - joinVoiceChat: nil, - present: { _, _ in - }, - dismissInput: { - }, - contentContext: nil, - progress: nil, - completion: { [weak nextController] in - Queue.mainQueue().after(0.5) { - nextController?.dismissWithoutTransitionOut() + if let story { + let context = component.context + let peerId = component.slice.peer.id + let currentResult: ResolvedUrl = .story(peerId: peerId, id: component.slice.item.storyItem.id) + + self.sendMessageContext.openResolved(view: self, result: .story(peerId: peer.id, id: story.id), completion: { [weak self] in + guard let self, let controller = self.component?.controller() as? StoryContainerScreen else { + return + } + if let nextController = controller.navigationController?.viewControllers.last as? StoryContainerScreen { + nextController.customBackAction = { [weak nextController] in + context.sharedContext.openResolvedUrl( + currentResult, + context: context, + urlContext: .generic, + navigationController: nextController?.navigationController as? NavigationController, + forceExternal: false, + openPeer: { _, _ in + }, + sendFile: nil, + sendSticker: nil, + requestMessageActionUrlAuth: nil, + joinVoiceChat: nil, + present: { _, _ in + }, + dismissInput: { + }, + contentContext: nil, + progress: nil, + completion: { [weak nextController] in + Queue.mainQueue().after(0.5) { + nextController?.dismissWithoutTransitionOut() + } } - } - ) + ) + } + } + Queue.mainQueue().after(0.5) { + controller.dismissWithoutTransitionOut() + } + }) + } else { + for mediaArea in component.slice.item.storyItem.mediaAreas { + if case .channelMessage = mediaArea { + self.sendMessageContext.activateMediaArea(view: self, mediaArea: mediaArea, immediate: true) + break } } - Queue.mainQueue().after(0.5) { - controller.dismissWithoutTransitionOut() - } - }) + } } )), environment: {}, @@ -5196,7 +5205,7 @@ public final class StoryItemSetContainerComponent: Component { } let context = component.context - let storyContent = RepostStoriesContentContextImpl(context: context, focusedStoryId: StoryId(peerId: peer.id, id: id), viewListContext: viewListContext, readGlobally: false) + let storyContent = RepostStoriesContentContextImpl(context: context, originalPeerId: component.slice.peer.id, originalStory: component.slice.item.storyItem, focusedStoryId: StoryId(peerId: peer.id, id: id), viewListContext: viewListContext, readGlobally: false) let _ = (storyContent.state |> take(1) |> deliverOnMainQueue).startStandalone(next: { [weak controller, weak viewListView, weak sourceView] _ in diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift index a42d4c9585..30ccbb145d 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift @@ -3264,8 +3264,8 @@ final class StoryItemSetContainerSendMessage { controller.push(sheet) }) } - - func activateMediaArea(view: StoryItemSetContainerComponent.View, mediaArea: MediaArea) { + + func activateMediaArea(view: StoryItemSetContainerComponent.View, mediaArea: MediaArea, immediate: Bool = false) { guard let component = view.component, let controller = component.controller() else { return } @@ -3278,8 +3278,8 @@ final class StoryItemSetContainerSendMessage { var actions: [ContextMenuAction] = [] switch mediaArea { case let .venue(_, venue): - let subject = EngineMessage(stableId: 0, stableVersion: 0, id: EngineMessage.Id(peerId: PeerId(0), namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [.geo(TelegramMediaMap(latitude: venue.latitude, longitude: venue.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: venue.venue, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil))], peers: [:], associatedMessages: [:], associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:]) - actions.append(ContextMenuAction(content: .textWithIcon(title: updatedPresentationData.initial.strings.Story_ViewLocation, icon: generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: .white)), action: { [weak controller, weak view] in + let action = { [weak controller, weak view] in + let subject = EngineMessage(stableId: 0, stableVersion: 0, id: EngineMessage.Id(peerId: PeerId(0), namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [.geo(TelegramMediaMap(latitude: venue.latitude, longitude: venue.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: venue.venue, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil))], peers: [:], associatedMessages: [:], associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:]) let locationController = LocationViewController( context: context, updatedPresentationData: updatedPresentationData, @@ -3302,9 +3302,16 @@ final class StoryItemSetContainerSendMessage { }) } controller?.push(locationController) + } + if immediate { + action() + return + } + actions.append(ContextMenuAction(content: .textWithIcon(title: updatedPresentationData.initial.strings.Story_ViewLocation, icon: generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: .white)), action: { + action() })) case let .channelMessage(_, messageId): - actions.append(ContextMenuAction(content: .textWithIcon(title: updatedPresentationData.initial.strings.Story_ViewMessage, icon: generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: .white)), action: { + let action = { [weak self, weak view] in let _ = ((context.engine.messages.getMessagesLoadIfNecessary([messageId], strategy: .local) |> mapToSignal { result -> Signal in if case let .result(messages) = result { @@ -3312,12 +3319,21 @@ final class StoryItemSetContainerSendMessage { } return .single(nil) }) - |> deliverOnMainQueue).startStandalone(next: { message in - guard let message else { + |> deliverOnMainQueue).startStandalone(next: { [weak self, weak view] message in + guard let self, let view else { return } - context.sharedContext.navigateToChat(accountId: context.account.id, peerId: message.id.peerId, messageId: message.id) + if let message, let peer = message.peers[message.id.peerId] { + self.openResolved(view: view, result: .channelMessage(peer: peer, messageId: message.id, timecode: nil)) + } }) + } + if immediate { + action() + return + } + actions.append(ContextMenuAction(content: .textWithIcon(title: updatedPresentationData.initial.strings.Story_ViewMessage, icon: generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: .white)), action: { + action() })) case .reaction: return diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift index d9e9d1c5c2..699e67cc9e 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift @@ -518,7 +518,7 @@ final class StoryItemSetViewListComponent: Component { )).string if let story = item.story, !story.text.isEmpty { - dateText += " • commented" + dateText += component.strings.Story_Views_Commented } let subtitleAccessory: PeerListItemComponent.SubtitleAccessory diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 46ee58418a..5eba98702a 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -118,6 +118,7 @@ import WebsiteType import ChatQrCodeScreen import PeerInfoScreen import MediaEditorScreen +import WallpaperGalleryScreen public enum ChatControllerPeekActions { case standard @@ -18780,10 +18781,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let context = self.context let subject: Signal = .single(.message(messages.map { $0.id })) - let initialCaption: NSAttributedString? = nil - let initialPrivacy: EngineStoryPrivacy? = nil - let initialMediaAreas: [MediaArea] = [] - let externalState = MediaEditorTransitionOutExternalState( storyTarget: nil, isPeerArchived: false, @@ -18793,28 +18790,43 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let controller = MediaEditorScreen( context: context, subject: subject, - isEditing: false, - forwardSource: nil, - initialCaption: initialCaption, - initialPrivacy: initialPrivacy, - initialMediaAreas: initialMediaAreas, - initialVideoPosition: nil, transitionIn: nil, transitionOut: { _, _ in return nil }, - completion: { result, commit in + completion: { [weak self] result, commit in + guard let self else { + return + } + let targetPeerId: EnginePeer.Id let target: Stories.PendingTarget if let sendAsPeerId = result.options.sendAsPeerId { target = .peer(sendAsPeerId) + targetPeerId = sendAsPeerId } else { target = .myStories + targetPeerId = self.context.account.peerId } externalState.storyTarget = target if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface { rootController.proceedWithStoryUpload(target: target, result: result, existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit) } + + let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: targetPeerId)) + |> deliverOnMainQueue).start(next: { [weak self] peer in + guard let self, let peer else { + return + } + let text: String + if case .channel = peer { + text = self.presentationData.strings.Story_MessageReposted_Channel(peer.compactDisplayTitle).string + } else { + text = self.presentationData.strings.Story_MessageReposted_Personal + } + self.present(UndoOverlayController(presentationData: self.presentationData, content: .succeed(text: text, timeout: nil, customUndoText: nil), elevatedLayout: false, action: { _ in return false }), in: .current) + }) + } ) self.push(controller) diff --git a/submodules/TelegramUI/Sources/NavigateToChatController.swift b/submodules/TelegramUI/Sources/NavigateToChatController.swift index b219c99935..f181e3c929 100644 --- a/submodules/TelegramUI/Sources/NavigateToChatController.swift +++ b/submodules/TelegramUI/Sources/NavigateToChatController.swift @@ -19,6 +19,7 @@ import CameraScreen import MediaEditorScreen import ChatControllerInteraction import SavedMessagesScreen +import WallpaperGalleryScreen public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParams) { if case let .peer(peer) = params.chatLocation { diff --git a/submodules/TelegramUI/Sources/OpenChatMessage.swift b/submodules/TelegramUI/Sources/OpenChatMessage.swift index fb5028708a..f84afb561e 100644 --- a/submodules/TelegramUI/Sources/OpenChatMessage.swift +++ b/submodules/TelegramUI/Sources/OpenChatMessage.swift @@ -23,6 +23,7 @@ import UndoUI import WebsiteType import GalleryData import StoryContainerScreen +import WallpaperGalleryScreen func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool { var story: TelegramMediaStory? diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index 852b3e231b..d7ba72c945 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -31,6 +31,7 @@ import PremiumUI import AuthorizationUI import ChatFolderLinkPreviewScreen import StoryContainerScreen +import WallpaperGalleryScreen private func defaultNavigationForPeerId(_ peerId: PeerId?, navigation: ChatControllerInteractionNavigateToPeer) -> ChatControllerInteractionNavigateToPeer { if case .default = navigation {