From e918b353ec31beffef521d89f7694a925b6475f4 Mon Sep 17 00:00:00 2001 From: isaac <> Date: Tue, 5 May 2026 14:11:06 +0200 Subject: [PATCH] Postbox refactor waves 278-356: squash Squashes 79 sequential refactor waves into a single commit. Highlights: - Drop `import Postbox` (and matching `//submodules/Postbox` BUILD deps) from a wide swath of consumer files: ChatList, ChatMessage*BubbleContentNode subclasses, ListMessageNode/ListMessageItem, GalleryData, ChatHistorySearchContainerNode, ChatPanelInterfaceInteraction, ChatControllerInteraction, ChatMessageStickerItemNode, ChatMessageReplyInfoNode, ChatMessageInstantVideoItemNode, ChatPresentationInterfaceState, BrowserMarkdown/Readability, MediaResources, LocalMediaResources, ICloudResources, FetchManager, ShareController, OpenChatMessage, GalleryController, GroupStickerSearchContainerNode, GroupStickerPackCurrentItem, ChatPinnedMessageTitlePanelNode, OverlayAudioPlayerController, PresentationThemeSettings, StatisticsUI/StoryIconNode, TextFormat/StringWithAppliedEntities, GalleryUI/VideoAdComponent, StickerPackPreviewUI, WallpaperPreviewMedia, WallpaperResources, YoutubeEmbedImplementation, InstantPageExternalMediaResource, PlatformRestrictionMatching, TelegramUIDeclareEncodables, ChatListNode/ChatListSearchContainerNode. - Add `TelegramEngine` facades: `Themes.wallpapers`, `Themes.themes`, `AccountData.addAppLogEvent`. - Add `EngineMessageHistoryEntryLocation` wrapper. - Add `EngineRaw*` escape-hatch typealiases (`EngineRawMessage`, `EngineRawPeer`, `EngineRawMedia`, `EngineRawMediaResource`, `EngineRawMediaResourceData`, `EngineRawItemCollectionItem`, `EngineRawItemCollectionInfo`) and `engineDeclareEncodable` forwarder. - Drop unused `account:`/`postbox:`/`network:` parameters from several public functions and delete the dead overloads/types/functions left over: `automaticThemeShouldSwitchNow`, `cancelFreeMediaFileInteractiveFetch`, `legacyEnqueueVideoMessage`, `TelegramMediaFileReference`, plus assorted dead public TelegramCore/AccountContext SecureId entry points. - Delete entire dead modules: `LegacyDataImport`, `TonBinding`, `SpotlightSupport`, `SvgRendering`, third-party `AppCenter`/`VectorPlus`/`SwiftColor`/`SwiftSVG`. - Drop orphan `//submodules/Postbox` BUILD deps across 3 cleanup rounds. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../AccountContext/Sources/FetchManager.swift | 13 +- .../Sources/FetchMediaUtils.swift | 4 - .../Sources/GalleryController.swift | 21 +- .../Sources/OpenChatMessage.swift | 37 +- .../Sources/PeerSelectionController.swift | 34 - .../Sources/PresentationCallManager.swift | 16 - .../Sources/ShareController.swift | 23 +- submodules/AuthorizationUI/BUILD | 1 - .../AvatarNode/Sources/AvatarNode.swift | 2 +- .../AvatarNode/Sources/PeerAvatar.swift | 18 +- .../BrowserUI/Sources/BrowserMarkdown.swift | 15 +- .../Sources/BrowserReadability.swift | 33 +- .../Sources/ChatListSearchContainerNode.swift | 17 +- .../Sources/ChatListSearchListPaneNode.swift | 2 +- .../Sources/Node/ChatListItem.swift | 13 +- .../Sources/Node/ChatListNode.swift | 5 +- .../ChatPanelInterfaceInteraction.swift | 99 +- submodules/GalleryData/BUILD | 1 - .../GalleryData/Sources/GalleryData.swift | 39 +- .../Items/ChatDocumentGalleryItem.swift | 13 +- .../Items/ChatExternalFileGalleryItem.swift | 15 +- .../Items/UniversalVideoGalleryItem.swift | 10 +- .../Sources/Items/VideoAdComponent.swift | 3 +- submodules/ICloudResources/BUILD | 1 - .../Sources/ICloudResources.swift | 23 +- .../InstantPageExternalMediaResource.swift | 27 +- submodules/LegacyDataImport/BUILD | 23 - submodules/LegacyDataImport/Impl/BUILD | 22 - .../LegacyDataImportImpl.h | 7 - .../TGAutoDownloadPreferences.h | 76 - .../TGAutoDownloadPreferences.m | 250 ---- .../TGPresentationAutoNightPreferences.h | 31 - .../TGPresentationAutoNightPreferences.m | 23 - .../LegacyDataImportImpl/TGProxyItem.h | 15 - .../LegacyDataImportImpl/TGProxyItem.m | 73 - .../Impl/Sources/TGAutoDownloadPreferences.m | 250 ---- .../TGPresentationAutoNightPreferences.m | 23 - .../Impl/Sources/TGProxyItem.m | 73 - .../Sources/LegacyBuffer.swift | 197 --- .../Sources/LegacyChatImport.swift | 780 ----------- .../Sources/LegacyDataImport.swift | 245 ---- .../Sources/LegacyDataImportSplash.swift | 89 -- .../Sources/LegacyFileImport.swift | 189 --- .../Sources/LegacyPreferencesImport.swift | 438 ------ .../Sources/LegacyResourceImport.swift | 137 -- .../Sources/LegacyUserDataImport.swift | 47 - .../Sources/LegacyMediaPickers.swift | 42 - .../Sources/ListMessageItem.swift | 39 +- .../Sources/ListMessageNode.swift | 4 +- submodules/LocalMediaResources/BUILD | 1 - .../Sources/MediaResources.swift | 83 +- submodules/MediaResources/BUILD | 1 - .../CachedResourceRepresentations.swift | 86 +- .../LegacySecureIdAttachmentMenu.swift | 4 +- .../Sources/PhotoResources.swift | 110 -- .../Sources/PlatformRestrictionMatching.swift | 3 +- .../PremiumUI/Sources/PremiumGiftScreen.swift | 8 +- .../Sources/PremiumIntroScreen.swift | 10 +- .../Sources/DeleteAccountDataController.swift | 26 +- .../DeleteAccountOptionsController.swift | 22 +- .../Sources/ThemePickerController.swift | 4 +- .../ThemeAutoNightSettingsController.swift | 2 +- .../Themes/ThemePreviewController.swift | 4 +- .../Themes/ThemeSettingsController.swift | 4 +- submodules/SpotlightSupport/BUILD | 18 - .../StatisticsUI/Sources/StoryIconNode.swift | 5 +- submodules/StickerPackPreviewUI/BUILD | 1 - .../Sources/StickerPackScreen.swift | 26 +- .../Sources/StickerResources.swift | 68 - submodules/SvgRendering/BUILD | 14 - .../SvgRendering/Sources/SvgParser.swift | 0 .../Sources/LegacyCallControllerNode.swift | 1 - .../Sources/ApiUtils/ChatContextResult.swift | 4 - .../CloudMediaResourceParameters.swift | 8 - .../TelegramCore/Sources/Authorization.swift | 22 - .../Network/FetchedMediaResource.swift | 4 +- .../Sources/Network/NetworkStatsContext.swift | 2 +- .../PendingMessages/EnqueueMessage.swift | 31 - .../StandaloneUploadedMedia.swift | 6 - .../Settings/ContentPrivacySettings.swift | 20 - .../TelegramCore/Sources/SplitTest.swift | 2 +- .../Sources/State/CallSessionManager.swift | 4 - .../SynchronizeAppLogEventsOperation.swift | 2 +- .../SyncCore_ArchivedStickerPacksInfo.swift | 42 - .../SyncCore_AutodownloadSettings.swift | 6 - ...Core_LocalMediaPlaybackInfoAttribute.swift | 18 - .../SyncCore/SyncCore_NewSessionReview.swift | 17 - .../SyncCore/SyncCore_TelegramMediaFile.swift | 28 - .../SyncCore/SyncCore_VoipConfiguration.swift | 6 - .../TelegramEngineAccountData.swift | 4 + .../Auth/TwoStepVerification.swift | 7 - .../TelegramEngine/Calls/GroupCalls.swift | 4 - .../TelegramEngine/Payments/AppStore.swift | 4 - .../Peers/ChatListFiltering.swift | 12 - .../Peers/ResolvePeerByName.swift | 11 - .../SecureId/SaveSecureIdValue.swift | 38 - .../SecureId/SecureIdValueAccessContext.swift | 4 - .../Themes/TelegramEngineThemes.swift | 8 + .../Utils/EnginePostboxCoding.swift | 22 + submodules/TelegramCore/Sources/Themes.swift | 6 +- .../Sources/Utils/PeerUtils.swift | 12 - .../TelegramCore/Sources/Wallpapers.swift | 2 +- .../TelegramCore/Sources/WebpagePreview.swift | 4 - .../Sources/PresentationData.swift | 5 - .../Chat/ChatButtonKeyboardInputNode/BUILD | 1 - .../Chat/ChatHistorySearchContainerNode/BUILD | 1 - .../ChatHistorySearchContainerNode.swift | 21 +- .../Chat/ChatMediaInputStickerGridItem/BUILD | 1 - .../ChatMediaInputStickerGridItem.swift | 9 +- .../ChatMessageActionBubbleContentNode.swift | 11 +- .../Chat/ChatMessageBubbleContentNode/BUILD | 1 - .../ChatMessageBubbleContentNode.swift | 23 +- .../ChatMessageCommentFooterContentNode/BUILD | 1 - ...entLogPreviousDescriptionContentNode.swift | 7 +- ...ssageEventLogPreviousLinkContentNode.swift | 9 +- ...geEventLogPreviousMessageContentNode.swift | 7 +- .../ChatMessageFileBubbleContentNode.swift | 5 +- .../ChatMessageGameBubbleContentNode.swift | 7 +- .../BUILD | 1 - ...MessageInstantVideoBubbleContentNode.swift | 7 +- .../ChatMessageInstantVideoItemNode/BUILD | 1 - .../ChatMessageInstantVideoItemNode.swift | 11 +- .../ChatMessageInvoiceBubbleContentNode.swift | 7 +- .../Components/Chat/ChatMessageItem/BUILD | 1 - .../Sources/ChatMessageItem.swift | 29 +- .../Sources/ChatMessageItemImpl.swift | 25 +- .../Components/Chat/ChatMessageItemView/BUILD | 1 - .../Sources/ChatMessageItemView.swift | 23 +- ...essageJoinedChannelBubbleContentNode.swift | 2 +- .../ChatMessageMapBubbleContentNode.swift | 5 +- .../ChatMessageMediaBubbleContentNode.swift | 9 +- ...atMessageQuizAnswerBubbleContentNode.swift | 7 +- ...ageProfilePhotoSuggestionContentNode.swift | 9 +- .../Chat/ChatMessageReplyInfoNode/BUILD | 1 - .../Sources/ChatMessageReplyInfoNode.swift | 17 +- .../BUILD | 1 - ...ChatMessageRichDataBubbleContentNode.swift | 9 +- .../Chat/ChatMessageStickerItemNode/BUILD | 1 - .../Sources/ChatMessageStickerItemNode.swift | 21 +- .../ChatMessageStoryMentionContentNode.swift | 9 +- .../ChatMessageTodoBubbleContentNode/BUILD | 1 - .../ChatMessageTodoBubbleContentNode.swift | 9 +- ...hatMessageWallpaperBubbleContentNode.swift | 7 +- .../ChatMessageWebpageBubbleContentNode.swift | 15 +- .../ChatRecentActionsFilterController.swift | 504 ------- .../ChatControllerInteraction/BUILD | 1 - .../Sources/ChatControllerInteraction.swift | 267 ++-- .../Components/EntityKeyboardGifContent/BUILD | 1 - .../Sources/GiftSetupScreen.swift | 4 +- .../Components/Gifts/GiftViewScreen/BUILD | 1 - .../Sources/GroupStickerPackCurrentItem.swift | 3 +- .../GroupStickerSearchContainerNode.swift | 7 +- .../PeerInfo/PeerInfoChatListPaneNode/BUILD | 1 - .../PeerInfo/PeerInfoChatPaneNode/BUILD | 1 - .../PeerInfo/PeerInfoPaneNode/BUILD | 1 - .../Sources/Panes/PeerInfoListPaneNode.swift | 23 +- .../Resources/FetchAudioMediaResource/BUILD | 1 - .../Sources/FetchAudioMediaResource.swift | 5 +- .../Sources/ChannelAppearanceScreen.swift | 17 +- .../Sources/SettingsThemeWallpaperNode.swift | 2 +- .../Sources/ThemeAccentColorController.swift | 2 +- .../Sources/WallpaperGalleryItem.swift | 4 +- .../Sources/WallpaperPatternPanelNode.swift | 2 +- .../Sources/ThemeGridController.swift | 2 +- .../Sources/ThemeGridControllerNode.swift | 2 +- .../Sources/StorySetIndicatorComponent.swift | 2 +- .../TelegramAccountAuxiliaryMethods.swift | 2 +- .../TelegramUIDeclareEncodables/BUILD | 2 +- .../Sources/TelegramUIDeclareEncodables.swift | 14 +- .../Sources/WallpaperPreviewMedia.swift | 43 +- .../TelegramUI/Sources/ChatController.swift | 2 +- .../Sources/ChatControllerContentData.swift | 4 +- .../ChatPinnedMessageTitlePanelNode.swift | 19 +- .../Sources/FetchCachedRepresentations.swift | 55 +- .../Sources/HorizontalStickerGridItem.swift | 3 +- .../Sources/NotificationContentContext.swift | 7 +- .../OverlayAudioPlayerController.swift | 7 +- .../Sources/ThemeUpdateManager.swift | 3 +- .../Sources/PresentationThemeSettings.swift | 49 +- .../Sources/YoutubeEmbedImplementation.swift | 33 +- .../Sources/StringWithAppliedEntities.swift | 7 +- submodules/TonBinding/BUILD | 26 - submodules/TonBinding/Sources/TON.h | 190 --- submodules/TonBinding/Sources/TON.mm | 1227 ----------------- submodules/UrlHandling/BUILD | 1 - submodules/WallpaperResources/BUILD | 1 - .../Sources/WallpaperResources.swift | 19 +- third-party/AppCenter/AppCenter.BUILD | 15 - third-party/AppCenter/BUILD | 0 third-party/SwiftColor/BUILD | 17 - third-party/SwiftColor/Sources/Clamping.swift | 20 - .../SwiftColor/Sources/ColorSpace.swift | 3 - .../SwiftColor/Sources/Pigment+AppKit.swift | 24 - .../Sources/Pigment+CoreGraphics.swift | 39 - .../SwiftColor/Sources/Pigment+Float.swift | 95 -- .../SwiftColor/Sources/Pigment+Hex.swift | 145 -- .../SwiftColor/Sources/Pigment+Int.swift | 89 -- .../SwiftColor/Sources/Pigment+Name.swift | 470 ------- .../SwiftColor/Sources/Pigment+String.swift | 76 - .../SwiftColor/Sources/Pigment+SwiftUI.swift | 9 - .../SwiftColor/Sources/Pigment+UIKit.swift | 37 - third-party/SwiftColor/Sources/Pigment.swift | 53 - third-party/SwiftSVG/BUILD | 19 - third-party/SwiftSVG/Sources/Circle.swift | 93 -- .../Sources/CommandRepresentable.swift | 15 - third-party/SwiftSVG/Sources/Container.swift | 58 - .../SwiftSVG/Sources/CoreAttributes.swift | 17 - third-party/SwiftSVG/Sources/Element.swift | 46 - third-party/SwiftSVG/Sources/Ellipse.swift | 93 -- .../Sources/Extensions/Point+SwiftSVG.swift | 37 - third-party/SwiftSVG/Sources/Fill.swift | 44 - third-party/SwiftSVG/Sources/Group.swift | 152 -- .../Sources/Internal/EllipseProcessor.swift | 88 -- .../Sources/Internal/PathProcessor.swift | 12 - .../Sources/Internal/PolygonProcressor.swift | 52 - .../Sources/Internal/PolylineProcessor.swift | 54 - .../Sources/Internal/RectangleProcessor.swift | 175 --- third-party/SwiftSVG/Sources/Line.swift | 98 -- .../SwiftSVG/Sources/Path.Command.swift | 276 ---- .../SwiftSVG/Sources/Path.Component.swift | 98 -- .../Sources/Path.ComponentParser.swift | 275 ---- third-party/SwiftSVG/Sources/Path.swift | 101 -- third-party/SwiftSVG/Sources/Polygon.swift | 82 -- third-party/SwiftSVG/Sources/Polyline.swift | 81 -- .../Sources/PresentationAttributes.swift | 120 -- third-party/SwiftSVG/Sources/Rectangle.swift | 115 -- .../SwiftSVG/Sources/SVG+Swift2D.swift | 62 - third-party/SwiftSVG/Sources/SVG.swift | 160 --- third-party/SwiftSVG/Sources/Stroke.swift | 64 - .../SwiftSVG/Sources/StylingAttributes.swift | 17 - third-party/SwiftSVG/Sources/Text.swift | 110 -- .../SwiftSVG/Sources/Transformation.swift | 113 -- third-party/VectorPlus/BUILD | 19 - .../CoreGraphics/CGContext+Render.swift | 72 - .../CGMutablePath+Instruction.swift | 45 - .../CoreGraphics/Fill+CoreGraphics.swift | 14 - .../Sources/CoreGraphics/SVG+CGPath.swift | 37 - .../CoreGraphics/Stroke+CoreGraphics.swift | 25 - .../VectorPlus/Sources/Fill+VectorPlus.swift | 29 - .../VectorPlus/Sources/Path+VectorPlus.swift | 34 - .../Sources/Path.Command+VectorPlus.swift | 216 --- .../Sources/Pigment+VectorPlus.swift | 7 - .../VectorPlus/Sources/Point+VectorPlus.swift | 7 - .../VectorPlus/Sources/Rect+VectorPlus.swift | 7 - .../VectorPlus/Sources/SVG+AppleSymbols.swift | 324 ----- .../VectorPlus/Sources/SVG+Template.swift | 56 - .../VectorPlus/Sources/Size+VectorPlus.swift | 7 - .../Sources/Stroke+VectorPlus.swift | 40 - .../Sources/Template+UIImageView.swift | 177 --- .../Sources/UIKit/SVG+UIImage.swift | 43 - .../Sources/UIKit/SVGImageView.swift | 81 -- .../VectorPlus/Sources/VectorPoint.swift | 126 -- 252 files changed, 829 insertions(+), 11680 deletions(-) delete mode 100644 submodules/LegacyDataImport/BUILD delete mode 100644 submodules/LegacyDataImport/Impl/BUILD delete mode 100644 submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/LegacyDataImportImpl.h delete mode 100644 submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGAutoDownloadPreferences.h delete mode 100644 submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGAutoDownloadPreferences.m delete mode 100644 submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGPresentationAutoNightPreferences.h delete mode 100644 submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGPresentationAutoNightPreferences.m delete mode 100644 submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGProxyItem.h delete mode 100644 submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGProxyItem.m delete mode 100644 submodules/LegacyDataImport/Impl/Sources/TGAutoDownloadPreferences.m delete mode 100644 submodules/LegacyDataImport/Impl/Sources/TGPresentationAutoNightPreferences.m delete mode 100644 submodules/LegacyDataImport/Impl/Sources/TGProxyItem.m delete mode 100644 submodules/LegacyDataImport/Sources/LegacyBuffer.swift delete mode 100644 submodules/LegacyDataImport/Sources/LegacyChatImport.swift delete mode 100644 submodules/LegacyDataImport/Sources/LegacyDataImport.swift delete mode 100644 submodules/LegacyDataImport/Sources/LegacyDataImportSplash.swift delete mode 100644 submodules/LegacyDataImport/Sources/LegacyFileImport.swift delete mode 100644 submodules/LegacyDataImport/Sources/LegacyPreferencesImport.swift delete mode 100644 submodules/LegacyDataImport/Sources/LegacyResourceImport.swift delete mode 100644 submodules/LegacyDataImport/Sources/LegacyUserDataImport.swift delete mode 100644 submodules/SpotlightSupport/BUILD delete mode 100644 submodules/SvgRendering/BUILD delete mode 100644 submodules/SvgRendering/Sources/SvgParser.swift delete mode 100644 submodules/TelegramCore/Sources/ApiUtils/CloudMediaResourceParameters.swift delete mode 100644 submodules/TelegramCore/Sources/Settings/ContentPrivacySettings.swift delete mode 100644 submodules/TelegramCore/Sources/SyncCore/SyncCore_ArchivedStickerPacksInfo.swift delete mode 100644 submodules/TelegramCore/Sources/SyncCore/SyncCore_LocalMediaPlaybackInfoAttribute.swift delete mode 100644 submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsFilterController.swift delete mode 100644 submodules/TonBinding/BUILD delete mode 100644 submodules/TonBinding/Sources/TON.h delete mode 100644 submodules/TonBinding/Sources/TON.mm delete mode 100644 third-party/AppCenter/AppCenter.BUILD delete mode 100644 third-party/AppCenter/BUILD delete mode 100644 third-party/SwiftColor/BUILD delete mode 100644 third-party/SwiftColor/Sources/Clamping.swift delete mode 100644 third-party/SwiftColor/Sources/ColorSpace.swift delete mode 100644 third-party/SwiftColor/Sources/Pigment+AppKit.swift delete mode 100644 third-party/SwiftColor/Sources/Pigment+CoreGraphics.swift delete mode 100644 third-party/SwiftColor/Sources/Pigment+Float.swift delete mode 100644 third-party/SwiftColor/Sources/Pigment+Hex.swift delete mode 100644 third-party/SwiftColor/Sources/Pigment+Int.swift delete mode 100644 third-party/SwiftColor/Sources/Pigment+Name.swift delete mode 100644 third-party/SwiftColor/Sources/Pigment+String.swift delete mode 100644 third-party/SwiftColor/Sources/Pigment+SwiftUI.swift delete mode 100644 third-party/SwiftColor/Sources/Pigment+UIKit.swift delete mode 100644 third-party/SwiftColor/Sources/Pigment.swift delete mode 100644 third-party/SwiftSVG/BUILD delete mode 100644 third-party/SwiftSVG/Sources/Circle.swift delete mode 100644 third-party/SwiftSVG/Sources/CommandRepresentable.swift delete mode 100644 third-party/SwiftSVG/Sources/Container.swift delete mode 100644 third-party/SwiftSVG/Sources/CoreAttributes.swift delete mode 100644 third-party/SwiftSVG/Sources/Element.swift delete mode 100644 third-party/SwiftSVG/Sources/Ellipse.swift delete mode 100644 third-party/SwiftSVG/Sources/Extensions/Point+SwiftSVG.swift delete mode 100644 third-party/SwiftSVG/Sources/Fill.swift delete mode 100644 third-party/SwiftSVG/Sources/Group.swift delete mode 100644 third-party/SwiftSVG/Sources/Internal/EllipseProcessor.swift delete mode 100644 third-party/SwiftSVG/Sources/Internal/PathProcessor.swift delete mode 100644 third-party/SwiftSVG/Sources/Internal/PolygonProcressor.swift delete mode 100644 third-party/SwiftSVG/Sources/Internal/PolylineProcessor.swift delete mode 100644 third-party/SwiftSVG/Sources/Internal/RectangleProcessor.swift delete mode 100644 third-party/SwiftSVG/Sources/Line.swift delete mode 100644 third-party/SwiftSVG/Sources/Path.Command.swift delete mode 100644 third-party/SwiftSVG/Sources/Path.Component.swift delete mode 100644 third-party/SwiftSVG/Sources/Path.ComponentParser.swift delete mode 100644 third-party/SwiftSVG/Sources/Path.swift delete mode 100644 third-party/SwiftSVG/Sources/Polygon.swift delete mode 100644 third-party/SwiftSVG/Sources/Polyline.swift delete mode 100644 third-party/SwiftSVG/Sources/PresentationAttributes.swift delete mode 100644 third-party/SwiftSVG/Sources/Rectangle.swift delete mode 100644 third-party/SwiftSVG/Sources/SVG+Swift2D.swift delete mode 100644 third-party/SwiftSVG/Sources/SVG.swift delete mode 100644 third-party/SwiftSVG/Sources/Stroke.swift delete mode 100644 third-party/SwiftSVG/Sources/StylingAttributes.swift delete mode 100644 third-party/SwiftSVG/Sources/Text.swift delete mode 100644 third-party/SwiftSVG/Sources/Transformation.swift delete mode 100644 third-party/VectorPlus/BUILD delete mode 100644 third-party/VectorPlus/Sources/CoreGraphics/CGContext+Render.swift delete mode 100644 third-party/VectorPlus/Sources/CoreGraphics/CGMutablePath+Instruction.swift delete mode 100644 third-party/VectorPlus/Sources/CoreGraphics/Fill+CoreGraphics.swift delete mode 100644 third-party/VectorPlus/Sources/CoreGraphics/SVG+CGPath.swift delete mode 100644 third-party/VectorPlus/Sources/CoreGraphics/Stroke+CoreGraphics.swift delete mode 100644 third-party/VectorPlus/Sources/Fill+VectorPlus.swift delete mode 100644 third-party/VectorPlus/Sources/Path+VectorPlus.swift delete mode 100644 third-party/VectorPlus/Sources/Path.Command+VectorPlus.swift delete mode 100644 third-party/VectorPlus/Sources/Pigment+VectorPlus.swift delete mode 100644 third-party/VectorPlus/Sources/Point+VectorPlus.swift delete mode 100644 third-party/VectorPlus/Sources/Rect+VectorPlus.swift delete mode 100644 third-party/VectorPlus/Sources/SVG+AppleSymbols.swift delete mode 100644 third-party/VectorPlus/Sources/SVG+Template.swift delete mode 100644 third-party/VectorPlus/Sources/Size+VectorPlus.swift delete mode 100644 third-party/VectorPlus/Sources/Stroke+VectorPlus.swift delete mode 100644 third-party/VectorPlus/Sources/Template+UIImageView.swift delete mode 100644 third-party/VectorPlus/Sources/UIKit/SVG+UIImage.swift delete mode 100644 third-party/VectorPlus/Sources/UIKit/SVGImageView.swift delete mode 100644 third-party/VectorPlus/Sources/VectorPoint.swift diff --git a/submodules/AccountContext/Sources/FetchManager.swift b/submodules/AccountContext/Sources/FetchManager.swift index 39ca3de10c..a705710c9c 100644 --- a/submodules/AccountContext/Sources/FetchManager.swift +++ b/submodules/AccountContext/Sources/FetchManager.swift @@ -1,5 +1,4 @@ import Foundation -import Postbox import TelegramCore import SwiftSignalKit import TelegramUIPreferences @@ -13,7 +12,7 @@ public enum FetchManagerCategory: Int32 { } public enum FetchManagerLocationKey: Comparable, Hashable { - case messageId(MessageId) + case messageId(EngineMessage.Id) case free public static func <(lhs: FetchManagerLocationKey, rhs: FetchManagerLocationKey) -> Bool { @@ -87,7 +86,7 @@ public struct FetchManagerPriorityKey: Comparable { } public enum FetchManagerLocation: Hashable, CustomStringConvertible { - case chat(PeerId) + case chat(EnginePeer.Id) public var description: String { switch self { @@ -104,8 +103,8 @@ public enum FetchManagerForegroundDirection { public enum FetchManagerPriority: Comparable { case userInitiated - case foregroundPrefetch(direction: FetchManagerForegroundDirection, localOrder: MessageIndex) - case backgroundPrefetch(locationOrder: HistoryPreloadIndex, localOrder: MessageIndex) + case foregroundPrefetch(direction: FetchManagerForegroundDirection, localOrder: EngineMessage.Index) + case backgroundPrefetch(locationOrder: HistoryPreloadIndex, localOrder: EngineMessage.Index) public static func <(lhs: FetchManagerPriority, rhs: FetchManagerPriority) -> Bool { switch lhs { @@ -160,11 +159,11 @@ public protocol FetchManager { var queue: Queue { get } func interactivelyFetched(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, mediaReference: AnyMediaReference?, resourceReference: MediaResourceReference, ranges: RangeSet, statsCategory: MediaResourceStatsCategory, elevatedPriority: Bool, userInitiated: Bool, priority: FetchManagerPriority, storeToDownloadsPeerId: EnginePeer.Id?) -> Signal - func cancelInteractiveFetches(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, resource: MediaResource) + func cancelInteractiveFetches(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, resource: EngineRawMediaResource) func cancelInteractiveFetches(resourceId: String) func toggleInteractiveFetchPaused(resourceId: String, isPaused: Bool) func raisePriority(resourceId: String) - func fetchStatus(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, resource: MediaResource) -> Signal + func fetchStatus(category: FetchManagerCategory, location: FetchManagerLocation, locationKey: FetchManagerLocationKey, resource: EngineRawMediaResource) -> Signal } public protocol PrefetchManager { diff --git a/submodules/AccountContext/Sources/FetchMediaUtils.swift b/submodules/AccountContext/Sources/FetchMediaUtils.swift index 805ae7a967..b969890fbb 100644 --- a/submodules/AccountContext/Sources/FetchMediaUtils.swift +++ b/submodules/AccountContext/Sources/FetchMediaUtils.swift @@ -24,10 +24,6 @@ public func freeMediaFileResourceInteractiveFetched(postbox: Postbox, userLocati return fetchedMediaResource(mediaBox: postbox.mediaBox, userLocation: userLocation, userContentType: MediaResourceUserContentType(file: fileReference.media), reference: fileReference.resourceReference(resource), range: range) } -public func cancelFreeMediaFileInteractiveFetch(account: Account, file: TelegramMediaFile) { - account.postbox.mediaBox.cancelInteractiveResourceFetch(file.resource) -} - private func fetchCategoryForFile(_ file: TelegramMediaFile) -> FetchManagerCategory { if file.isVoice || file.isInstantVideo { return .voice diff --git a/submodules/AccountContext/Sources/GalleryController.swift b/submodules/AccountContext/Sources/GalleryController.swift index 7a13847f0c..02b81f7088 100644 --- a/submodules/AccountContext/Sources/GalleryController.swift +++ b/submodules/AccountContext/Sources/GalleryController.swift @@ -1,7 +1,6 @@ import Foundation import UIKit import Display -import Postbox import SwiftSignalKit import TelegramCore @@ -10,13 +9,13 @@ public enum GalleryMediaSubject: Hashable { case pollDescription case pollOption(Data) case pollSolution - case instantPageMedia(MediaId) + case instantPageMedia(EngineMedia.Id) } public enum GalleryControllerItemSource { - case peerMessagesAtId(messageId: MessageId, chatLocation: ChatLocation, customTag: MemoryBuffer?, chatLocationContextHolder: Atomic) - case standaloneMessage(Message, GalleryMediaSubject?) - case custom(messages: Signal<([Message], Int32, Bool), NoError>, messageId: MessageId, loadMore: (() -> Void)?) + case peerMessagesAtId(messageId: EngineMessage.Id, chatLocation: ChatLocation, customTag: EngineMemoryBuffer?, chatLocationContextHolder: Atomic) + case standaloneMessage(EngineRawMessage, GalleryMediaSubject?) + case custom(messages: Signal<([EngineRawMessage], Int32, Bool), NoError>, messageId: EngineMessage.Id, loadMore: (() -> Void)?) } public final class GalleryControllerActionInteraction { @@ -26,10 +25,10 @@ public final class GalleryControllerActionInteraction { public let openPeer: (EnginePeer) -> Void public let openHashtag: (String?, String) -> Void public let openBotCommand: (String) -> Void - public let openAd: (MessageId) -> Void + public let openAd: (EngineMessage.Id) -> Void public let addContact: (String) -> Void - public let storeMediaPlaybackState: (MessageId, Double?, Double) -> Void - public let editMedia: (MessageId, [UIView], @escaping () -> Void) -> Void + public let storeMediaPlaybackState: (EngineMessage.Id, Double?, Double) -> Void + public let editMedia: (EngineMessage.Id, [UIView], @escaping () -> Void) -> Void public let updateCanReadHistory: (Bool) -> Void public let sendSticker: ((FileMediaReference) -> Void)? @@ -40,10 +39,10 @@ public final class GalleryControllerActionInteraction { openPeer: @escaping (EnginePeer) -> Void, openHashtag: @escaping (String?, String) -> Void, openBotCommand: @escaping (String) -> Void, - openAd: @escaping (MessageId) -> Void, + openAd: @escaping (EngineMessage.Id) -> Void, addContact: @escaping (String) -> Void, - storeMediaPlaybackState: @escaping (MessageId, Double?, Double) -> Void, - editMedia: @escaping (MessageId, [UIView], @escaping () -> Void) -> Void, + storeMediaPlaybackState: @escaping (EngineMessage.Id, Double?, Double) -> Void, + editMedia: @escaping (EngineMessage.Id, [UIView], @escaping () -> Void) -> Void, updateCanReadHistory: @escaping (Bool) -> Void, sendSticker: ((FileMediaReference) -> Void)? ) { diff --git a/submodules/AccountContext/Sources/OpenChatMessage.swift b/submodules/AccountContext/Sources/OpenChatMessage.swift index 43f9bf0caf..68b45fe0ed 100644 --- a/submodules/AccountContext/Sources/OpenChatMessage.swift +++ b/submodules/AccountContext/Sources/OpenChatMessage.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import TelegramCore import SwiftSignalKit import Display @@ -22,9 +21,9 @@ public final class OpenChatMessageParams { public let context: AccountContext public let updatedPresentationData: (initial: PresentationData, signal: Signal)? public let chatLocation: ChatLocation? - public let chatFilterTag: MemoryBuffer? + public let chatFilterTag: EngineMemoryBuffer? public let chatLocationContextHolder: Atomic? - public let message: Message + public let message: EngineRawMessage public let mediaSubject: GalleryMediaSubject? public let standalone: Bool public let copyProtected: Bool @@ -34,21 +33,21 @@ public final class OpenChatMessageParams { public let modal: Bool public let dismissInput: () -> Void public let present: (ViewController, Any?, PresentationContextType) -> Void - public let transitionNode: (MessageId, Media, Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? + public let transitionNode: (EngineMessage.Id, EngineRawMedia, Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? public let addToTransitionSurface: (UIView) -> Void public let openUrl: (String) -> Void - public let openPeer: (Peer, ChatControllerInteractionNavigateToPeer) -> Void - public let callPeer: (PeerId, Bool) -> Void - public let openConferenceCall: (Message) -> Void + public let openPeer: (EngineRawPeer, ChatControllerInteractionNavigateToPeer) -> Void + public let callPeer: (EnginePeer.Id, Bool) -> Void + public let openConferenceCall: (EngineRawMessage) -> Void public let enqueueMessage: (EnqueueMessage) -> Void public let sendSticker: ((FileMediaReference, UIView?, CGRect?) -> Bool)? public let sendEmoji: ((String, ChatTextInputTextCustomEmojiAttribute) -> Void)? - public let setupTemporaryHiddenMedia: (Signal, Int, Media) -> Void - public let chatAvatarHiddenMedia: (Signal, Media) -> Void + public let setupTemporaryHiddenMedia: (Signal, Int, EngineRawMedia) -> Void + public let chatAvatarHiddenMedia: (Signal, EngineRawMedia) -> Void public let actionInteraction: GalleryControllerActionInteraction? public let playlistLocation: PeerMessagesPlaylistLocation? public let gallerySource: GalleryControllerItemSource? - public let centralItemUpdated: ((MessageId) -> Void)? + public let centralItemUpdated: ((EngineMessage.Id) -> Void)? public let navigateToMessageContext: ((EngineMessage) -> Void)? public let getSourceRect: (() -> CGRect?)? public let blockInteraction: Promise @@ -57,9 +56,9 @@ public final class OpenChatMessageParams { context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, chatLocation: ChatLocation?, - chatFilterTag: MemoryBuffer?, + chatFilterTag: EngineMemoryBuffer?, chatLocationContextHolder: Atomic?, - message: Message, + message: EngineRawMessage, mediaSubject: GalleryMediaSubject? = nil, standalone: Bool, copyProtected: Bool = false, @@ -69,21 +68,21 @@ public final class OpenChatMessageParams { modal: Bool = false, dismissInput: @escaping () -> Void, present: @escaping (ViewController, Any?, PresentationContextType) -> Void, - transitionNode: @escaping (MessageId, Media, Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, + transitionNode: @escaping (EngineMessage.Id, EngineRawMedia, Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, addToTransitionSurface: @escaping (UIView) -> Void, openUrl: @escaping (String) -> Void, - openPeer: @escaping (Peer, ChatControllerInteractionNavigateToPeer) -> Void, - callPeer: @escaping (PeerId, Bool) -> Void, - openConferenceCall: @escaping (Message) -> Void, + openPeer: @escaping (EngineRawPeer, ChatControllerInteractionNavigateToPeer) -> Void, + callPeer: @escaping (EnginePeer.Id, Bool) -> Void, + openConferenceCall: @escaping (EngineRawMessage) -> Void, enqueueMessage: @escaping (EnqueueMessage) -> Void, sendSticker: ((FileMediaReference, UIView?, CGRect?) -> Bool)?, sendEmoji: ((String, ChatTextInputTextCustomEmojiAttribute) -> Void)?, - setupTemporaryHiddenMedia: @escaping (Signal, Int, Media) -> Void, - chatAvatarHiddenMedia: @escaping (Signal, Media) -> Void, + setupTemporaryHiddenMedia: @escaping (Signal, Int, EngineRawMedia) -> Void, + chatAvatarHiddenMedia: @escaping (Signal, EngineRawMedia) -> Void, actionInteraction: GalleryControllerActionInteraction? = nil, playlistLocation: PeerMessagesPlaylistLocation? = nil, gallerySource: GalleryControllerItemSource? = nil, - centralItemUpdated: ((MessageId) -> Void)? = nil, + centralItemUpdated: ((EngineMessage.Id) -> Void)? = nil, navigateToMessageContext: ((EngineMessage) -> Void)? = nil, getSourceRect: (() -> CGRect?)? = nil ) { diff --git a/submodules/AccountContext/Sources/PeerSelectionController.swift b/submodules/AccountContext/Sources/PeerSelectionController.swift index 547d98a0e6..19e8d7a3bc 100644 --- a/submodules/AccountContext/Sources/PeerSelectionController.swift +++ b/submodules/AccountContext/Sources/PeerSelectionController.swift @@ -2,7 +2,6 @@ import Foundation import Display import SwiftSignalKit import TelegramCore -import Postbox import TelegramPresentationData import AnimationCache import MultiAnimationRenderer @@ -125,39 +124,6 @@ public enum AttachmentTextInputPanelSendMode { case whenOnline } -public enum PeerSelectionControllerContext { - public final class Custom { - public let accountPeerId: EnginePeer.Id - public let postbox: Postbox - public let network: Network - public let animationCache: AnimationCache - public let animationRenderer: MultiAnimationRenderer - public let presentationData: PresentationData - public let updatedPresentationData: Signal - - public init( - accountPeerId: EnginePeer.Id, - postbox: Postbox, - network: Network, - animationCache: AnimationCache, - animationRenderer: MultiAnimationRenderer, - presentationData: PresentationData, - updatedPresentationData: Signal - ) { - self.accountPeerId = accountPeerId - self.postbox = postbox - self.network = network - self.animationCache = animationCache - self.animationRenderer = animationRenderer - self.presentationData = presentationData - self.updatedPresentationData = updatedPresentationData - } - } - - case account(AccountContext) - case custom(Custom) -} - public protocol PeerSelectionController: ViewController { var peerSelected: ((EnginePeer, Int64?) -> Void)? { get set } var multiplePeersSelected: (([EnginePeer], [EnginePeer.Id: EnginePeer], NSAttributedString, AttachmentTextInputPanelSendMode, ChatInterfaceForwardOptionsState?, ChatSendMessageActionSheetController.SendParameters?) -> Void)? { get set } diff --git a/submodules/AccountContext/Sources/PresentationCallManager.swift b/submodules/AccountContext/Sources/PresentationCallManager.swift index 62bde63548..a3ac3bb3bd 100644 --- a/submodules/AccountContext/Sources/PresentationCallManager.swift +++ b/submodules/AccountContext/Sources/PresentationCallManager.swift @@ -309,22 +309,6 @@ public struct PresentationGroupCallSummaryState: Equatable { } } -public struct PresentationGroupCallMemberState: Equatable { - public var ssrc: UInt32 - public var muteState: GroupCallParticipantsContext.Participant.MuteState? - public var speaking: Bool - - public init( - ssrc: UInt32, - muteState: GroupCallParticipantsContext.Participant.MuteState?, - speaking: Bool - ) { - self.ssrc = ssrc - self.muteState = muteState - self.speaking = speaking - } -} - public enum PresentationGroupCallMuteAction: Equatable { case muted(isPushToTalkActive: Bool) case unmuted diff --git a/submodules/AccountContext/Sources/ShareController.swift b/submodules/AccountContext/Sources/ShareController.swift index 5ef521a5d5..a018a1f987 100644 --- a/submodules/AccountContext/Sources/ShareController.swift +++ b/submodules/AccountContext/Sources/ShareController.swift @@ -1,6 +1,5 @@ import Foundation import SwiftSignalKit -import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences @@ -9,7 +8,7 @@ import MultiAnimationRenderer import Display public enum StorySharingSubject { - case messages([Message]) + case messages([EngineRawMessage]) case gift(StarGift.UniqueGift) } @@ -110,11 +109,11 @@ public enum ShareControllerSubject { case url(String) case text(String) case quote(text: String, url: String) - case messages([Message]) + case messages([EngineRawMessage]) case image([ImageRepresentationWithReference]) case media(AnyMediaReference, MediaParameters?) case mapMedia(TelegramMediaMap) - case fromExternal(Int, ([PeerId], [PeerId: Int64], [PeerId: StarsAmount], String, ShareControllerAccountContext, Bool) -> Signal) + case fromExternal(Int, ([EnginePeer.Id], [EnginePeer.Id: Int64], [EnginePeer.Id: StarsAmount], String, ShareControllerAccountContext, Bool) -> Signal) } public struct ShareControllerAction { @@ -151,12 +150,12 @@ public final class ShareControllerParams { public let subject: ShareControllerSubject public let presetText: String? public let preferredAction: ShareControllerPreferredAction - public let showInChat: ((Message) -> Void)? + public let showInChat: ((EngineRawMessage) -> Void)? public let fromForeignApp: Bool public let segmentedValues: [ShareControllerSegmentedValue]? public let externalShare: Bool public let immediateExternalShare: Bool - public let immediatePeerId: PeerId? + public let immediatePeerId: EnginePeer.Id? public let updatedPresentationData: (initial: PresentationData, signal: Signal)? public let forceTheme: PresentationTheme? public let forcedActionTitle: String? @@ -165,8 +164,8 @@ public final class ShareControllerParams { public let actionCompleted: (() -> Void)? public let dismissed: ((Bool) -> Void)? - public let completed: (([PeerId]) -> Void)? - public let enqueued: (([PeerId], [Int64]) -> Void)? + public let completed: (([EnginePeer.Id]) -> Void)? + public let enqueued: (([EnginePeer.Id], [Int64]) -> Void)? public let shareStory: (() -> Void)? public let debugAction: (() -> Void)? public let onMediaTimestampLinkCopied: ((Int32?) -> Void)? @@ -177,12 +176,12 @@ public final class ShareControllerParams { subject: ShareControllerSubject, presetText: String? = nil, preferredAction: ShareControllerPreferredAction = .default, - showInChat: ((Message) -> Void)? = nil, + showInChat: ((EngineRawMessage) -> Void)? = nil, fromForeignApp: Bool = false, segmentedValues: [ShareControllerSegmentedValue]? = nil, externalShare: Bool = true, immediateExternalShare: Bool = false, - immediatePeerId: PeerId? = nil, + immediatePeerId: EnginePeer.Id? = nil, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, forceTheme: PresentationTheme? = nil, forcedActionTitle: String? = nil, @@ -190,8 +189,8 @@ public final class ShareControllerParams { collectibleItemInfo: TelegramCollectibleItemInfo? = nil, actionCompleted: (() -> Void)? = nil, dismissed: ((Bool) -> Void)? = nil, - completed: (([PeerId]) -> Void)? = nil, - enqueued: (([PeerId], [Int64]) -> Void)? = nil, + completed: (([EnginePeer.Id]) -> Void)? = nil, + enqueued: (([EnginePeer.Id], [Int64]) -> Void)? = nil, shareStory: (() -> Void)? = nil, debugAction: (() -> Void)? = nil, onMediaTimestampLinkCopied: ((Int32?) -> Void)? = nil, diff --git a/submodules/AuthorizationUI/BUILD b/submodules/AuthorizationUI/BUILD index cc280f1551..00851a3e15 100644 --- a/submodules/AuthorizationUI/BUILD +++ b/submodules/AuthorizationUI/BUILD @@ -12,7 +12,6 @@ swift_library( deps = [ "//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/TelegramCore:TelegramCore", - "//submodules/Postbox:Postbox", "//submodules/Display:Display", "//submodules/SSignalKit/SSignalKit", "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", diff --git a/submodules/AvatarNode/Sources/AvatarNode.swift b/submodules/AvatarNode/Sources/AvatarNode.swift index bbecec9430..e690da30ad 100644 --- a/submodules/AvatarNode/Sources/AvatarNode.swift +++ b/submodules/AvatarNode/Sources/AvatarNode.swift @@ -643,7 +643,7 @@ public final class AvatarNode: ASDisplayNode { let parameters: AvatarNodeParameters - if let peer = peer, let signal = peerAvatarImage(postbox: postbox, network: network, peerReference: PeerReference(peer), authorOfMessage: authorOfMessage, representation: representation, displayDimensions: displayDimensions, clipStyle: clipStyle, emptyColor: emptyColor, synchronousLoad: synchronousLoad, provideUnrounded: storeUnrounded, cutoutRect: cutoutRect) { + if let peer = peer, let signal = peerAvatarImage(postbox: postbox, peerReference: PeerReference(peer), authorOfMessage: authorOfMessage, representation: representation, displayDimensions: displayDimensions, clipStyle: clipStyle, emptyColor: emptyColor, synchronousLoad: synchronousLoad, provideUnrounded: storeUnrounded, cutoutRect: cutoutRect) { self.contents = nil self.displaySuspended = true self.imageReady.set(self.imageNode.contentReady) diff --git a/submodules/AvatarNode/Sources/PeerAvatar.swift b/submodules/AvatarNode/Sources/PeerAvatar.swift index 61b7742175..caf06427e9 100644 --- a/submodules/AvatarNode/Sources/PeerAvatar.swift +++ b/submodules/AvatarNode/Sources/PeerAvatar.swift @@ -27,11 +27,7 @@ public enum PeerAvatarImageType { case complete } -public func peerAvatarImageData(account: Account, peerReference: PeerReference?, authorOfMessage: MessageReference?, representation: TelegramMediaImageRepresentation?, synchronousLoad: Bool) -> Signal<(Data, PeerAvatarImageType)?, NoError>? { - return peerAvatarImageData(postbox: account.postbox, network: account.network, peerReference: peerReference, authorOfMessage: authorOfMessage, representation: representation, synchronousLoad: synchronousLoad) -} - -public func peerAvatarImageData(postbox: Postbox, network: Network, peerReference: PeerReference?, authorOfMessage: MessageReference?, representation: TelegramMediaImageRepresentation?, synchronousLoad: Bool) -> Signal<(Data, PeerAvatarImageType)?, NoError>? { +public func peerAvatarImageData(postbox: Postbox, peerReference: PeerReference?, authorOfMessage: MessageReference?, representation: TelegramMediaImageRepresentation?, synchronousLoad: Bool) -> Signal<(Data, PeerAvatarImageType)?, NoError>? { if let smallProfileImage = representation { let resourceData = postbox.mediaBox.resourceData(smallProfileImage.resource, attemptSynchronously: synchronousLoad) let imageData = resourceData @@ -92,7 +88,6 @@ public func peerAvatarImageData(postbox: Postbox, network: Network, peerReferenc public func peerAvatarCompleteImage(account: Account, peer: EnginePeer, forceProvidedRepresentation: Bool = false, representation: TelegramMediaImageRepresentation? = nil, size: CGSize, round: Bool = true, font: UIFont = avatarPlaceholderFont(size: 13.0), drawLetters: Bool = true, fullSize: Bool = false, blurred: Bool = false) -> Signal { return peerAvatarCompleteImage( postbox: account.postbox, - network: account.network, peer: peer, forceProvidedRepresentation: forceProvidedRepresentation, representation: representation, @@ -105,7 +100,7 @@ public func peerAvatarCompleteImage(account: Account, peer: EnginePeer, forcePro ) } -public func peerAvatarCompleteImage(postbox: Postbox, network: Network, peer: EnginePeer, forceProvidedRepresentation: Bool = false, representation: TelegramMediaImageRepresentation? = nil, size: CGSize, round: Bool = true, font: UIFont = avatarPlaceholderFont(size: 13.0), drawLetters: Bool = true, fullSize: Bool = false, blurred: Bool = false) -> Signal { +public func peerAvatarCompleteImage(postbox: Postbox, peer: EnginePeer, forceProvidedRepresentation: Bool = false, representation: TelegramMediaImageRepresentation? = nil, size: CGSize, round: Bool = true, font: UIFont = avatarPlaceholderFont(size: 13.0), drawLetters: Bool = true, fullSize: Bool = false, blurred: Bool = false) -> Signal { let iconSignal: Signal let clipStyle: AvatarNodeClipStyle @@ -126,8 +121,8 @@ public func peerAvatarCompleteImage(postbox: Postbox, network: Network, peer: En thumbnailRepresentation = peer.profileImageRepresentations.first } - if let signal = peerAvatarImage(postbox: postbox, network: network, peerReference: PeerReference(peer), authorOfMessage: nil, representation: thumbnailRepresentation, displayDimensions: size, clipStyle: clipStyle, blurred: blurred, inset: 0.0, emptyColor: nil, synchronousLoad: fullSize) { - if fullSize, let fullSizeSignal = peerAvatarImage(postbox: postbox, network: network, peerReference: PeerReference(peer), authorOfMessage: nil, representation: peer.profileImageRepresentations.last, displayDimensions: size, emptyColor: nil, synchronousLoad: true) { + if let signal = peerAvatarImage(postbox: postbox, peerReference: PeerReference(peer), authorOfMessage: nil,representation: thumbnailRepresentation, displayDimensions: size, clipStyle: clipStyle, blurred: blurred, inset: 0.0, emptyColor: nil, synchronousLoad: fullSize) { + if fullSize, let fullSizeSignal = peerAvatarImage(postbox: postbox, peerReference: PeerReference(peer), authorOfMessage: nil,representation: peer.profileImageRepresentations.last, displayDimensions: size, emptyColor: nil, synchronousLoad: true) { iconSignal = combineLatest(.single(nil) |> then(signal), .single(nil) |> then(fullSizeSignal)) |> mapToSignal { thumbnailImage, fullSizeImage -> Signal in if let fullSizeImage = fullSizeImage { @@ -174,7 +169,6 @@ public func peerAvatarCompleteImage(postbox: Postbox, network: Network, peer: En public func peerAvatarImage(account: Account, peerReference: PeerReference?, authorOfMessage: MessageReference?, representation: TelegramMediaImageRepresentation?, displayDimensions: CGSize = CGSize(width: 60.0, height: 60.0), clipStyle: AvatarNodeClipStyle = .round, blurred: Bool = false, inset: CGFloat = 0.0, emptyColor: UIColor? = nil, synchronousLoad: Bool = false, provideUnrounded: Bool = false, cutoutRect: CGRect? = nil) -> Signal<(UIImage, UIImage)?, NoError>? { return peerAvatarImage( postbox: account.postbox, - network: account.network, peerReference: peerReference, authorOfMessage: authorOfMessage, representation: representation, @@ -189,8 +183,8 @@ public func peerAvatarImage(account: Account, peerReference: PeerReference?, aut ) } -public func peerAvatarImage(postbox: Postbox, network: Network, peerReference: PeerReference?, authorOfMessage: MessageReference?, representation: TelegramMediaImageRepresentation?, displayDimensions: CGSize = CGSize(width: 60.0, height: 60.0), clipStyle: AvatarNodeClipStyle = .round, blurred: Bool = false, inset: CGFloat = 0.0, emptyColor: UIColor? = nil, synchronousLoad: Bool = false, provideUnrounded: Bool = false, cutoutRect: CGRect? = nil) -> Signal<(UIImage, UIImage)?, NoError>? { - if let imageData = peerAvatarImageData(postbox: postbox, network: network, peerReference: peerReference, authorOfMessage: authorOfMessage, representation: representation, synchronousLoad: synchronousLoad) { +public func peerAvatarImage(postbox: Postbox, peerReference: PeerReference?, authorOfMessage: MessageReference?, representation: TelegramMediaImageRepresentation?, displayDimensions: CGSize = CGSize(width: 60.0, height: 60.0), clipStyle: AvatarNodeClipStyle = .round, blurred: Bool = false, inset: CGFloat = 0.0, emptyColor: UIColor? = nil, synchronousLoad: Bool = false, provideUnrounded: Bool = false, cutoutRect: CGRect? = nil) -> Signal<(UIImage, UIImage)?, NoError>? { + if let imageData = peerAvatarImageData(postbox: postbox, peerReference: peerReference, authorOfMessage: authorOfMessage, representation: representation, synchronousLoad: synchronousLoad) { return imageData |> mapToSignal { data -> Signal<(UIImage, UIImage)?, NoError> in let generate = deferred { () -> Signal<(UIImage, UIImage)?, NoError> in diff --git a/submodules/BrowserUI/Sources/BrowserMarkdown.swift b/submodules/BrowserUI/Sources/BrowserMarkdown.swift index c3723b4075..d5669a19c7 100644 --- a/submodules/BrowserUI/Sources/BrowserMarkdown.swift +++ b/submodules/BrowserUI/Sources/BrowserMarkdown.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import TelegramCore import AccountContext import InstantPageUI @@ -211,7 +210,7 @@ private final class MarkdownConversionBudget { private struct MarkdownPageResult { let blocks: [InstantPageBlock] - let media: [MediaId: Media] + let media: [EngineMedia.Id: EngineRawMedia] } private enum MarkdownFormulaMode { @@ -315,7 +314,7 @@ private struct MarkdownInlineContent { } private struct MarkdownResolvedImage { - let mediaId: MediaId + let mediaId: EngineMedia.Id let inlineDimensions: PixelDimensions let caption: InstantPageCaption let linkUrl: String? @@ -340,7 +339,7 @@ private final class MarkdownConversionContext { private var nextRemoteMediaId: Int64 = 0 private var nextLocalMediaId: Int64 = 0 - private(set) var media: [MediaId: Media] = [:] + private(set) var media: [EngineMedia.Id: EngineRawMedia] = [:] init(context: AccountContext, documentURL: URL, formulasByPlaceholder: [String: MarkdownFormulaDescriptor], budget: MarkdownConversionBudget) { self.context = context @@ -426,14 +425,14 @@ private final class MarkdownConversionContext { } } - private func nextMediaId(namespace: Int32) -> MediaId { + private func nextMediaId(namespace: Int32) -> EngineMedia.Id { switch namespace { case Namespaces.Media.LocalImage: self.nextLocalMediaId += 1 - return MediaId(namespace: namespace, id: self.nextLocalMediaId) + return EngineMedia.Id(namespace: namespace, id: self.nextLocalMediaId) default: self.nextRemoteMediaId += 1 - return MediaId(namespace: namespace, id: self.nextRemoteMediaId) + return EngineMedia.Id(namespace: namespace, id: self.nextRemoteMediaId) } } } @@ -1028,7 +1027,7 @@ private func markdownWebpage(context: AccountContext, file: FileMediaReference, ) return TelegramMediaWebpage( - webpageId: MediaId(namespace: 0, id: 0), + webpageId: EngineMedia.Id(namespace: 0, id: 0), content: .Loaded( TelegramMediaWebpageLoadedContent( url: fileURL.absoluteString, diff --git a/submodules/BrowserUI/Sources/BrowserReadability.swift b/submodules/BrowserUI/Sources/BrowserReadability.swift index e021ad2d01..c63a4469bf 100644 --- a/submodules/BrowserUI/Sources/BrowserReadability.swift +++ b/submodules/BrowserUI/Sources/BrowserReadability.swift @@ -1,7 +1,6 @@ import Foundation import WebKit import AppBundle -import Postbox import TelegramCore import InstantPageUI @@ -115,14 +114,14 @@ private func parseJson(_ input: [String: Any], url: String) -> TelegramMediaWebp let byline = input["byline"] as? String let excerpt = input["excerpt"] as? String - var media: [MediaId: Media] = [:] + var media: [EngineMedia.Id: EngineRawMedia] = [:] let blocks = parseContent(input, url, &media) guard !blocks.isEmpty else { return nil } return TelegramMediaWebpage( - webpageId: MediaId(namespace: 0, id: 0), + webpageId: EngineMedia.Id(namespace: 0, id: 0), content: .Loaded( TelegramMediaWebpageLoadedContent( url: url, @@ -156,7 +155,7 @@ private func parseJson(_ input: [String: Any], url: String) -> TelegramMediaWebp ) } -private func parseContent(_ input: [String: Any], _ url: String, _ media: inout [MediaId: Media]) -> [InstantPageBlock] { +private func parseContent(_ input: [String: Any], _ url: String, _ media: inout [EngineMedia.Id: EngineRawMedia]) -> [InstantPageBlock] { let title = input["title"] as? String let byline = input["byline"] as? String let date = input["publishedTime"] as? String @@ -185,7 +184,7 @@ private func parseRichText(_ input: String) -> RichText { return .plain(input) } -private func parseRichText(_ input: [String: Any], _ media: inout [MediaId: Media]) -> RichText { +private func parseRichText(_ input: [String: Any], _ media: inout [EngineMedia.Id: EngineRawMedia]) -> RichText { var text: RichText if let string = input["content"] as? String { text = parseRichText(string) @@ -204,7 +203,7 @@ private func parseRichText(_ input: [String: Any], _ media: inout [MediaId: Medi return text } -private func parseRichText(_ input: [Any], _ media: inout [MediaId: Media]) -> RichText { +private func parseRichText(_ input: [Any], _ media: inout [EngineMedia.Id: EngineRawMedia]) -> RichText { var result: [RichText] = [] for item in input { @@ -258,7 +257,7 @@ private func parseRichText(_ input: [Any], _ media: inout [MediaId: Media]) -> R } else { height = 0 } - let id = MediaId(namespace: Namespaces.Media.CloudFile, id: Int64(media.count)) + let id = EngineMedia.Id(namespace: Namespaces.Media.CloudFile, id: Int64(media.count)) media[id] = TelegramMediaImage( imageId: id, representations: [ @@ -489,7 +488,7 @@ private func applyAnchor(_ input: RichText, item: [String: Any]) -> RichText { return .anchor(text: input, name: id) } -private func parseTable(_ input: [String: Any], _ media: inout [MediaId: Media]) -> InstantPageBlock { +private func parseTable(_ input: [String: Any], _ media: inout [EngineMedia.Id: EngineRawMedia]) -> InstantPageBlock { let title = (input["title"] as? String) ?? "" return .table( title: trim(applyAnchor(parseRichText(title), item: input)), @@ -499,7 +498,7 @@ private func parseTable(_ input: [String: Any], _ media: inout [MediaId: Media]) ) } -private func parseTableRows(_ input: [Any], _ media: inout [MediaId: Media]) -> [InstantPageTableRow] { +private func parseTableRows(_ input: [Any], _ media: inout [EngineMedia.Id: EngineRawMedia]) -> [InstantPageTableRow] { var result: [InstantPageTableRow] = [] for item in input { if let item = item as? [String: Any] { @@ -514,7 +513,7 @@ private func parseTableRows(_ input: [Any], _ media: inout [MediaId: Media]) -> return result } -private func parseTableRow(_ input: [String: Any], _ media: inout [MediaId: Media]) -> InstantPageTableRow { +private func parseTableRow(_ input: [String: Any], _ media: inout [EngineMedia.Id: EngineRawMedia]) -> InstantPageTableRow { var cells: [InstantPageTableCell] = [] if let content = input["content"] as? [Any] { @@ -552,7 +551,7 @@ private func parseTableRow(_ input: [String: Any], _ media: inout [MediaId: Medi return InstantPageTableRow(cells: cells) } -private func parseDetails(_ item: [String: Any], _ url: String, _ media: inout [MediaId: Media]) -> InstantPageBlock? { +private func parseDetails(_ item: [String: Any], _ url: String, _ media: inout [EngineMedia.Id: EngineRawMedia]) -> InstantPageBlock? { guard var content = item["contant"] as? [Any] else { return nil } @@ -576,7 +575,7 @@ private func parseDetails(_ item: [String: Any], _ url: String, _ media: inout [ } private let nonListCharacters = CharacterSet(charactersIn: "0123456789").inverted -private func parseList(_ input: [String: Any], _ url: String, _ media: inout [MediaId: Media]) -> InstantPageBlock? { +private func parseList(_ input: [String: Any], _ url: String, _ media: inout [EngineMedia.Id: EngineRawMedia]) -> InstantPageBlock? { guard let content = input["content"] as? [Any], let tag = input["tag"] as? String else { return nil } @@ -625,7 +624,7 @@ private func parseList(_ input: [String: Any], _ url: String, _ media: inout [Me return .list(items: items, ordered: ordered) } -private func parseImage(_ input: [String: Any], _ media: inout [MediaId: Media]) -> InstantPageBlock? { +private func parseImage(_ input: [String: Any], _ media: inout [EngineMedia.Id: EngineRawMedia]) -> InstantPageBlock? { guard let src = input["src"] as? String else { return nil } @@ -654,7 +653,7 @@ private func parseImage(_ input: [String: Any], _ media: inout [MediaId: Media]) height = 0 } - let id = MediaId(namespace: Namespaces.Media.CloudImage, id: Int64(media.count)) + let id = EngineMedia.Id(namespace: Namespaces.Media.CloudImage, id: Int64(media.count)) media[id] = TelegramMediaImage( imageId: id, representations: [ @@ -679,7 +678,7 @@ private func parseImage(_ input: [String: Any], _ media: inout [MediaId: Media]) ) } -private func parseVideo(_ input: [String: Any], _ media: inout [MediaId: Media]) -> InstantPageBlock? { +private func parseVideo(_ input: [String: Any], _ media: inout [EngineMedia.Id: EngineRawMedia]) -> InstantPageBlock? { guard let src = input["src"] as? String else { return nil } @@ -709,7 +708,7 @@ private func parseVideo(_ input: [String: Any], _ media: inout [MediaId: Media]) ) } -private func parseFigure(_ input: [String: Any], _ media: inout [MediaId: Media]) -> InstantPageBlock? { +private func parseFigure(_ input: [String: Any], _ media: inout [EngineMedia.Id: EngineRawMedia]) -> InstantPageBlock? { guard let content = input["content"] as? [Any] else { return nil } @@ -743,7 +742,7 @@ private func parseFigure(_ input: [String: Any], _ media: inout [MediaId: Media] return block } -private func parsePageBlocks(_ input: [Any], _ url: String, _ media: inout [MediaId: Media]) -> [InstantPageBlock] { +private func parsePageBlocks(_ input: [Any], _ url: String, _ media: inout [EngineMedia.Id: EngineRawMedia]) -> [InstantPageBlock] { var result: [InstantPageBlock] = [] for item in input { if let string = item as? String { diff --git a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift index 09eec8961f..9a5b05d768 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift @@ -28,7 +28,6 @@ import InstantPageUI import ChatInterfaceState import UndoUI import TextFormat -import Postbox import TelegramAnimatedStickerNode import AnimationCache import MultiAnimationRenderer @@ -63,12 +62,12 @@ final class ChatListSearchInteraction { let present: (ViewController, Any?) -> Void let dismissInput: () -> Void let getSelectedMessageIds: () -> Set? - let openStories: ((PeerId, ASDisplayNode) -> Void)? + let openStories: ((EnginePeer.Id, ASDisplayNode) -> Void)? let switchToFilter: (ChatListSearchPaneKey) -> Void let dismissSearch: () -> Void let openAdInfo: (ASDisplayNode, AdPeer) -> Void - init(openPeer: @escaping (EnginePeer, EnginePeer?, Int64?, Bool) -> Void, openDisabledPeer: @escaping (EnginePeer, Int64?, ChatListDisabledPeerReason) -> Void, openMessage: @escaping (EnginePeer, Int64?, EngineMessage.Id, Bool) -> Void, openUrl: @escaping (String) -> Void, clearRecentSearch: @escaping () -> Void, addContact: @escaping (String) -> Void, toggleMessageSelection: @escaping (EngineMessage.Id, Bool) -> Void, messageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void), mediaMessageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?) -> Void), peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, getSelectedMessageIds: @escaping () -> Set?, openStories: ((PeerId, ASDisplayNode) -> Void)?, switchToFilter: @escaping (ChatListSearchPaneKey) -> Void, dismissSearch: @escaping () -> Void, openAdInfo: @escaping (ASDisplayNode, AdPeer) -> Void) { + init(openPeer: @escaping (EnginePeer, EnginePeer?, Int64?, Bool) -> Void, openDisabledPeer: @escaping (EnginePeer, Int64?, ChatListDisabledPeerReason) -> Void, openMessage: @escaping (EnginePeer, Int64?, EngineMessage.Id, Bool) -> Void, openUrl: @escaping (String) -> Void, clearRecentSearch: @escaping () -> Void, addContact: @escaping (String) -> Void, toggleMessageSelection: @escaping (EngineMessage.Id, Bool) -> Void, messageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void), mediaMessageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?) -> Void), peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, getSelectedMessageIds: @escaping () -> Set?, openStories: ((EnginePeer.Id, ASDisplayNode) -> Void)?, switchToFilter: @escaping (ChatListSearchPaneKey) -> Void, dismissSearch: @escaping () -> Void, openAdInfo: @escaping (ASDisplayNode, AdPeer) -> Void) { self.openPeer = openPeer self.openDisabledPeer = openDisabledPeer self.openMessage = openMessage @@ -215,14 +214,14 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo let interaction = ChatListSearchInteraction(openPeer: { peer, chatPeer, threadId, value in originalOpenPeer(peer, chatPeer, threadId, value) if peer.id.namespace != Namespaces.Peer.SecretChat { - addAppLogEvent(postbox: context.account.postbox, type: "search_global_open_peer", peerId: peer.id) + context.engine.accountData.addAppLogEvent(type: "search_global_open_peer") } }, openDisabledPeer: { peer, threadId, reason in openDisabledPeer(peer, threadId, reason) }, openMessage: { peer, threadId, messageId, deactivateOnAction in originalOpenMessage(peer, threadId, messageId, deactivateOnAction) if peer.id.namespace != Namespaces.Peer.SecretChat { - addAppLogEvent(postbox: context.account.postbox, type: "search_global_open_message", peerId: peer.id, data: .dictionary(["msg_id": .number(Double(messageId.id))])) + context.engine.accountData.addAppLogEvent(type: "search_global_open_message", data: .dictionary(["msg_id": .number(Double(messageId.id))])) } }, openUrl: { [weak self] url in let _ = openUserGeneratedUrl(context: context, peerId: nil, url: url, concealed: false, present: { c in @@ -1396,16 +1395,16 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo return } - var resourceIds = Set() + var resourceIds = Set() for message in messages { for media in message.media { if let file = media as? TelegramMediaFile { - resourceIds.insert(file.resource.id) + resourceIds.insert(EngineMediaResource.Id(file.resource.id)) } } } - - let _ = (strongSelf.context.engine.resources.removeCachedResources(ids: resourceIds.map { EngineMediaResource.Id($0) }, force: true, notify: true) + + let _ = (strongSelf.context.engine.resources.removeCachedResources(ids: Array(resourceIds), force: true, notify: true) |> deliverOnMainQueue).startStandalone(completed: { guard let strongSelf = self else { return diff --git a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift index d702a7d420..0b47c1eacf 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift @@ -2732,7 +2732,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { } } else { if !finalQuery.isEmpty { - addAppLogEvent(postbox: context.account.postbox, type: "search_global_query") + context.engine.accountData.addAppLogEvent(type: "search_global_query") } let searchSignals: [Signal<(SearchMessagesResult, SearchMessagesState), NoError>] diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index abc01321fb..7cb442d48e 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import TelegramPresentationData import ItemListUI @@ -2624,18 +2623,18 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { } if case .chatList = item.chatListLocation, itemPeer.peerId == item.context.account.peerId, let message = messages.first { - var effectiveAuthor: Peer? = message.author?._asPeer() + var effectiveAuthor: EngineRawPeer? = message.author?._asPeer() if let forwardInfo = message.forwardInfo { effectiveAuthor = forwardInfo.author if effectiveAuthor == nil, let authorSignature = forwardInfo.authorSignature { - effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) + effectiveAuthor = TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.Empty, id: EnginePeer.Id.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) } } if let sourceAuthorInfo = message._asMessage().sourceAuthorInfo { if let originalAuthor = sourceAuthorInfo.originalAuthor, let peer = message.peers[originalAuthor] { effectiveAuthor = peer } else if let authorSignature = sourceAuthorInfo.originalAuthorName { - effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) + effectiveAuthor = TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.Empty, id: EnginePeer.Id.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) } } @@ -2960,10 +2959,10 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { case let .preview(dimensions, immediateThumbnailData, videoDuration): if let immediateThumbnailData { if let videoDuration { - let thumbnailMedia = TelegramMediaFile(fileId: MediaId(namespace: 0, id: index), partialReference: nil, resource: EmptyMediaResource(), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Video(duration: Double(videoDuration), size: dimensions ?? PixelDimensions(width: 1, height: 1), flags: [], preloadSize: nil, coverTime: nil, videoCodec: nil)], alternativeRepresentations: []) + let thumbnailMedia = TelegramMediaFile(fileId: EngineMedia.Id(namespace: 0, id: index), partialReference: nil, resource: EmptyMediaResource(), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Video(duration: Double(videoDuration), size: dimensions ?? PixelDimensions(width: 1, height: 1), flags: [], preloadSize: nil, coverTime: nil, videoCodec: nil)], alternativeRepresentations: []) contentImageSpecs.append(ContentImageSpec(message: message, media: .file(thumbnailMedia), size: fitSize)) } else { - let thumbnailMedia = TelegramMediaImage(imageId: MediaId(namespace: 0, id: index), representations: [], immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: []) + let thumbnailMedia = TelegramMediaImage(imageId: EngineMedia.Id(namespace: 0, id: index), representations: [], immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: []) contentImageSpecs.append(ContentImageSpec(message: message, media: .image(thumbnailMedia), size: fitSize)) } index += 1 @@ -3196,7 +3195,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { textAttributedString = attributedText let dateText: String - var topIndex: MessageIndex? + var topIndex: EngineMessage.Index? switch item.content { case .loading: break diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 8213296e4b..a835020531 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -16,7 +16,6 @@ import ChatListSearchItemHeader import PremiumUI import AnimationCache import MultiAnimationRenderer -import Postbox import ChatFolderLinkPreviewScreen import StoryContainerScreen import ChatListHeaderComponent @@ -1239,7 +1238,7 @@ public final class ChatListNode: ListViewImpl { case .Header, .Hole: return nil case let .PeerId(value): - return PeerId(value) + return EnginePeer.Id(value) case .ThreadId, .GroupId, .ContactId, .ArchiveIntro, .EmptyIntro, .SectionHeader, .Notice, .additionalCategory, .TopPeer: return nil } @@ -2618,7 +2617,7 @@ public final class ChatListNode: ListViewImpl { strongSelf.enqueueHistoryPreloadUpdate() } - var refreshStoryPeerIds: [PeerId] = [] + var refreshStoryPeerIds: [EnginePeer.Id] = [] var isHiddenItemVisible = false if let range = range.visibleRange { let entryCount = chatListView.filteredEntries.count diff --git a/submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift b/submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift index 0833307f24..5eea683612 100644 --- a/submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift +++ b/submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift @@ -1,7 +1,6 @@ import Foundation import UIKit import AsyncDisplayKit -import Postbox import SwiftSignalKit import TelegramCore import Display @@ -71,18 +70,18 @@ public final class ChatPanelInterfaceInteraction { case editPrice } - public let setupReplyMessage: (MessageId?, EngineMessageReplyInnerSubject?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void - public let setupEditMessage: (MessageId?, @escaping (ContainedViewLayoutTransition) -> Void) -> Void - public let beginMessageSelection: ([MessageId], @escaping (ContainedViewLayoutTransition) -> Void) -> Void + public let setupReplyMessage: (EngineMessage.Id?, EngineMessageReplyInnerSubject?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void + public let setupEditMessage: (EngineMessage.Id?, @escaping (ContainedViewLayoutTransition) -> Void) -> Void + public let beginMessageSelection: ([EngineMessage.Id], @escaping (ContainedViewLayoutTransition) -> Void) -> Void public let cancelMessageSelection: (ContainedViewLayoutTransition) -> Void public let deleteSelectedMessages: () -> Void public let reportSelectedMessages: () -> Void - public let reportMessages: ([Message], ContextControllerProtocol?) -> Void - public let blockMessageAuthor: (Message, ContextControllerProtocol?) -> Void - public let deleteMessages: ([Message], ContextControllerProtocol?, @escaping (ContextMenuActionResult) -> Void) -> Void + public let reportMessages: ([EngineRawMessage], ContextControllerProtocol?) -> Void + public let blockMessageAuthor: (EngineRawMessage, ContextControllerProtocol?) -> Void + public let deleteMessages: ([EngineRawMessage], ContextControllerProtocol?, @escaping (ContextMenuActionResult) -> Void) -> Void public let forwardSelectedMessages: () -> Void public let forwardCurrentForwardMessages: () -> Void - public let forwardMessages: ([Message]) -> Void + public let forwardMessages: ([EngineRawMessage]) -> Void public let updateForwardOptionsState: ((ChatInterfaceForwardOptionsState) -> ChatInterfaceForwardOptionsState) -> Void public let presentForwardOptions: (UIView) -> Void public let presentReplyOptions: (UIView) -> Void @@ -90,7 +89,7 @@ public final class ChatPanelInterfaceInteraction { public let presentSuggestPostOptions: () -> Void public let shareSelectedMessages: () -> Void public let updateTextInputStateAndMode: (@escaping (ChatTextInputState, ChatInputMode) -> (ChatTextInputState, ChatInputMode)) -> Void - public let updateInputModeAndDismissedButtonKeyboardMessageId: ((ChatPresentationInterfaceState) -> (ChatInputMode, MessageId?)) -> Void + public let updateInputModeAndDismissedButtonKeyboardMessageId: ((ChatPresentationInterfaceState) -> (ChatInputMode, EngineMessage.Id?)) -> Void public let openStickers: () -> Void public let editMessage: () -> Void public let beginMessageSearch: (ChatSearchDomain, String) -> Void @@ -100,17 +99,17 @@ public final class ChatPanelInterfaceInteraction { public let openSearchResults: () -> Void public let openCalendarSearch: () -> Void public let toggleMembersSearch: (Bool) -> Void - public let navigateToMessage: (MessageId, Bool, Bool, ChatLoadingMessageSubject) -> Void - public let navigateToChat: (PeerId) -> Void - public let navigateToProfile: (PeerId) -> Void + public let navigateToMessage: (EngineMessage.Id, Bool, Bool, ChatLoadingMessageSubject) -> Void + public let navigateToChat: (EnginePeer.Id) -> Void + public let navigateToProfile: (EnginePeer.Id) -> Void public let openPeerInfo: () -> Void public let togglePeerNotifications: () -> Void public let sendContextResult: (ChatContextResultCollection, ChatContextResult, ASDisplayNode, CGRect) -> Bool - public let sendBotCommand: (Peer, String) -> Void + public let sendBotCommand: (EngineRawPeer, String) -> Void public let sendShortcut: (Int32) -> Void public let openEditShortcuts: () -> Void public let sendBotStart: (String?) -> Void - public let botSwitchChatWithPayload: (PeerId, String) -> Void + public let botSwitchChatWithPayload: (EnginePeer.Id, String) -> Void public let beginMediaRecording: (Bool) -> Void public let finishMediaRecording: (ChatFinishMediaRecordingAction) -> Void public let stopMediaRecording: () -> Void @@ -122,20 +121,20 @@ public final class ChatPanelInterfaceInteraction { public let displayVideoUnmuteTip: (CGPoint?) -> Void public let switchMediaRecordingMode: () -> Void public let setupMessageAutoremoveTimeout: () -> Void - public let sendSticker: (FileMediaReference, Bool, UIView?, CGRect?, CALayer?, [ItemCollectionId]) -> Bool + public let sendSticker: (FileMediaReference, Bool, UIView?, CGRect?, CALayer?, [EngineItemCollectionId]) -> Bool public let editSticker: (TelegramMediaFile) -> Void public let unblockPeer: () -> Void - public let pinMessage: (MessageId, ContextControllerProtocol?) -> Void - public let unpinMessage: (MessageId, Bool, ContextControllerProtocol?) -> Void + public let pinMessage: (EngineMessage.Id, ContextControllerProtocol?) -> Void + public let unpinMessage: (EngineMessage.Id, Bool, ContextControllerProtocol?) -> Void public let unpinAllMessages: () -> Void - public let openPinnedList: (MessageId) -> Void + public let openPinnedList: (EngineMessage.Id) -> Void public let shareAccountContact: () -> Void public let reportPeer: () -> Void public let presentPeerContact: () -> Void public let dismissReportPeer: () -> Void public let deleteChat: () -> Void public let beginCall: (Bool) -> Void - public let toggleMessageStickerStarred: (MessageId) -> Void + public let toggleMessageStickerStarred: (EngineMessage.Id) -> Void public let presentController: (ViewController, Any?) -> Void public let presentControllerInCurrent: (ViewController, Any?) -> Void public let getNavigationController: () -> NavigationController? @@ -143,8 +142,8 @@ public final class ChatPanelInterfaceInteraction { public let navigateFeed: () -> Void public let openGrouping: () -> Void public let toggleSilentPost: () -> Void - public let requestUnvoteInMessage: (MessageId) -> Void - public let requestStopPollInMessage: (MessageId) -> Void + public let requestUnvoteInMessage: (EngineMessage.Id) -> Void + public let requestStopPollInMessage: (EngineMessage.Id) -> Void public let updateInputLanguage: (@escaping (String?) -> String?) -> Void public let unarchiveChat: () -> Void public let openLinkEditing: () -> Void @@ -156,9 +155,9 @@ public final class ChatPanelInterfaceInteraction { public let openPeersNearby: () -> Void public let unarchivePeer: () -> Void public let scrollToTop: () -> Void - public let viewReplies: (MessageId?, ChatReplyThreadMessage) -> Void + public let viewReplies: (EngineMessage.Id?, ChatReplyThreadMessage) -> Void public let activatePinnedListPreview: (ASDisplayNode, ContextGesture) -> Void - public let editMessageMedia: (MessageId, Bool) -> Void + public let editMessageMedia: (EngineMessage.Id, Bool) -> Void public let joinGroupCall: (CachedChannelData.ActiveCall) -> Void public let presentInviteMembers: () -> Void public let presentGigagroupHelp: () -> Void @@ -179,7 +178,7 @@ public final class ChatPanelInterfaceInteraction { public let addDoNotTranslateLanguage: (String) -> Void public let hideTranslationPanel: () -> Void public let openPremiumGift: () -> Void - public let openSuggestPost: (Message?, OpenSuggestPostMode) -> Void + public let openSuggestPost: (EngineRawMessage?, OpenSuggestPostMode) -> Void public let openPremiumRequiredForMessaging: () -> Void public let openStarsPurchase: (Int64?) -> Void public let openMessagePayment: () -> Void @@ -190,7 +189,7 @@ public final class ChatPanelInterfaceInteraction { public let openBoostToUnrestrict: () -> Void public let updateRecordingTrimRange: (Double, Double, Bool, Bool) -> Void public let dismissAllTooltips: () -> Void - public let editTodoMessage: (MessageId, Int32?, Bool) -> Void + public let editTodoMessage: (EngineMessage.Id, Int32?, Bool) -> Void public let dismissUrlPreview: () -> Void public let dismissForwardMessages: () -> Void public let dismissSuggestPost: () -> Void @@ -204,18 +203,18 @@ public final class ChatPanelInterfaceInteraction { public let statuses: ChatPanelInterfaceInteractionStatuses? public init( - setupReplyMessage: @escaping (MessageId?, EngineMessageReplyInnerSubject?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void, - setupEditMessage: @escaping (MessageId?, @escaping (ContainedViewLayoutTransition) -> Void) -> Void, - beginMessageSelection: @escaping ([MessageId], @escaping (ContainedViewLayoutTransition) -> Void) -> Void, + setupReplyMessage: @escaping (EngineMessage.Id?, EngineMessageReplyInnerSubject?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void, + setupEditMessage: @escaping (EngineMessage.Id?, @escaping (ContainedViewLayoutTransition) -> Void) -> Void, + beginMessageSelection: @escaping ([EngineMessage.Id], @escaping (ContainedViewLayoutTransition) -> Void) -> Void, cancelMessageSelection: @escaping (ContainedViewLayoutTransition) -> Void, deleteSelectedMessages: @escaping () -> Void, reportSelectedMessages: @escaping () -> Void, - reportMessages: @escaping ([Message], ContextControllerProtocol?) -> Void, - blockMessageAuthor: @escaping (Message, ContextControllerProtocol?) -> Void, - deleteMessages: @escaping ([Message], ContextControllerProtocol?, @escaping (ContextMenuActionResult) -> Void) -> Void, + reportMessages: @escaping ([EngineRawMessage], ContextControllerProtocol?) -> Void, + blockMessageAuthor: @escaping (EngineRawMessage, ContextControllerProtocol?) -> Void, + deleteMessages: @escaping ([EngineRawMessage], ContextControllerProtocol?, @escaping (ContextMenuActionResult) -> Void) -> Void, forwardSelectedMessages: @escaping () -> Void, forwardCurrentForwardMessages: @escaping () -> Void, - forwardMessages: @escaping ([Message]) -> Void, + forwardMessages: @escaping ([EngineRawMessage]) -> Void, updateForwardOptionsState: @escaping ((ChatInterfaceForwardOptionsState) -> ChatInterfaceForwardOptionsState) -> Void, presentForwardOptions: @escaping (UIView) -> Void, presentReplyOptions: @escaping (UIView) -> Void, @@ -223,7 +222,7 @@ public final class ChatPanelInterfaceInteraction { presentSuggestPostOptions: @escaping () -> Void, shareSelectedMessages: @escaping () -> Void, updateTextInputStateAndMode: @escaping ((ChatTextInputState, ChatInputMode) -> (ChatTextInputState, ChatInputMode)) -> Void, - updateInputModeAndDismissedButtonKeyboardMessageId: @escaping ((ChatPresentationInterfaceState) -> (ChatInputMode, MessageId?)) -> Void, + updateInputModeAndDismissedButtonKeyboardMessageId: @escaping ((ChatPresentationInterfaceState) -> (ChatInputMode, EngineMessage.Id?)) -> Void, openStickers: @escaping () -> Void, editMessage: @escaping () -> Void, beginMessageSearch: @escaping (ChatSearchDomain, String) -> Void, @@ -233,17 +232,17 @@ public final class ChatPanelInterfaceInteraction { navigateMessageSearch: @escaping (ChatPanelSearchNavigationAction) -> Void, openCalendarSearch: @escaping () -> Void, toggleMembersSearch: @escaping (Bool) -> Void, - navigateToMessage: @escaping (MessageId, Bool, Bool, ChatLoadingMessageSubject) -> Void, - navigateToChat: @escaping (PeerId) -> Void, - navigateToProfile: @escaping (PeerId) -> Void, + navigateToMessage: @escaping (EngineMessage.Id, Bool, Bool, ChatLoadingMessageSubject) -> Void, + navigateToChat: @escaping (EnginePeer.Id) -> Void, + navigateToProfile: @escaping (EnginePeer.Id) -> Void, openPeerInfo: @escaping () -> Void, togglePeerNotifications: @escaping () -> Void, sendContextResult: @escaping (ChatContextResultCollection, ChatContextResult, ASDisplayNode, CGRect) -> Bool, - sendBotCommand: @escaping (Peer, String) -> Void, + sendBotCommand: @escaping (EngineRawPeer, String) -> Void, sendShortcut: @escaping (Int32) -> Void, openEditShortcuts: @escaping () -> Void, sendBotStart: @escaping (String?) -> Void, - botSwitchChatWithPayload: @escaping (PeerId, String) -> Void, + botSwitchChatWithPayload: @escaping (EnginePeer.Id, String) -> Void, beginMediaRecording: @escaping (Bool) -> Void, finishMediaRecording: @escaping (ChatFinishMediaRecordingAction) -> Void, stopMediaRecording: @escaping () -> Void, @@ -255,20 +254,20 @@ public final class ChatPanelInterfaceInteraction { displayVideoUnmuteTip: @escaping (CGPoint?) -> Void, switchMediaRecordingMode: @escaping () -> Void, setupMessageAutoremoveTimeout: @escaping () -> Void, - sendSticker: @escaping (FileMediaReference, Bool, UIView?, CGRect?, CALayer?, [ItemCollectionId]) -> Bool, + sendSticker: @escaping (FileMediaReference, Bool, UIView?, CGRect?, CALayer?, [EngineItemCollectionId]) -> Bool, editSticker: @escaping (TelegramMediaFile) -> Void, unblockPeer: @escaping () -> Void, - pinMessage: @escaping (MessageId, ContextControllerProtocol?) -> Void, - unpinMessage: @escaping (MessageId, Bool, ContextControllerProtocol?) -> Void, + pinMessage: @escaping (EngineMessage.Id, ContextControllerProtocol?) -> Void, + unpinMessage: @escaping (EngineMessage.Id, Bool, ContextControllerProtocol?) -> Void, unpinAllMessages: @escaping () -> Void, - openPinnedList: @escaping (MessageId) -> Void, + openPinnedList: @escaping (EngineMessage.Id) -> Void, shareAccountContact: @escaping () -> Void, reportPeer: @escaping () -> Void, presentPeerContact: @escaping () -> Void, dismissReportPeer: @escaping () -> Void, deleteChat: @escaping () -> Void, beginCall: @escaping (Bool) -> Void, - toggleMessageStickerStarred: @escaping (MessageId) -> Void, + toggleMessageStickerStarred: @escaping (EngineMessage.Id) -> Void, presentController: @escaping (ViewController, Any?) -> Void, presentControllerInCurrent: @escaping (ViewController, Any?) -> Void, getNavigationController: @escaping () -> NavigationController?, @@ -276,8 +275,8 @@ public final class ChatPanelInterfaceInteraction { navigateFeed: @escaping () -> Void, openGrouping: @escaping () -> Void, toggleSilentPost: @escaping () -> Void, - requestUnvoteInMessage: @escaping (MessageId) -> Void, - requestStopPollInMessage: @escaping (MessageId) -> Void, + requestUnvoteInMessage: @escaping (EngineMessage.Id) -> Void, + requestStopPollInMessage: @escaping (EngineMessage.Id) -> Void, updateInputLanguage: @escaping ((String?) -> String?) -> Void, unarchiveChat: @escaping () -> Void, openLinkEditing: @escaping () -> Void, @@ -289,13 +288,13 @@ public final class ChatPanelInterfaceInteraction { displaySearchResultsTooltip: @escaping (ASDisplayNode, CGRect) -> Void, unarchivePeer: @escaping () -> Void, scrollToTop: @escaping () -> Void, - viewReplies: @escaping (MessageId?, ChatReplyThreadMessage) -> Void, + viewReplies: @escaping (EngineMessage.Id?, ChatReplyThreadMessage) -> Void, activatePinnedListPreview: @escaping (ASDisplayNode, ContextGesture) -> Void, joinGroupCall: @escaping (CachedChannelData.ActiveCall) -> Void, presentInviteMembers: @escaping () -> Void, presentGigagroupHelp: @escaping () -> Void, openMonoforum: @escaping () -> Void, - editMessageMedia: @escaping (MessageId, Bool) -> Void, + editMessageMedia: @escaping (EngineMessage.Id, Bool) -> Void, updateShowCommands: @escaping ((Bool) -> Bool) -> Void, updateShowSendAsPeers: @escaping ((Bool) -> Bool) -> Void, openInviteRequests: @escaping () -> Void, @@ -312,14 +311,14 @@ public final class ChatPanelInterfaceInteraction { addDoNotTranslateLanguage: @escaping (String) -> Void, hideTranslationPanel: @escaping () -> Void, openPremiumGift: @escaping () -> Void, - openSuggestPost: @escaping (Message?, OpenSuggestPostMode) -> Void, + openSuggestPost: @escaping (EngineRawMessage?, OpenSuggestPostMode) -> Void, openPremiumRequiredForMessaging: @escaping () -> Void, openStarsPurchase: @escaping (Int64?) -> Void, openMessagePayment: @escaping () -> Void, openBoostToUnrestrict: @escaping () -> Void, updateRecordingTrimRange: @escaping (Double, Double, Bool, Bool) -> Void, dismissAllTooltips: @escaping () -> Void, - editTodoMessage: @escaping (MessageId, Int32?, Bool) -> Void, + editTodoMessage: @escaping (EngineMessage.Id, Int32?, Bool) -> Void, dismissUrlPreview: @escaping () -> Void, dismissForwardMessages: @escaping () -> Void, dismissSuggestPost: @escaping () -> Void, @@ -472,7 +471,7 @@ public final class ChatPanelInterfaceInteraction { public convenience init( updateTextInputStateAndMode: @escaping ((ChatTextInputState, ChatInputMode) -> (ChatTextInputState, ChatInputMode)) -> Void, - updateInputModeAndDismissedButtonKeyboardMessageId: @escaping ((ChatPresentationInterfaceState) -> (ChatInputMode, MessageId?)) -> Void, + updateInputModeAndDismissedButtonKeyboardMessageId: @escaping ((ChatPresentationInterfaceState) -> (ChatInputMode, EngineMessage.Id?)) -> Void, openLinkEditing: @escaping () -> Void ) { self.init(setupReplyMessage: { _, _, _ in diff --git a/submodules/GalleryData/BUILD b/submodules/GalleryData/BUILD index ec0ae7d4d8..83e10f7cc2 100644 --- a/submodules/GalleryData/BUILD +++ b/submodules/GalleryData/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/Display:Display", - "//submodules/Postbox:Postbox", "//submodules/TelegramCore:TelegramCore", "//submodules/TelegramPresentationData:TelegramPresentationData", "//submodules/AccountContext:AccountContext", diff --git a/submodules/GalleryData/Sources/GalleryData.swift b/submodules/GalleryData/Sources/GalleryData.swift index 3e8e70523f..b9c578e07c 100644 --- a/submodules/GalleryData/Sources/GalleryData.swift +++ b/submodules/GalleryData/Sources/GalleryData.swift @@ -1,7 +1,6 @@ import Foundation import Display import AsyncDisplayKit -import Postbox import TelegramCore import SwiftSignalKit import PassKit @@ -19,20 +18,20 @@ import StoryContainerScreen public enum ChatMessageGalleryControllerData { case url(String) case pass(TelegramMediaFile) - case instantPage(InstantPageGalleryController, Int, Media) + case instantPage(InstantPageGalleryController, Int, EngineRawMedia) case map(TelegramMediaMap) case stickerPack(StickerPackReference, TelegramMediaFile?) case audio(TelegramMediaFile) case document(TelegramMediaFile, Bool) case gallery(Signal) case secretGallery(SecretMediaPreviewController) - case chatAvatars(AvatarGalleryController, Media) + case chatAvatars(AvatarGalleryController, EngineRawMedia) case theme(TelegramMediaFile) - case other(Media) + case other(EngineRawMedia) case story(Signal) } -private func instantPageBlockMedia(pageId: MediaId, block: InstantPageBlock, media: [MediaId: Media], counter: inout Int) -> [InstantPageGalleryEntry] { +private func instantPageBlockMedia(pageId: EngineMedia.Id, block: InstantPageBlock, media: [EngineMedia.Id: EngineRawMedia], counter: inout Int) -> [InstantPageGalleryEntry] { switch block { case let .image(id, caption, _, _): if let m = media[id] { @@ -64,7 +63,7 @@ private func instantPageBlockMedia(pageId: MediaId, block: InstantPageBlock, med return [] } -public func instantPageGalleryMedia(webpageId: MediaId, page: InstantPage.Accessor, galleryMedia: Media) -> [InstantPageGalleryEntry] { +public func instantPageGalleryMedia(webpageId: EngineMedia.Id, page: InstantPage.Accessor, galleryMedia: EngineRawMedia) -> [InstantPageGalleryEntry] { var result: [InstantPageGalleryEntry] = [] var counter: Int = 0 @@ -96,9 +95,9 @@ public func instantPageGalleryMedia(webpageId: MediaId, page: InstantPage.Access public func chatMessageGalleryControllerData( context: AccountContext, chatLocation: ChatLocation?, - chatFilterTag: MemoryBuffer?, + chatFilterTag: EngineMemoryBuffer?, chatLocationContextHolder: Atomic?, - message: Message, + message: EngineRawMessage, mediaSubject: GalleryMediaSubject? = nil, navigationController: NavigationController?, standalone: Bool, @@ -113,10 +112,10 @@ public func chatMessageGalleryControllerData( standalone = true } - var galleryMedia: Media? - var otherMedia: Media? + var galleryMedia: EngineRawMedia? + var otherMedia: EngineRawMedia? var instantPageMedia: (TelegramMediaWebpage, [InstantPageGalleryEntry])? - if message.media.isEmpty, let entities = message.textEntitiesAttribute?.entities, entities.count == 1, let firstEntity = entities.first, case let .CustomEmoji(_, fileId) = firstEntity.type, let file = message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile { + if message.media.isEmpty, let entities = message.textEntitiesAttribute?.entities, entities.count == 1, let firstEntity = entities.first, case let .CustomEmoji(_, fileId) = firstEntity.type, let file = message.associatedMedia[EngineMedia.Id(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile { for attribute in file.attributes { if case let .CustomEmoji(_, _, _, reference) = attribute { if let reference = reference { @@ -356,25 +355,11 @@ public func chatMessageGalleryControllerData( } public enum ChatMessagePreviewControllerData { - case instantPage(InstantPageGalleryController, Int, Media) + case instantPage(InstantPageGalleryController, Int, EngineRawMedia) case gallery(GalleryController) } -public func chatMessagePreviewControllerData(context: AccountContext, chatLocation: ChatLocation?, chatFilterTag: MemoryBuffer?, chatLocationContextHolder: Atomic?, message: Message, standalone: Bool, reverseMessageGalleryOrder: Bool, navigationController: NavigationController?) -> ChatMessagePreviewControllerData? { - if let mediaData = chatMessageGalleryControllerData(context: context, chatLocation: chatLocation, chatFilterTag: chatFilterTag, chatLocationContextHolder: chatLocationContextHolder, message: message, navigationController: navigationController, standalone: standalone, reverseMessageGalleryOrder: reverseMessageGalleryOrder, mode: .default, source: nil, synchronousLoad: true, actionInteraction: nil) { - switch mediaData { - case .gallery: - break - case let .instantPage(gallery, centralIndex, galleryMedia): - return .instantPage(gallery, centralIndex, galleryMedia) - default: - break - } - } - return nil -} - -public func chatMediaListPreviewControllerData(context: AccountContext, chatLocation: ChatLocation?, chatFilterTag: MemoryBuffer?, chatLocationContextHolder: Atomic?, message: Message, standalone: Bool, reverseMessageGalleryOrder: Bool, navigationController: NavigationController?) -> Signal { +public func chatMediaListPreviewControllerData(context: AccountContext, chatLocation: ChatLocation?, chatFilterTag: EngineMemoryBuffer?, chatLocationContextHolder: Atomic?, message: EngineRawMessage, standalone: Bool, reverseMessageGalleryOrder: Bool, navigationController: NavigationController?) -> Signal { if let mediaData = chatMessageGalleryControllerData(context: context, chatLocation: chatLocation, chatFilterTag: chatFilterTag, chatLocationContextHolder: chatLocationContextHolder, message: message, navigationController: navigationController, standalone: standalone, reverseMessageGalleryOrder: reverseMessageGalleryOrder, mode: .default, source: nil, synchronousLoad: true, actionInteraction: nil) { switch mediaData { case let .gallery(gallery): diff --git a/submodules/GalleryUI/Sources/Items/ChatDocumentGalleryItem.swift b/submodules/GalleryUI/Sources/Items/ChatDocumentGalleryItem.swift index 7d1b52c291..c3f795abc0 100644 --- a/submodules/GalleryUI/Sources/Items/ChatDocumentGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/ChatDocumentGalleryItem.swift @@ -1,7 +1,6 @@ import Foundation import UIKit import AsyncDisplayKit -import Postbox import Display import SwiftSignalKit import WebKit @@ -17,10 +16,10 @@ class ChatDocumentGalleryItem: GalleryItem { let context: AccountContext let presentationData: PresentationData - let message: Message - let location: MessageHistoryEntryLocation? + let message: EngineRawMessage + let location: EngineMessageHistoryEntryLocation? - init(context: AccountContext, presentationData: PresentationData, message: Message, location: MessageHistoryEntryLocation?) { + init(context: AccountContext, presentationData: PresentationData, message: EngineRawMessage, location: EngineMessageHistoryEntryLocation?) { self.context = context self.presentationData = presentationData self.message = message @@ -104,7 +103,7 @@ class ChatDocumentGalleryItemNode: ZoomableContentGalleryItemNode, WKNavigationD private var itemIsVisible = false - private var message: Message? + private var message: EngineRawMessage? private let footerContentNode: ChatItemGalleryFooterContentNode @@ -163,7 +162,7 @@ class ChatDocumentGalleryItemNode: ZoomableContentGalleryItemNode, WKNavigationD transition.updateFrame(node: self.statusNode, frame: CGRect(origin: CGPoint(), size: statusSize)) } - fileprivate func setMessage(_ message: Message) { + fileprivate func setMessage(_ message: EngineRawMessage) { self.footerContentNode.setMessage(message) } @@ -187,7 +186,7 @@ class ChatDocumentGalleryItemNode: ZoomableContentGalleryItemNode, WKNavigationD } } - private func setupStatus(context: AccountContext, resource: MediaResource) { + private func setupStatus(context: AccountContext, resource: EngineRawMediaResource) { self.statusDisposable.set((context.engine.resources.status(resource: EngineMediaResource(resource)) |> deliverOnMainQueue).start(next: { [weak self] status in if let strongSelf = self { diff --git a/submodules/GalleryUI/Sources/Items/ChatExternalFileGalleryItem.swift b/submodules/GalleryUI/Sources/Items/ChatExternalFileGalleryItem.swift index 67f671959d..88027cbb47 100644 --- a/submodules/GalleryUI/Sources/Items/ChatExternalFileGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/ChatExternalFileGalleryItem.swift @@ -1,7 +1,6 @@ import Foundation import UIKit import AsyncDisplayKit -import Postbox import Display import SwiftSignalKit import WebKit @@ -17,10 +16,10 @@ class ChatExternalFileGalleryItem: GalleryItem { let context: AccountContext let presentationData: PresentationData - let message: Message - let location: MessageHistoryEntryLocation? - - init(context: AccountContext, presentationData: PresentationData, message: Message, location: MessageHistoryEntryLocation?) { + let message: EngineRawMessage + let location: EngineMessageHistoryEntryLocation? + + init(context: AccountContext, presentationData: PresentationData, message: EngineRawMessage, location: EngineMessageHistoryEntryLocation?) { self.context = context self.presentationData = presentationData self.message = message @@ -78,7 +77,7 @@ class ChatExternalFileGalleryItemNode: GalleryItemNode { private var itemIsVisible = false - private var message: Message? + private var message: EngineRawMessage? private let footerContentNode: ChatItemGalleryFooterContentNode @@ -164,7 +163,7 @@ class ChatExternalFileGalleryItemNode: GalleryItemNode { transition.updateFrame(node: self.statusNode, frame: CGRect(origin: CGPoint(), size: statusSize)) } - fileprivate func setMessage(_ message: Message) { + fileprivate func setMessage(_ message: EngineRawMessage) { self.message = message self.footerContentNode.setMessage(message) } @@ -182,7 +181,7 @@ class ChatExternalFileGalleryItemNode: GalleryItemNode { } } - private func setupStatus(context: AccountContext, resource: MediaResource) { + private func setupStatus(context: AccountContext, resource: EngineRawMediaResource) { self.statusDisposable.set((context.engine.resources.status(resource: EngineMediaResource(resource)) |> deliverOnMainQueue).start(next: { [weak self] status in if let strongSelf = self { diff --git a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift index ba222b9a7a..015887386d 100644 --- a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift @@ -2949,7 +2949,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { } if swipeUpToClose { - addAppLogEvent(postbox: self.context.account.postbox, type: "swipe_up_close", peerId: self.context.account.peerId) + self.context.engine.accountData.addAppLogEvent(type: "swipe_up_close") return false } @@ -2957,7 +2957,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { if #available(iOS 15.0, *) { if let nativePictureInPictureContent = self.nativePictureInPictureContent as? NativePictureInPictureContentImpl { - addAppLogEvent(postbox: self.context.account.postbox, type: "swipe_up_pip", peerId: self.context.account.peerId) + self.context.engine.accountData.addAppLogEvent(type: "swipe_up_pip") nativePictureInPictureContent.beginPictureInPicture() return true } @@ -2966,7 +2966,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { } override func maybePerformActionForSwipeDownDismiss() -> Bool { - addAppLogEvent(postbox: self.context.account.postbox, type: "swipe_down_close", peerId: self.context.account.peerId) + self.context.engine.accountData.addAppLogEvent(type: "swipe_down_close") return false } @@ -3184,7 +3184,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { self.activePictureInPictureController = nil self.activePictureInPictureNavigationController = nil - addAppLogEvent(postbox: self.context.account.postbox, type: "pip_close_btn", peerId: self.context.account.peerId) + self.context.engine.accountData.addAppLogEvent(type: "pip_close_btn") } }, expand: { [weak self] completion in didExpand = true @@ -3234,7 +3234,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { if #available(iOS 15.0, *) { if let nativePictureInPictureContent = self.nativePictureInPictureContent as? NativePictureInPictureContentImpl { - addAppLogEvent(postbox: self.context.account.postbox, type: "pip_btn", peerId: self.context.account.peerId) + self.context.engine.accountData.addAppLogEvent(type: "pip_btn") nativePictureInPictureContent.beginPictureInPicture() return } diff --git a/submodules/GalleryUI/Sources/Items/VideoAdComponent.swift b/submodules/GalleryUI/Sources/Items/VideoAdComponent.swift index 5bdb216175..31b54db45f 100644 --- a/submodules/GalleryUI/Sources/Items/VideoAdComponent.swift +++ b/submodules/GalleryUI/Sources/Items/VideoAdComponent.swift @@ -5,7 +5,6 @@ import SwiftSignalKit import ComponentFlow import MultilineTextComponent import MultilineTextWithEntitiesComponent -import Postbox import TelegramCore import TelegramPresentationData import ContextUI @@ -111,7 +110,7 @@ final class VideoAdComponent: Component { let titleString = component.message.author?.compactDisplayTitle ?? "" - var media: Media? + var media: EngineRawMedia? if let photo = component.message.media.first as? TelegramMediaImage { media = photo } else if let file = component.message.media.first as? TelegramMediaFile { diff --git a/submodules/ICloudResources/BUILD b/submodules/ICloudResources/BUILD index b282708cee..9b4faf0021 100644 --- a/submodules/ICloudResources/BUILD +++ b/submodules/ICloudResources/BUILD @@ -11,7 +11,6 @@ swift_library( ], deps = [ "//submodules/TelegramCore", - "//submodules/Postbox", "//submodules/SSignalKit/SwiftSignalKit", "//submodules/Display", "//submodules/Pdf", diff --git a/submodules/ICloudResources/Sources/ICloudResources.swift b/submodules/ICloudResources/Sources/ICloudResources.swift index 9658b88460..b13f4dbbd0 100644 --- a/submodules/ICloudResources/Sources/ICloudResources.swift +++ b/submodules/ICloudResources/Sources/ICloudResources.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import TelegramCore import SwiftSignalKit import Display @@ -13,9 +12,9 @@ public struct ICloudFileResourceId { public var uniqueId: String { if self.thumbnail { - return "icloud-thumb-\(persistentHash32(self.urlData))" + return "icloud-thumb-\(enginePersistentHash32(self.urlData))" } else { - return "icloud-\(persistentHash32(self.urlData))" + return "icloud-\(enginePersistentHash32(self.urlData))" } } @@ -37,21 +36,21 @@ public class ICloudFileResource: TelegramMediaResource { self.thumbnail = thumbnail } - public required init(decoder: PostboxDecoder) { + public required init(decoder: EnginePostboxDecoder) { self.urlData = decoder.decodeStringForKey("url", orElse: "") self.thumbnail = decoder.decodeBoolForKey("thumb", orElse: false) } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeString(self.urlData, forKey: "url") encoder.encodeBool(self.thumbnail, forKey: "thumb") } - public var id: MediaResourceId { - return MediaResourceId(ICloudFileResourceId(urlData: self.urlData, thumbnail: self.thumbnail).uniqueId) + public var id: EngineRawMediaResourceId { + return EngineRawMediaResourceId(ICloudFileResourceId(urlData: self.urlData, thumbnail: self.thumbnail).uniqueId) } - - public func isEqual(to: MediaResource) -> Bool { + + public func isEqual(to: EngineRawMediaResource) -> Bool { if let to = to as? ICloudFileResource { if self.urlData != to.urlData || self.thumbnail != to.thumbnail { return false @@ -252,7 +251,7 @@ public func iCloudFileDescription(_ url: URL) -> Signal Signal { +public func fetchICloudFileResource(resource: ICloudFileResource) -> Signal { return Signal { subscriber in subscriber.putNext(.reset) @@ -306,7 +305,7 @@ public func fetchICloudFileResource(resource: ICloudFileResource) -> Signal Bool { + + public func isEqual(to: EngineRawMediaResource) -> Bool { if let to = to as? InstantPageExternalMediaResource { return self.url == to.url } else { diff --git a/submodules/LegacyDataImport/BUILD b/submodules/LegacyDataImport/BUILD deleted file mode 100644 index 199ce4f386..0000000000 --- a/submodules/LegacyDataImport/BUILD +++ /dev/null @@ -1,23 +0,0 @@ -load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") - -swift_library( - name = "LegacyDataImport", - module_name = "LegacyDataImport", - srcs = glob([ - "Sources/**/*.swift", - ]), - deps = [ - "//submodules/TelegramCore:TelegramCore", - "//submodules/SyncCore:SyncCore", - "//submodules/Postbox:Postbox", - "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", - "//submodules/TelegramNotices:TelegramNotices", - "//submodules/TelegramUIPreferences:TelegramUIPreferences", - "//submodules/RadialStatusNode:RadialStatusNode", - "//submodules/LegacyComponents:LegacyComponents", - "//submodules/LegacyDataImport/Impl:LegacyDataImportImpl", - ], - visibility = [ - "//visibility:public", - ], -) diff --git a/submodules/LegacyDataImport/Impl/BUILD b/submodules/LegacyDataImport/Impl/BUILD deleted file mode 100644 index 4bab57e0ce..0000000000 --- a/submodules/LegacyDataImport/Impl/BUILD +++ /dev/null @@ -1,22 +0,0 @@ - -objc_library( - name = "LegacyDataImportImpl", - enable_modules = True, - module_name = "LegacyDataImportImpl", - srcs = glob([ - "Sources/**/*.m", - "Sources/**/*.h", - ]), - hdrs = glob([ - "PublicHeaders/**/*.h", - ]), - includes = [ - "PublicHeaders", - ], - sdk_frameworks = [ - "Foundation", - ], - visibility = [ - "//visibility:public", - ], -) diff --git a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/LegacyDataImportImpl.h b/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/LegacyDataImportImpl.h deleted file mode 100644 index 7a94876eb4..0000000000 --- a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/LegacyDataImportImpl.h +++ /dev/null @@ -1,7 +0,0 @@ -#import - -#import -#import -#import - - diff --git a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGAutoDownloadPreferences.h b/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGAutoDownloadPreferences.h deleted file mode 100644 index 975ffbd435..0000000000 --- a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGAutoDownloadPreferences.h +++ /dev/null @@ -1,76 +0,0 @@ -#import - -typedef enum { - TGNetworkTypeUnknown, - TGNetworkTypeNone, - TGNetworkTypeGPRS, - TGNetworkTypeEdge, - TGNetworkType3G, - TGNetworkTypeLTE, - TGNetworkTypeWiFi, -} TGNetworkType; - -typedef enum { - TGAutoDownloadModeNone = 0, - - TGAutoDownloadModeCellularContacts = 1 << 0, - TGAutoDownloadModeWifiContacts = 1 << 1, - - TGAutoDownloadModeCellularPrivateChats = 1 << 2, - TGAutoDownloadModeWifiPrivateChats = 1 << 3, - - TGAutoDownloadModeCellularGroups = 1 << 4, - TGAutoDownloadModeWifiGroups = 1 << 5, - - TGAutoDownloadModeCellularChannels = 1 << 6, - TGAutoDownloadModeWifiChannels = 1 << 7, - - TGAutoDownloadModeAutosavePhotosAll = TGAutoDownloadModeCellularContacts | TGAutoDownloadModeCellularPrivateChats | TGAutoDownloadModeCellularGroups | TGAutoDownloadModeCellularChannels, - - TGAutoDownloadModeAllPrivateChats = TGAutoDownloadModeCellularContacts | TGAutoDownloadModeWifiContacts | TGAutoDownloadModeCellularPrivateChats | TGAutoDownloadModeWifiPrivateChats, - TGAutoDownloadModeAllGroups = TGAutoDownloadModeCellularGroups | TGAutoDownloadModeWifiGroups | TGAutoDownloadModeCellularChannels | TGAutoDownloadModeWifiChannels, - TGAutoDownloadModeAll = TGAutoDownloadModeCellularContacts | TGAutoDownloadModeWifiContacts | TGAutoDownloadModeCellularPrivateChats | TGAutoDownloadModeWifiPrivateChats | TGAutoDownloadModeCellularGroups | TGAutoDownloadModeWifiGroups | TGAutoDownloadModeCellularChannels | TGAutoDownloadModeWifiChannels -} TGAutoDownloadMode; - -typedef enum { - TGAutoDownloadChatContact, - TGAutoDownloadChatOtherPrivateChat, - TGAutoDownloadChatGroup, - TGAutoDownloadChatChannel -} TGAutoDownloadChat; - -@interface TGAutoDownloadPreferences : NSObject - -@property (nonatomic, readonly) bool disabled; - -@property (nonatomic, readonly) TGAutoDownloadMode photos; -@property (nonatomic, readonly) TGAutoDownloadMode videos; -@property (nonatomic, readonly) int32_t maximumVideoSize; -@property (nonatomic, readonly) TGAutoDownloadMode documents; -@property (nonatomic, readonly) int32_t maximumDocumentSize; -@property (nonatomic, readonly) TGAutoDownloadMode gifs; -@property (nonatomic, readonly) TGAutoDownloadMode voiceMessages; -@property (nonatomic, readonly) TGAutoDownloadMode videoMessages; - -- (instancetype)updateDisabled:(bool)disabled; -- (instancetype)updatePhotosMode:(TGAutoDownloadMode)mode; -- (instancetype)updateVideosMode:(TGAutoDownloadMode)mode maximumSize:(int32_t)maximumSize; -- (instancetype)updateDocumentsMode:(TGAutoDownloadMode)mode maximumSize:(int32_t)maximumSize; -- (instancetype)updateGifsMode:(TGAutoDownloadMode)mode; -- (instancetype)updateVoiceMessagesMode:(TGAutoDownloadMode)mode; -- (instancetype)updateVideoMessagesMode:(TGAutoDownloadMode)mode; - -+ (bool)shouldDownload:(TGAutoDownloadMode)mode inChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType; -- (bool)shouldDownloadPhotoInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType; -- (bool)shouldDownloadVideoInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType; -- (bool)shouldDownloadDocumentInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType; -- (bool)shouldDownloadGifInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType; -- (bool)shouldDownloadVoiceMessageInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType; -- (bool)shouldDownloadVideoMessageInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType; - -- (bool)isDefaultPreferences; - -+ (instancetype)defaultPreferences; -+ (instancetype)preferencesWithLegacyDownloadPrivatePhotos:(bool)privatePhotos groupPhotos:(bool)groupPhotos privateVoiceMessages:(bool)privateVoiceMessages groupVoiceMessages:(bool)groupVoiceMessages privateVideoMessages:(bool)privateVideoMessages groupVideoMessages:(bool)groupVideoMessages; - -@end diff --git a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGAutoDownloadPreferences.m b/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGAutoDownloadPreferences.m deleted file mode 100644 index 64c8cca6c7..0000000000 --- a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGAutoDownloadPreferences.m +++ /dev/null @@ -1,250 +0,0 @@ -#import - -@implementation TGAutoDownloadPreferences - -- (instancetype)initWithCoder:(NSCoder *)aDecoder -{ - self = [super init]; - if (self != nil) - { - _disabled = [aDecoder decodeBoolForKey:@"disabled"]; - _photos = [aDecoder decodeInt32ForKey:@"photos"]; - _videos = [aDecoder decodeInt32ForKey:@"videos"]; - _maximumVideoSize = [aDecoder decodeInt32ForKey:@"maxVideoSize"]; - _documents = [aDecoder decodeInt32ForKey:@"documents"]; - _maximumDocumentSize = [aDecoder decodeInt32ForKey:@"maxDocumentSize"]; - _voiceMessages = [aDecoder decodeInt32ForKey:@"voiceMessages"]; - _videoMessages = [aDecoder decodeInt32ForKey:@"videoMessages"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)aCoder -{ - [aCoder encodeBool:_disabled forKey:@"disabled"]; - [aCoder encodeInt32:_photos forKey:@"photos"]; - [aCoder encodeInt32:_videos forKey:@"videos"]; - [aCoder encodeInt32:_maximumVideoSize forKey:@"maxVideoSize"]; - [aCoder encodeInt32:_documents forKey:@"documents"]; - [aCoder encodeInt32:_maximumDocumentSize forKey:@"maxDocumentSize"]; - [aCoder encodeInt32:_voiceMessages forKey:@"voiceMessages"]; - [aCoder encodeInt32:_videoMessages forKey:@"videoMessages"]; -} - -+ (instancetype)defaultPreferences -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = TGAutoDownloadModeAll; - preferences->_videos = TGAutoDownloadModeNone; - preferences->_maximumVideoSize = 10; - preferences->_documents = TGAutoDownloadModeNone; - preferences->_maximumDocumentSize = 10; - preferences->_voiceMessages = TGAutoDownloadModeAll; - preferences->_videoMessages = TGAutoDownloadModeAll; - return preferences; -} - -+ (instancetype)preferencesWithLegacyDownloadPrivatePhotos:(bool)privatePhotos groupPhotos:(bool)groupPhotos privateVoiceMessages:(bool)privateVoiceMessages groupVoiceMessages:(bool)groupVoiceMessages privateVideoMessages:(bool)privateVideoMessages groupVideoMessages:(bool)groupVideoMessages -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - - if (privatePhotos) - preferences->_photos |= TGAutoDownloadModeAllPrivateChats; - if (groupPhotos) - preferences->_photos |= TGAutoDownloadModeAllGroups; - - if (privateVoiceMessages) - preferences->_voiceMessages |= TGAutoDownloadModeAllPrivateChats; - if (groupVoiceMessages) - preferences->_voiceMessages |= TGAutoDownloadModeAllGroups; - - if (privateVideoMessages) - preferences->_videoMessages |= TGAutoDownloadModeAllPrivateChats; - if (groupVideoMessages) - preferences->_videoMessages |= TGAutoDownloadModeAllGroups; - - preferences->_maximumVideoSize = 10; - preferences->_maximumDocumentSize = 10; - - return preferences; -} - -- (instancetype)updateDisabled:(bool)disabled -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_disabled = disabled; - preferences->_photos = _photos; - preferences->_videos = _videos; - preferences->_maximumVideoSize = _maximumVideoSize; - preferences->_documents = _documents; - preferences->_maximumDocumentSize = _maximumDocumentSize; - preferences->_voiceMessages = _voiceMessages; - preferences->_videoMessages = _videoMessages; - return preferences; -} - -- (instancetype)updatePhotosMode:(TGAutoDownloadMode)mode -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = mode; - preferences->_videos = _videos; - preferences->_maximumVideoSize = _maximumVideoSize; - preferences->_documents = _documents; - preferences->_maximumDocumentSize = _maximumDocumentSize; - preferences->_voiceMessages = _voiceMessages; - preferences->_videoMessages = _videoMessages; - return preferences; -} - -- (instancetype)updateVideosMode:(TGAutoDownloadMode)mode maximumSize:(int32_t)maximumSize -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = _photos; - preferences->_videos = mode; - preferences->_maximumVideoSize = maximumSize; - preferences->_documents = _documents; - preferences->_maximumDocumentSize = _maximumDocumentSize; - preferences->_voiceMessages = _voiceMessages; - preferences->_videoMessages = _videoMessages; - return preferences; -} - -- (instancetype)updateDocumentsMode:(TGAutoDownloadMode)mode maximumSize:(int32_t)maximumSize -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = _photos; - preferences->_videos = _videos; - preferences->_maximumVideoSize = _maximumVideoSize; - preferences->_documents = mode; - preferences->_maximumDocumentSize = maximumSize; - preferences->_voiceMessages = _voiceMessages; - preferences->_videoMessages = _videoMessages; - return preferences; -} - -- (instancetype)updateVoiceMessagesMode:(TGAutoDownloadMode)mode -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = _photos; - preferences->_videos = _videos; - preferences->_maximumVideoSize = _maximumVideoSize; - preferences->_documents = _documents; - preferences->_maximumDocumentSize = _maximumDocumentSize; - preferences->_voiceMessages = mode; - preferences->_videoMessages = _videoMessages; - return preferences; -} - -- (instancetype)updateVideoMessagesMode:(TGAutoDownloadMode)mode -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = _photos; - preferences->_videos = _videos; - preferences->_maximumVideoSize = _maximumVideoSize; - preferences->_documents = _documents; - preferences->_maximumDocumentSize = _maximumDocumentSize; - preferences->_voiceMessages = _voiceMessages; - preferences->_videoMessages = mode; - return preferences; -} - -+ (bool)shouldDownload:(TGAutoDownloadMode)mode inChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - bool isWiFi = networkType == TGNetworkTypeWiFi; - bool isCellular = !isWiFi && networkType != TGNetworkTypeNone; - - bool shouldDownload = false; - switch (chat) - { - case TGAutoDownloadChatContact: - if (isCellular) - shouldDownload = (mode & TGAutoDownloadModeCellularContacts) != 0; - else if (isWiFi) - shouldDownload = (mode & TGAutoDownloadModeWifiContacts) != 0; - break; - - case TGAutoDownloadChatOtherPrivateChat: - if (isCellular) - shouldDownload = (mode & TGAutoDownloadModeCellularPrivateChats) != 0; - else if (isWiFi) - shouldDownload = (mode & TGAutoDownloadModeWifiPrivateChats) != 0; - break; - - case TGAutoDownloadChatGroup: - if (isCellular) - shouldDownload = (mode & TGAutoDownloadModeCellularGroups) != 0; - else if (isWiFi) - shouldDownload = (mode & TGAutoDownloadModeWifiGroups) != 0; - break; - - case TGAutoDownloadChatChannel: - if (isCellular) - shouldDownload = (mode & TGAutoDownloadModeCellularChannels) != 0; - else if (isWiFi) - shouldDownload = (mode & TGAutoDownloadModeWifiChannels) != 0; - break; - - default: - break; - } - return shouldDownload; -} - -- (bool)shouldDownloadPhotoInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - if (self.disabled) - return false; - - return [TGAutoDownloadPreferences shouldDownload:_photos inChat:chat networkType:networkType]; -} - -- (bool)shouldDownloadVideoInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - if (self.disabled) - return false; - - return [TGAutoDownloadPreferences shouldDownload:_videos inChat:chat networkType:networkType]; -} - -- (bool)shouldDownloadDocumentInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - if (self.disabled) - return false; - - return [TGAutoDownloadPreferences shouldDownload:_documents inChat:chat networkType:networkType]; -} - -- (bool)shouldDownloadVoiceMessageInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - if (self.disabled) - return false; - - return [TGAutoDownloadPreferences shouldDownload:_voiceMessages inChat:chat networkType:networkType]; -} - -- (bool)shouldDownloadVideoMessageInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - if (self.disabled) - return false; - - return [TGAutoDownloadPreferences shouldDownload:_videoMessages inChat:chat networkType:networkType]; -} - -- (bool)isDefaultPreferences -{ - return [self isEqual:[TGAutoDownloadPreferences defaultPreferences]]; -} - -- (BOOL)isEqual:(id)object -{ - if (object == self) - return YES; - - if (!object || ![object isKindOfClass:[self class]]) - return NO; - - TGAutoDownloadPreferences *preferences = (TGAutoDownloadPreferences *)object; - return preferences.photos == _photos && preferences.videos == _videos && preferences.documents == _documents && preferences.voiceMessages == _voiceMessages && preferences.videoMessages == _videoMessages && preferences.maximumVideoSize == _maximumVideoSize && preferences.maximumDocumentSize == _maximumDocumentSize && preferences.disabled == _disabled; -} - -@end diff --git a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGPresentationAutoNightPreferences.h b/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGPresentationAutoNightPreferences.h deleted file mode 100644 index 1a403c5215..0000000000 --- a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGPresentationAutoNightPreferences.h +++ /dev/null @@ -1,31 +0,0 @@ -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -typedef enum -{ - TGPresentationAutoNightModeDisabled, - TGPresentationAutoNightModeBrightness, - TGPresentationAutoNightModeScheduled, - TGPresentationAutoNightModeSunsetSunrise -} TGPresentationAutoNightMode; - -@interface TGPresentationAutoNightPreferences : NSObject - -@property (nonatomic, readonly) TGPresentationAutoNightMode mode; - -@property (nonatomic, readonly) CGFloat brightnessThreshold; - -@property (nonatomic, readonly) int32_t scheduleStart; -@property (nonatomic, readonly) int32_t scheduleEnd; - -@property (nonatomic, readonly) CGFloat latitude; -@property (nonatomic, readonly) CGFloat longitude; -@property (nonatomic, readonly) NSString *cachedLocationName; - -@property (nonatomic, readonly) int32_t preferredPalette; - -@end - -NS_ASSUME_NONNULL_END diff --git a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGPresentationAutoNightPreferences.m b/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGPresentationAutoNightPreferences.m deleted file mode 100644 index b53b768e38..0000000000 --- a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGPresentationAutoNightPreferences.m +++ /dev/null @@ -1,23 +0,0 @@ -#import - -@implementation TGPresentationAutoNightPreferences - -- (instancetype)initWithCoder:(NSCoder *)aDecoder { - self = [super init]; - if (self != nil) { - _mode = [aDecoder decodeInt32ForKey:@"m"]; - _brightnessThreshold = [aDecoder decodeDoubleForKey:@"b"]; - _scheduleStart = [aDecoder decodeInt32ForKey:@"ss"]; - _scheduleEnd = [aDecoder decodeInt32ForKey:@"se"]; - _latitude = [aDecoder decodeDoubleForKey:@"lat"]; - _longitude = [aDecoder decodeDoubleForKey:@"lon"]; - _cachedLocationName = [aDecoder decodeObjectForKey:@"loc"]; - _preferredPalette = [aDecoder decodeInt32ForKey:@"p"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)aCoder { -} - -@end diff --git a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGProxyItem.h b/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGProxyItem.h deleted file mode 100644 index 72c1b76fd3..0000000000 --- a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGProxyItem.h +++ /dev/null @@ -1,15 +0,0 @@ -#import - -@interface TGProxyItem : NSObject - -@property (nonatomic, readonly) NSString *server; -@property (nonatomic, readonly) int16_t port; -@property (nonatomic, readonly) NSString *username; -@property (nonatomic, readonly) NSString *password; -@property (nonatomic, readonly) NSString *secret; - -@property (nonatomic, readonly) bool isMTProxy; - -- (instancetype)initWithServer:(NSString *)server port:(int16_t)port username:(NSString *)username password:(NSString *)password secret:(NSString *)secret; - -@end diff --git a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGProxyItem.m b/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGProxyItem.m deleted file mode 100644 index 4dfc1d6c93..0000000000 --- a/submodules/LegacyDataImport/Impl/PublicHeaders/LegacyDataImportImpl/TGProxyItem.m +++ /dev/null @@ -1,73 +0,0 @@ -#import - -static bool TGObjectCompare(id obj1, id obj2) { - if (obj1 == nil && obj2 == nil) - return true; - - return [obj1 isEqual:obj2]; -} - -@implementation TGProxyItem - -- (instancetype)initWithServer:(NSString *)server port:(int16_t)port username:(NSString *)username password:(NSString *)password secret:(NSString *)secret -{ - self = [super init]; - if (self != nil) - { - _server = server; - _port = port; - _username = username; - _password = password; - _secret = secret; - } - return self; -} - -- (instancetype)initWithCoder:(NSCoder *)aDecoder -{ - return [self initWithServer:[aDecoder decodeObjectForKey:@"server"] port:(int16_t)[aDecoder decodeInt32ForKey:@"port"] username:[aDecoder decodeObjectForKey:@"user"] password:[aDecoder decodeObjectForKey:@"pass"] secret:[aDecoder decodeObjectForKey:@"secret"]]; -} - -- (void)encodeWithCoder:(NSCoder *)aCoder -{ - [aCoder encodeObject:_server forKey:@"server"]; - [aCoder encodeInt32:_port forKey:@"port"]; - [aCoder encodeObject:_username forKey:@"user"]; - [aCoder encodeObject:_password forKey:@"pass"]; - [aCoder encodeObject:_secret forKey:@"secret"]; -} - -- (bool)isMTProxy -{ - return _secret.length > 0; -} - -- (BOOL)isEqual:(id)object -{ - if (object == self) - return true; - - if (!object || ![object isKindOfClass:[self class]]) - return false; - - TGProxyItem *proxy = (TGProxyItem *)object; - - if (![_server isEqualToString:proxy.server]) - return false; - - if (_port != proxy.port) - return false; - - if (!TGObjectCompare(_username ?: @"", proxy.username ?: @"")) - return false; - - if (!TGObjectCompare(_password ?: @"", proxy.password ?: @"")) - return false; - - if (!TGObjectCompare(_secret ?: @"", proxy.secret ?: @"")) - return false; - - return true; -} - -@end diff --git a/submodules/LegacyDataImport/Impl/Sources/TGAutoDownloadPreferences.m b/submodules/LegacyDataImport/Impl/Sources/TGAutoDownloadPreferences.m deleted file mode 100644 index 64c8cca6c7..0000000000 --- a/submodules/LegacyDataImport/Impl/Sources/TGAutoDownloadPreferences.m +++ /dev/null @@ -1,250 +0,0 @@ -#import - -@implementation TGAutoDownloadPreferences - -- (instancetype)initWithCoder:(NSCoder *)aDecoder -{ - self = [super init]; - if (self != nil) - { - _disabled = [aDecoder decodeBoolForKey:@"disabled"]; - _photos = [aDecoder decodeInt32ForKey:@"photos"]; - _videos = [aDecoder decodeInt32ForKey:@"videos"]; - _maximumVideoSize = [aDecoder decodeInt32ForKey:@"maxVideoSize"]; - _documents = [aDecoder decodeInt32ForKey:@"documents"]; - _maximumDocumentSize = [aDecoder decodeInt32ForKey:@"maxDocumentSize"]; - _voiceMessages = [aDecoder decodeInt32ForKey:@"voiceMessages"]; - _videoMessages = [aDecoder decodeInt32ForKey:@"videoMessages"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)aCoder -{ - [aCoder encodeBool:_disabled forKey:@"disabled"]; - [aCoder encodeInt32:_photos forKey:@"photos"]; - [aCoder encodeInt32:_videos forKey:@"videos"]; - [aCoder encodeInt32:_maximumVideoSize forKey:@"maxVideoSize"]; - [aCoder encodeInt32:_documents forKey:@"documents"]; - [aCoder encodeInt32:_maximumDocumentSize forKey:@"maxDocumentSize"]; - [aCoder encodeInt32:_voiceMessages forKey:@"voiceMessages"]; - [aCoder encodeInt32:_videoMessages forKey:@"videoMessages"]; -} - -+ (instancetype)defaultPreferences -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = TGAutoDownloadModeAll; - preferences->_videos = TGAutoDownloadModeNone; - preferences->_maximumVideoSize = 10; - preferences->_documents = TGAutoDownloadModeNone; - preferences->_maximumDocumentSize = 10; - preferences->_voiceMessages = TGAutoDownloadModeAll; - preferences->_videoMessages = TGAutoDownloadModeAll; - return preferences; -} - -+ (instancetype)preferencesWithLegacyDownloadPrivatePhotos:(bool)privatePhotos groupPhotos:(bool)groupPhotos privateVoiceMessages:(bool)privateVoiceMessages groupVoiceMessages:(bool)groupVoiceMessages privateVideoMessages:(bool)privateVideoMessages groupVideoMessages:(bool)groupVideoMessages -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - - if (privatePhotos) - preferences->_photos |= TGAutoDownloadModeAllPrivateChats; - if (groupPhotos) - preferences->_photos |= TGAutoDownloadModeAllGroups; - - if (privateVoiceMessages) - preferences->_voiceMessages |= TGAutoDownloadModeAllPrivateChats; - if (groupVoiceMessages) - preferences->_voiceMessages |= TGAutoDownloadModeAllGroups; - - if (privateVideoMessages) - preferences->_videoMessages |= TGAutoDownloadModeAllPrivateChats; - if (groupVideoMessages) - preferences->_videoMessages |= TGAutoDownloadModeAllGroups; - - preferences->_maximumVideoSize = 10; - preferences->_maximumDocumentSize = 10; - - return preferences; -} - -- (instancetype)updateDisabled:(bool)disabled -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_disabled = disabled; - preferences->_photos = _photos; - preferences->_videos = _videos; - preferences->_maximumVideoSize = _maximumVideoSize; - preferences->_documents = _documents; - preferences->_maximumDocumentSize = _maximumDocumentSize; - preferences->_voiceMessages = _voiceMessages; - preferences->_videoMessages = _videoMessages; - return preferences; -} - -- (instancetype)updatePhotosMode:(TGAutoDownloadMode)mode -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = mode; - preferences->_videos = _videos; - preferences->_maximumVideoSize = _maximumVideoSize; - preferences->_documents = _documents; - preferences->_maximumDocumentSize = _maximumDocumentSize; - preferences->_voiceMessages = _voiceMessages; - preferences->_videoMessages = _videoMessages; - return preferences; -} - -- (instancetype)updateVideosMode:(TGAutoDownloadMode)mode maximumSize:(int32_t)maximumSize -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = _photos; - preferences->_videos = mode; - preferences->_maximumVideoSize = maximumSize; - preferences->_documents = _documents; - preferences->_maximumDocumentSize = _maximumDocumentSize; - preferences->_voiceMessages = _voiceMessages; - preferences->_videoMessages = _videoMessages; - return preferences; -} - -- (instancetype)updateDocumentsMode:(TGAutoDownloadMode)mode maximumSize:(int32_t)maximumSize -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = _photos; - preferences->_videos = _videos; - preferences->_maximumVideoSize = _maximumVideoSize; - preferences->_documents = mode; - preferences->_maximumDocumentSize = maximumSize; - preferences->_voiceMessages = _voiceMessages; - preferences->_videoMessages = _videoMessages; - return preferences; -} - -- (instancetype)updateVoiceMessagesMode:(TGAutoDownloadMode)mode -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = _photos; - preferences->_videos = _videos; - preferences->_maximumVideoSize = _maximumVideoSize; - preferences->_documents = _documents; - preferences->_maximumDocumentSize = _maximumDocumentSize; - preferences->_voiceMessages = mode; - preferences->_videoMessages = _videoMessages; - return preferences; -} - -- (instancetype)updateVideoMessagesMode:(TGAutoDownloadMode)mode -{ - TGAutoDownloadPreferences *preferences = [[TGAutoDownloadPreferences alloc] init]; - preferences->_photos = _photos; - preferences->_videos = _videos; - preferences->_maximumVideoSize = _maximumVideoSize; - preferences->_documents = _documents; - preferences->_maximumDocumentSize = _maximumDocumentSize; - preferences->_voiceMessages = _voiceMessages; - preferences->_videoMessages = mode; - return preferences; -} - -+ (bool)shouldDownload:(TGAutoDownloadMode)mode inChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - bool isWiFi = networkType == TGNetworkTypeWiFi; - bool isCellular = !isWiFi && networkType != TGNetworkTypeNone; - - bool shouldDownload = false; - switch (chat) - { - case TGAutoDownloadChatContact: - if (isCellular) - shouldDownload = (mode & TGAutoDownloadModeCellularContacts) != 0; - else if (isWiFi) - shouldDownload = (mode & TGAutoDownloadModeWifiContacts) != 0; - break; - - case TGAutoDownloadChatOtherPrivateChat: - if (isCellular) - shouldDownload = (mode & TGAutoDownloadModeCellularPrivateChats) != 0; - else if (isWiFi) - shouldDownload = (mode & TGAutoDownloadModeWifiPrivateChats) != 0; - break; - - case TGAutoDownloadChatGroup: - if (isCellular) - shouldDownload = (mode & TGAutoDownloadModeCellularGroups) != 0; - else if (isWiFi) - shouldDownload = (mode & TGAutoDownloadModeWifiGroups) != 0; - break; - - case TGAutoDownloadChatChannel: - if (isCellular) - shouldDownload = (mode & TGAutoDownloadModeCellularChannels) != 0; - else if (isWiFi) - shouldDownload = (mode & TGAutoDownloadModeWifiChannels) != 0; - break; - - default: - break; - } - return shouldDownload; -} - -- (bool)shouldDownloadPhotoInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - if (self.disabled) - return false; - - return [TGAutoDownloadPreferences shouldDownload:_photos inChat:chat networkType:networkType]; -} - -- (bool)shouldDownloadVideoInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - if (self.disabled) - return false; - - return [TGAutoDownloadPreferences shouldDownload:_videos inChat:chat networkType:networkType]; -} - -- (bool)shouldDownloadDocumentInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - if (self.disabled) - return false; - - return [TGAutoDownloadPreferences shouldDownload:_documents inChat:chat networkType:networkType]; -} - -- (bool)shouldDownloadVoiceMessageInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - if (self.disabled) - return false; - - return [TGAutoDownloadPreferences shouldDownload:_voiceMessages inChat:chat networkType:networkType]; -} - -- (bool)shouldDownloadVideoMessageInChat:(TGAutoDownloadChat)chat networkType:(TGNetworkType)networkType -{ - if (self.disabled) - return false; - - return [TGAutoDownloadPreferences shouldDownload:_videoMessages inChat:chat networkType:networkType]; -} - -- (bool)isDefaultPreferences -{ - return [self isEqual:[TGAutoDownloadPreferences defaultPreferences]]; -} - -- (BOOL)isEqual:(id)object -{ - if (object == self) - return YES; - - if (!object || ![object isKindOfClass:[self class]]) - return NO; - - TGAutoDownloadPreferences *preferences = (TGAutoDownloadPreferences *)object; - return preferences.photos == _photos && preferences.videos == _videos && preferences.documents == _documents && preferences.voiceMessages == _voiceMessages && preferences.videoMessages == _videoMessages && preferences.maximumVideoSize == _maximumVideoSize && preferences.maximumDocumentSize == _maximumDocumentSize && preferences.disabled == _disabled; -} - -@end diff --git a/submodules/LegacyDataImport/Impl/Sources/TGPresentationAutoNightPreferences.m b/submodules/LegacyDataImport/Impl/Sources/TGPresentationAutoNightPreferences.m deleted file mode 100644 index b53b768e38..0000000000 --- a/submodules/LegacyDataImport/Impl/Sources/TGPresentationAutoNightPreferences.m +++ /dev/null @@ -1,23 +0,0 @@ -#import - -@implementation TGPresentationAutoNightPreferences - -- (instancetype)initWithCoder:(NSCoder *)aDecoder { - self = [super init]; - if (self != nil) { - _mode = [aDecoder decodeInt32ForKey:@"m"]; - _brightnessThreshold = [aDecoder decodeDoubleForKey:@"b"]; - _scheduleStart = [aDecoder decodeInt32ForKey:@"ss"]; - _scheduleEnd = [aDecoder decodeInt32ForKey:@"se"]; - _latitude = [aDecoder decodeDoubleForKey:@"lat"]; - _longitude = [aDecoder decodeDoubleForKey:@"lon"]; - _cachedLocationName = [aDecoder decodeObjectForKey:@"loc"]; - _preferredPalette = [aDecoder decodeInt32ForKey:@"p"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)aCoder { -} - -@end diff --git a/submodules/LegacyDataImport/Impl/Sources/TGProxyItem.m b/submodules/LegacyDataImport/Impl/Sources/TGProxyItem.m deleted file mode 100644 index 4dfc1d6c93..0000000000 --- a/submodules/LegacyDataImport/Impl/Sources/TGProxyItem.m +++ /dev/null @@ -1,73 +0,0 @@ -#import - -static bool TGObjectCompare(id obj1, id obj2) { - if (obj1 == nil && obj2 == nil) - return true; - - return [obj1 isEqual:obj2]; -} - -@implementation TGProxyItem - -- (instancetype)initWithServer:(NSString *)server port:(int16_t)port username:(NSString *)username password:(NSString *)password secret:(NSString *)secret -{ - self = [super init]; - if (self != nil) - { - _server = server; - _port = port; - _username = username; - _password = password; - _secret = secret; - } - return self; -} - -- (instancetype)initWithCoder:(NSCoder *)aDecoder -{ - return [self initWithServer:[aDecoder decodeObjectForKey:@"server"] port:(int16_t)[aDecoder decodeInt32ForKey:@"port"] username:[aDecoder decodeObjectForKey:@"user"] password:[aDecoder decodeObjectForKey:@"pass"] secret:[aDecoder decodeObjectForKey:@"secret"]]; -} - -- (void)encodeWithCoder:(NSCoder *)aCoder -{ - [aCoder encodeObject:_server forKey:@"server"]; - [aCoder encodeInt32:_port forKey:@"port"]; - [aCoder encodeObject:_username forKey:@"user"]; - [aCoder encodeObject:_password forKey:@"pass"]; - [aCoder encodeObject:_secret forKey:@"secret"]; -} - -- (bool)isMTProxy -{ - return _secret.length > 0; -} - -- (BOOL)isEqual:(id)object -{ - if (object == self) - return true; - - if (!object || ![object isKindOfClass:[self class]]) - return false; - - TGProxyItem *proxy = (TGProxyItem *)object; - - if (![_server isEqualToString:proxy.server]) - return false; - - if (_port != proxy.port) - return false; - - if (!TGObjectCompare(_username ?: @"", proxy.username ?: @"")) - return false; - - if (!TGObjectCompare(_password ?: @"", proxy.password ?: @"")) - return false; - - if (!TGObjectCompare(_secret ?: @"", proxy.secret ?: @"")) - return false; - - return true; -} - -@end diff --git a/submodules/LegacyDataImport/Sources/LegacyBuffer.swift b/submodules/LegacyDataImport/Sources/LegacyBuffer.swift deleted file mode 100644 index cebc964f39..0000000000 --- a/submodules/LegacyDataImport/Sources/LegacyBuffer.swift +++ /dev/null @@ -1,197 +0,0 @@ -import Foundation - -class LegacyBuffer: CustomStringConvertible { - var data: UnsafeMutableRawPointer? - var _size: UInt = 0 - private var capacity: UInt = 0 - private let freeWhenDone: Bool - - var size: Int { - return Int(self._size) - } - - deinit { - if self.freeWhenDone { - free(self.data) - } - } - - init(memory: UnsafeMutableRawPointer?, size: Int, capacity: Int, freeWhenDone: Bool) { - self.data = memory - self._size = UInt(size) - self.capacity = UInt(capacity) - self.freeWhenDone = freeWhenDone - } - - init() { - self.data = nil - self._size = 0 - self.capacity = 0 - self.freeWhenDone = true - } - - convenience init(data: Data?) { - self.init() - - if let data = data { - data.withUnsafeBytes { bytes in - self.appendBytes(bytes, length: UInt(data.count)) - } - } - } - - func makeData() -> Data { - return self.withUnsafeMutablePointer { pointer, size -> Data in - if let pointer = pointer { - return Data(bytes: pointer.assumingMemoryBound(to: UInt8.self), count: Int(size)) - } else { - return Data() - } - } - } - - var description: String { - get { - var string = "" - if let data = self.data { - var i: UInt = 0 - let bytes = data.assumingMemoryBound(to: UInt8.self) - while i < _size && i < 8 { - string += String(format: "%02x", Int(bytes.advanced(by: Int(i)).pointee)) - i += 1 - } - if i < _size { - string += "...\(_size)b" - } - } else { - string += "" - } - return string - } - } - - func appendBytes(_ bytes: UnsafeRawPointer, length: UInt) { - if self.capacity < self._size + length { - self.capacity = self._size + length + 128 - if self.data == nil { - self.data = malloc(Int(self.capacity))! - } - else { - self.data = realloc(self.data, Int(self.capacity))! - } - } - - memcpy(self.data?.advanced(by: Int(self._size)), bytes, Int(length)) - self._size += length - } - - func appendBuffer(_ buffer: LegacyBuffer) { - if self.capacity < self._size + buffer._size { - self.capacity = self._size + buffer._size + 128 - if self.data == nil { - self.data = malloc(Int(self.capacity))! - } - else { - self.data = realloc(self.data, Int(self.capacity))! - } - } - - memcpy(self.data?.advanced(by: Int(self._size)), buffer.data, Int(buffer._size)) - } - - func appendInt32(_ value: Int32) { - var v = value - self.appendBytes(&v, length: 4) - } - - func appendInt64(_ value: Int64) { - var v = value - self.appendBytes(&v, length: 8) - } - - func appendDouble(_ value: Double) { - var v = value - self.appendBytes(&v, length: 8) - } - - func withUnsafeMutablePointer(_ f: (UnsafeMutableRawPointer?, UInt) -> R) -> R { - return f(self.data, self._size) - } -} - -class LegacyBufferReader { - private let buffer: LegacyBuffer - private(set) var offset: UInt = 0 - - init(_ buffer: LegacyBuffer) { - self.buffer = buffer - } - - func reset() { - self.offset = 0 - } - - func skip(_ count: Int) { - self.offset = min(self.buffer._size, self.offset + UInt(count)) - } - - func readInt32() -> Int32? { - if self.offset + 4 <= self.buffer._size { - let value: Int32 = buffer.data!.advanced(by: Int(self.offset)).assumingMemoryBound(to: Int32.self).pointee - self.offset += 4 - return value - } - return nil - } - - func readInt64() -> Int64? { - if self.offset + 8 <= self.buffer._size { - let value: Int64 = buffer.data!.advanced(by: Int(self.offset)).assumingMemoryBound(to: Int64.self).pointee - self.offset += 8 - return value - } - return nil - } - - func readDouble() -> Double? { - if self.offset + 8 <= self.buffer._size { - let value: Double = buffer.data!.advanced(by: Int(self.offset)).assumingMemoryBound(to: Double.self).pointee - self.offset += 8 - return value - } - return nil - } - - func readBytesAsInt32(_ count: Int) -> Int32? { - if count == 0 { - return 0 - } - guard count > 0, count <= 4, self.offset + UInt(count) <= self.buffer._size else { - return nil - } - guard let bufferData = self.buffer.data else { - return nil - } - var value: Int32 = 0 - memcpy(&value, bufferData.advanced(by: Int(self.offset)), count) - self.offset += UInt(count) - return value - } - - func readBuffer(_ count: Int) -> LegacyBuffer? { - if count >= 0 && self.offset + UInt(count) <= self.buffer._size { - let buffer = LegacyBuffer() - buffer.appendBytes((self.buffer.data?.advanced(by: Int(self.offset)))!, length: UInt(count)) - self.offset += UInt(count) - return buffer - } - return nil - } - - func withReadBufferNoCopy(_ count: Int, _ f: (LegacyBuffer) -> T) -> T? { - if count >= 0 && self.offset + UInt(count) <= self.buffer._size { - return f(LegacyBuffer(memory: self.buffer.data!.advanced(by: Int(self.offset)), size: count, capacity: count, freeWhenDone: false)) - } - return nil - } -} diff --git a/submodules/LegacyDataImport/Sources/LegacyChatImport.swift b/submodules/LegacyDataImport/Sources/LegacyChatImport.swift deleted file mode 100644 index 9a50a1471a..0000000000 --- a/submodules/LegacyDataImport/Sources/LegacyChatImport.swift +++ /dev/null @@ -1,780 +0,0 @@ -import Foundation -import TelegramCore -import SyncCore -import SwiftSignalKit -import Postbox -import LegacyComponents - -private let reportedLayer_hash: Int32 = -717538193 -private let layer_hash: Int32 = 849537378 -private let seq_out_hash: Int32 = -737765753 -private let seq_in_hash: Int32 = -7646011 - -private let defaultPrime: Data = { - let bytes: [UInt8] = [ - 0xc7, 0x1c, 0xae, 0xb9, 0xc6, 0xb1, 0xc9, 0x04, 0x8e, 0x6c, 0x52, 0x2f, - 0x70, 0xf1, 0x3f, 0x73, 0x98, 0x0d, 0x40, 0x23, 0x8e, 0x3e, 0x21, 0xc1, - 0x49, 0x34, 0xd0, 0x37, 0x56, 0x3d, 0x93, 0x0f, 0x48, 0x19, 0x8a, 0x0a, - 0xa7, 0xc1, 0x40, 0x58, 0x22, 0x94, 0x93, 0xd2, 0x25, 0x30, 0xf4, 0xdb, - 0xfa, 0x33, 0x6f, 0x6e, 0x0a, 0xc9, 0x25, 0x13, 0x95, 0x43, 0xae, 0xd4, - 0x4c, 0xce, 0x7c, 0x37, 0x20, 0xfd, 0x51, 0xf6, 0x94, 0x58, 0x70, 0x5a, - 0xc6, 0x8c, 0xd4, 0xfe, 0x6b, 0x6b, 0x13, 0xab, 0xdc, 0x97, 0x46, 0x51, - 0x29, 0x69, 0x32, 0x84, 0x54, 0xf1, 0x8f, 0xaf, 0x8c, 0x59, 0x5f, 0x64, - 0x24, 0x77, 0xfe, 0x96, 0xbb, 0x2a, 0x94, 0x1d, 0x5b, 0xcd, 0x1d, 0x4a, - 0xc8, 0xcc, 0x49, 0x88, 0x07, 0x08, 0xfa, 0x9b, 0x37, 0x8e, 0x3c, 0x4f, - 0x3a, 0x90, 0x60, 0xbe, 0xe6, 0x7c, 0xf9, 0xa4, 0xa4, 0xa6, 0x95, 0x81, - 0x10, 0x51, 0x90, 0x7e, 0x16, 0x27, 0x53, 0xb5, 0x6b, 0x0f, 0x6b, 0x41, - 0x0d, 0xba, 0x74, 0xd8, 0xa8, 0x4b, 0x2a, 0x14, 0xb3, 0x14, 0x4e, 0x0e, - 0xf1, 0x28, 0x47, 0x54, 0xfd, 0x17, 0xed, 0x95, 0x0d, 0x59, 0x65, 0xb4, - 0xb9, 0xdd, 0x46, 0x58, 0x2d, 0xb1, 0x17, 0x8d, 0x16, 0x9c, 0x6b, 0xc4, - 0x65, 0xb0, 0xd6, 0xff, 0x9c, 0xa3, 0x92, 0x8f, 0xef, 0x5b, 0x9a, 0xe4, - 0xe4, 0x18, 0xfc, 0x15, 0xe8, 0x3e, 0xbe, 0xa0, 0xf8, 0x7f, 0xa9, 0xff, - 0x5e, 0xed, 0x70, 0x05, 0x0d, 0xed, 0x28, 0x49, 0xf4, 0x7b, 0xf9, 0x59, - 0xd9, 0x56, 0x85, 0x0c, 0xe9, 0x29, 0x85, 0x1f, 0x0d, 0x81, 0x15, 0xf6, - 0x35, 0xb1, 0x05, 0xee, 0x2e, 0x4e, 0x15, 0xd0, 0x4b, 0x24, 0x54, 0xbf, - 0x6f, 0x4f, 0xad, 0xf0, 0x34, 0xb1, 0x04, 0x03, 0x11, 0x9c, 0xd8, 0xe3, - 0xb9, 0x2f, 0xcc, 0x5b - ] - var data = Data(count: bytes.count) - data.withUnsafeMutableBytes { (dst: UnsafeMutablePointer) -> Void in - for i in 0 ..< bytes.count { - dst.advanced(by: i).pointee = bytes[i] - } - } - return data -}() - -@objc(TGEncryptionKeyData) private final class TGEncryptionKeyData: NSObject, NSCoding { - let keyId: Int64 - let key: Data - let firstSeqOut: Int32 - - init?(coder aDecoder: NSCoder) { - self.keyId = aDecoder.decodeInt64(forKey: "keyId") - self.key = (aDecoder.decodeObject(forKey: "key") as? Data) ?? Data() - self.firstSeqOut = aDecoder.decodeInt32(forKey: "firstSeqOut") - } - - func encode(with aCoder: NSCoder) { - assertionFailure() - } -} - -private struct SecretChatData { - let accessHash: Int64 - let handshakeState: Int32 - let rekeyState: SecretChatRekeySessionState? -} - -private func readSecretChatParticipantData(accountPeerId: PeerId, data: Data) -> (SecretChatRole, PeerId)? { - let reader = LegacyBufferReader(LegacyBuffer(data: data)) - - guard reader.readInt32() == Int32(bitPattern: 0xabcdef12) else { - return nil - } - guard let formatVersion = reader.readInt32(), formatVersion >= 2 else { - return nil - } - reader.skip(4) - - guard let adminId = reader.readInt32() else { - return nil - } - guard let count = reader.readInt32() else { - return nil - } - var ids: [Int32] = [] - for _ in 0 ..< Int(count) { - guard let id = reader.readInt32() else { - return nil - } - reader.skip(4) - reader.skip(4) - ids.append(id) - } - - guard let otherPeerId = ids.first else { - return nil - } - - return (adminId == accountPeerId.id ? .creator : .participant, PeerId(namespace: Namespaces.Peer.CloudUser, id: otherPeerId)) -} - -private func readSecretChatData(reader: LegacyBufferReader) -> SecretChatData? { - guard let version = reader.readBytesAsInt32(1) else { - return nil - } - if version != 3 { - return nil - } - reader.skip(8) - - guard let accessHash = reader.readInt64() else { - return nil - } - guard let _ = reader.readInt64() else { - return nil - } - guard let handshakeState = reader.readInt32() else { - return nil - } - guard let currentRekeyExchangeId = reader.readInt64() else { - return nil - } - guard let currentRekeyIsInitiatedByLocalClient = reader.readBytesAsInt32(1) else { - return nil - } - guard let currentRekeyNumberLength = reader.readInt32() else { - return nil - } - var currentRekeyNumber: Data? - if currentRekeyNumberLength > 0 { - guard let value = reader.readBuffer(Int(currentRekeyNumberLength))?.makeData() else { - return nil - } - currentRekeyNumber = value - } - guard let currentRekeyKeyLength = reader.readInt32() else { - return nil - } - var currentRekeyKey: Data? - if currentRekeyKeyLength > 0 { - guard let value = reader.readBuffer(Int(currentRekeyKeyLength))?.makeData() else { - return nil - } - currentRekeyKey = value - } - guard let currentRekeyKeyId = reader.readInt64() else { - return nil - } - - var rekeyState: SecretChatRekeySessionState? - if currentRekeyExchangeId != 0 { - let innerState: SecretChatRekeySessionData? - if currentRekeyIsInitiatedByLocalClient != 0, let currentRekeyNumber = currentRekeyNumber { - innerState = .requested(a: MemoryBuffer(data: currentRekeyNumber), config: SecretChatEncryptionConfig(g: 3, p: MemoryBuffer(data: defaultPrime), version: 0)) - } else if currentRekeyIsInitiatedByLocalClient == 0, let currentRekeyKey = currentRekeyKey, currentRekeyKeyId != 0 { - innerState = .accepted(key: MemoryBuffer(data: currentRekeyKey), keyFingerprint: currentRekeyKeyId) - } else { - innerState = nil - } - if let innerState = innerState { - rekeyState = SecretChatRekeySessionState(id: currentRekeyExchangeId, data: innerState) - } - } - - return SecretChatData(accessHash: accessHash, handshakeState: handshakeState, rekeyState: rekeyState) -} - -let registeredAttachmentParsers: Bool = { - let parsers: [(Int32, TGMediaAttachmentParser)] = [ - (TGActionMediaAttachmentType, TGActionMediaAttachment()), - (TGImageMediaAttachmentType, TGImageMediaAttachment()), - (TGLocationMediaAttachmentType, TGLocationMediaAttachment()), - (TGVideoMediaAttachmentType, TGVideoMediaAttachment()), - (Int32(bitPattern: 0xB90A5663), TGContactMediaAttachment()), - (Int32(bitPattern: 0xE6C64318), TGDocumentMediaAttachment()), - (TGAudioMediaAttachmentType, TGAudioMediaAttachment()), - (Int32(bitPattern: 0x8C2E3CCE), TGMessageEntitiesAttachment()), - (Int32(bitPattern: 0x944DE6B6), TGLocalMessageMetaMediaAttachment()), - (TGAuthorSignatureMediaAttachmentType, TGAuthorSignatureMediaAttachment()), - (TGInvoiceMediaAttachmentType, TGInvoiceMediaAttachment()), - (TGGameAttachmentType, TGGameMediaAttachment()), - (Int32(bitPattern: 0xA3F4C8F5), TGViaUserAttachment()), - (TGBotContextResultAttachmentType, TGBotContextResultAttachment()), - (TGReplyMarkupAttachmentType, TGReplyMarkupAttachment()), - (TGWebPageMediaAttachmentType, TGWebPageMediaAttachment()), - (TGReplyMessageMediaAttachmentType, TGReplyMessageMediaAttachment()), - (TGAudioMediaAttachmentType, TGAudioMediaAttachment()), - (Int32(bitPattern: 0xaa1050c1), TGForwardedMessageMediaAttachment()) - ] - for (id, parser) in parsers { - TGMessage.registerMediaAttachmentParser(id, parser: parser) - } - return true -}() - -private func parseSecretChatData(peerId: PeerId, data: Data, unreadCount: Int32) -> (SecretChatData, [MessageId.Namespace: PeerReadState], Int32)? { - let reader = LegacyBufferReader(LegacyBuffer(data: data)) - guard let magic = reader.readInt32() else { - return nil - } - var version: Int32 = 1 - if magic == 0x7acde441 { - guard let value = reader.readInt32() else { - return nil - } - version = value - } - - if version < 2 { - return nil - } - - for _ in 0 ..< 3 { - guard let length = reader.readInt32() else { - return nil - } - reader.skip(Int(length)) - } - - guard let hasEncryptedData = reader.readBytesAsInt32(1), hasEncryptedData == 1 else { - return nil - } - guard let secretChatData = readSecretChatData(reader: reader) else { - return nil - } - reader.skip(4) - reader.skip(4) - reader.skip(8) - reader.skip(4) - reader.skip(4) - reader.skip(4) - reader.skip(4) - guard let maxReadDate = reader.readInt32() else { - return nil - } - guard let maxOutgoingReadDate = reader.readInt32() else { - return nil - } - guard let messageDate = reader.readInt32() else { - return nil - } - guard let minMessageDate = reader.readInt32() else { - return nil - } - - let readStates: [MessageId.Namespace: PeerReadState] = [ - Namespaces.Message.SecretIncoming: .indexBased(maxIncomingReadIndex: MessageIndex(id: MessageId(peerId: peerId, namespace: Namespaces.Message.SecretIncoming, id: 1), timestamp: maxReadDate), maxOutgoingReadIndex: MessageIndex.lowerBound(peerId: peerId), count: 0, markedUnread: false), - Namespaces.Message.Local: .indexBased(maxIncomingReadIndex: MessageIndex.lowerBound(peerId: peerId), maxOutgoingReadIndex: MessageIndex(id: MessageId(peerId: peerId, namespace: Namespaces.Message.Local, id: 1), timestamp: maxOutgoingReadDate), count: 0, markedUnread: false) - ] - return (secretChatData, readStates, max(messageDate, minMessageDate)) -} - -private enum CustomPropertyKey { - case string(String) - case hash(Int32) -} - -private func loadLegacyPeerCustomProperyData(database: SqliteInterface, peerId: Int64, key: CustomPropertyKey) -> Data? { - var propertiesData: Data? - database.select("SELECT custom_properties FROM peers_v29 WHERE pid=\(peerId)", { cursor in - propertiesData = cursor.getData(at: 0) - return false - }) - if let propertiesData = propertiesData { - let keyHash: Int32 - switch key { - case let .string(string): - keyHash = HashFunctions.murMurHash32(string) - case let .hash(hash): - keyHash = hash - } - let reader = LegacyBufferReader(LegacyBuffer(data: propertiesData)) - - guard let _ = reader.readInt32() else { - return nil - } - guard let count = reader.readInt32() else { - return nil - } - for _ in 0 ..< Int(count) { - guard let valueKey = reader.readInt32() else { - return nil - } - guard let valueLength = reader.readInt32() else { - return nil - } - if valueKey == keyHash { - return reader.readBuffer(Int(valueLength))?.makeData() - } - reader.skip(Int(valueLength)) - } - } - return nil -} - -private func loadLegacyPeerCustomProperyInt32(database: SqliteInterface, peerId: Int64, key: CustomPropertyKey) -> Int32? { - guard let data = loadLegacyPeerCustomProperyData(database: database, peerId: peerId, key: key), data.count == 4 else { - return nil - } - var result: Int32 = 0 - withUnsafeMutablePointer(to: &result, { bytes -> Void in - data.copyBytes(to: UnsafeMutableRawPointer(bytes).assumingMemoryBound(to: UInt8.self), from: 0 ..< 4) - }) - return result -} - -private func loadLegacyMessages(account: TemporaryAccount, basePath: String, accountPeerId: PeerId, peerId: PeerId, userPeerId: PeerId, database: SqliteInterface, conversationId: Int64, expectedTotalCount: Int32) -> Signal { - return Signal { subscriber in - subscriber.putNext(0.0) - - var copyLocalFiles: [(MediaResource, String)] = [] - var messages: [StoreMessage] = [] - - Logger.shared.log("loadLegacyMessages", "begin peerId \(peerId) conversationId \(conversationId) count \(expectedTotalCount)") - - database.select("CREATE INDEX IF NOT EXISTS random_ids_mid ON random_ids_v29 (mid)", { _ in - return true - }) - - var messageIndex: Int32 = -1 - let reportBase = max(1, expectedTotalCount / 100) - - database.select("SELECT mid, message, media, from_id, dstate, date, flags, localMid, content_properties FROM messages_v29 WHERE cid=\(conversationId)", { cursor in - messageIndex += 1 - - #if DEBUG - //usleep(500000) - #endif - - if messageIndex % reportBase == 0 { - subscriber.putNext(min(1.0, Float(messageIndex) / Float(expectedTotalCount))) - } - - let messageId = cursor.getInt32(at: 0) - - //Logger.shared.log("loadLegacyMessages", "import message \(messageId)") - - var globallyUniqueId: Int64? - database.select("SELECT random_id FROM random_ids_v29 where mid=\(messageId)", { innerCursor in - globallyUniqueId = innerCursor.getInt64(at: 0) - return false - }) - - let text = cursor.getString(at: 1) - let fromId = cursor.getInt64(at: 3) - let deliveryState = cursor.getInt32(at: 4) - let timestamp = cursor.getInt32(at: 5) - let autoremoveTimeout = cursor.getInt32(at: 7) - let contentPropertiesData = cursor.getData(at: 8) - - let parsedAuthorId: PeerId - let parsedId: StoreMessageId - var parsedFlags: StoreMessageFlags = [] - var parsedAttributes: [MessageAttribute] = [] - var parsedMedia: [Media] = [] - var parsedGroupingKey: Int64? - - if fromId == accountPeerId.id { - parsedAuthorId = accountPeerId - parsedId = .Partial(peerId, Namespaces.Message.Local) - } else { - parsedAuthorId = userPeerId - parsedId = .Partial(peerId, Namespaces.Message.SecretIncoming) - parsedFlags.insert(.Incoming) - } - - if deliveryState != 0 { - return true - } - - if !contentPropertiesData.isEmpty { - if let contentProperties = TGMessage.parseContentProperties(contentPropertiesData) { - for (_, value) in contentProperties { - if let value = value as? TGMessageGroupedIdContentProperty { - parsedGroupingKey = value.groupedId - } - } - } - } - - //Logger.shared.log("loadLegacyMessages", "message \(messageId) read content properties") - - let media = cursor.getData(at: 2) - if let mediaList = TGMessage.parseMediaAttachments(media) { - for item in mediaList { - if let item = item as? TGImageMediaAttachment { - let mediaId = MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()) - var representations: [TelegramMediaImageRepresentation] = [] - if let allSizes = item.imageInfo?.allSizes() as? [String: NSValue] { - - for (imageUrl, sizeValue) in allSizes { - var resource: TelegramMediaResource = LocalFileMediaResource(fileId: arc4random64()) - var resourcePath: String? - if let (path, updatedResource) = pathAndResourceFromEncryptedFileUrl(basePath: basePath, url: imageUrl, type: .image) { - resource = updatedResource - copyLocalFiles.append((updatedResource, path)) - resourcePath = path - } else if imageUrl.hasPrefix("file://"), let path = URL(string: imageUrl)?.path { - copyLocalFiles.append((resource, path)) - resourcePath = path - } - - var dimensions = sizeValue.cgSizeValue - if let resourcePath = resourcePath, let image = UIImage(contentsOfFile: resourcePath) { - dimensions = image.size - } - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(dimensions), resource: resource, progressiveSizes: [])) - } - } - - if item.localImageId != 0 { - let fullSizePath = basePath + "/Documents/files/image-local-\(String(item.localImageId, radix: 16))/image.jpg" - if let image = UIImage(contentsOfFile: fullSizePath) { - let resource: TelegramMediaResource = LocalFileMediaResource(fileId: arc4random64()) - copyLocalFiles.append((resource, fullSizePath)) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(image.size), resource: resource, progressiveSizes: [])) - } - } - - parsedMedia.append(TelegramMediaImage(imageId: mediaId, representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])) - } else if let item = item as? TGVideoMediaAttachment { - let mediaId = MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()) - var representations: [TelegramMediaImageRepresentation] = [] - if let allSizes = item.thumbnailInfo?.allSizes() as? [String: NSValue] { - for (imageUrl, sizeValue) in allSizes { - var resource: TelegramMediaResource = LocalFileMediaResource(fileId: arc4random64()) - if let (path, updatedResource) = pathAndResourceFromEncryptedFileUrl(basePath: basePath, url: imageUrl, type: .image) { - resource = updatedResource - copyLocalFiles.append((updatedResource, path)) - } else if imageUrl.hasPrefix("file://"), let path = URL(string: imageUrl)?.path { - copyLocalFiles.append((resource, path)) - } - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(sizeValue.cgSizeValue), resource: resource, progressiveSizes: [])) - } - } - - var resource: TelegramMediaResource = LocalFileMediaResource(fileId: arc4random64()) - - var attributes: [TelegramMediaFileAttribute] = [] - attributes.append(.Video(duration: Int(item.duration), size: PixelDimensions(item.dimensions), flags: item.roundMessage ? .instantRoundVideo : [])) - - var size: Int32 = 0 - if let videoUrl = item.videoInfo?.url(withQuality: 1, actualQuality: nil, actualSize: &size) { - if let path = pathFromLegacyLocalVideoUrl(basePath: basePath, url: videoUrl) { - copyLocalFiles.append((resource, path)) - } else if let (path, updatedResource) = pathAndResourceFromEncryptedFileUrl(basePath: basePath, url: videoUrl, type: .video) { - resource = updatedResource - copyLocalFiles.append((updatedResource, path)) - } else if videoUrl.hasPrefix("file://"), let path = URL(string: videoUrl)?.path { - copyLocalFiles.append((resource, path)) - } - } - parsedMedia.append(TelegramMediaFile(fileId: mediaId, partialReference: nil, resource: resource, previewRepresentations: representations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: size == 0 ? nil : Int(size), attributes: attributes)) - } else if let item = item as? TGAudioMediaAttachment { - let mediaId = MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()) - let representations: [TelegramMediaImageRepresentation] = [] - - var resource: TelegramMediaResource = LocalFileMediaResource(fileId: arc4random64()) - - var attributes: [TelegramMediaFileAttribute] = [] - attributes.append(.Audio(isVoice: true, duration: Int(item.duration), title: nil, performer: nil, waveform: nil)) - - let size: Int32 = item.fileSize - let audioUrl = item.audioUri ?? "" - - if let path = pathFromLegacyLocalVideoUrl(basePath: basePath, url: audioUrl) { - copyLocalFiles.append((resource, path)) - } else if let (path, updatedResource) = pathAndResourceFromEncryptedFileUrl(basePath: basePath, url: audioUrl, type: .audio) { - resource = updatedResource - copyLocalFiles.append((updatedResource, path)) - } else if audioUrl.hasPrefix("file://"), let path = URL(string: audioUrl)?.path { - copyLocalFiles.append((resource, path)) - } - parsedMedia.append(TelegramMediaFile(fileId: mediaId, partialReference: nil, resource: resource, previewRepresentations: representations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: size == 0 ? nil : Int(size), attributes: attributes)) - } else if let item = item as? TGDocumentMediaAttachment { - let mediaId = MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()) - var representations: [TelegramMediaImageRepresentation] = [] - if let allSizes = (item.thumbnailInfo?.allSizes()) as? [String: NSValue] { - for (imageUrl, sizeValue) in allSizes { - var resource: TelegramMediaResource = LocalFileMediaResource(fileId: arc4random64()) - if let (path, updatedResource) = pathAndResourceFromEncryptedFileUrl(basePath: basePath, url: imageUrl, type: .image) { - resource = updatedResource - copyLocalFiles.append((updatedResource, path)) - } else if imageUrl.hasPrefix("file://"), let path = URL(string: imageUrl)?.path { - copyLocalFiles.append((resource, path)) - } else if let updatedResource = resourceFromLegacyImageUrl(imageUrl) { - resource = updatedResource - copyLocalFiles.append((resource, pathFromLegacyImageUrl(basePath: basePath, url: imageUrl))) - } - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(sizeValue.cgSizeValue), resource: resource, progressiveSizes: [])) - } - } - - var resource: TelegramMediaResource = LocalFileMediaResource(fileId: arc4random64()) - - var attributes: [TelegramMediaFileAttribute] = [] - var fileName = "file" - if let itemAttributes = item.attributes { - for attribute in itemAttributes { - if let attribute = attribute as? TGDocumentAttributeFilename { - attributes.append(.FileName(fileName: attribute.filename ?? "file")) - fileName = attribute.filename ?? "file" - } else if let attribute = attribute as? TGDocumentAttributeAudio { - let title = attribute.title ?? "" - let performer = attribute.performer ?? "" - var waveform: MemoryBuffer? - if let data = attribute.waveform { - waveform = MemoryBuffer(data: data.bitstream()!) - } - attributes.append(.Audio(isVoice: attribute.isVoice, duration: Int(attribute.duration), title: title.isEmpty ? nil : title, performer: performer.isEmpty ? nil : performer, waveform: waveform)) - } else if let _ = attribute as? TGDocumentAttributeAnimated { - attributes.append(.Animated) - } else if let attribute = attribute as? TGDocumentAttributeVideo { - attributes.append(.Video(duration: Int(attribute.duration), size: PixelDimensions(attribute.size), flags: attribute.isRoundMessage ? .instantRoundVideo : [])) - } else if let attribute = attribute as? TGDocumentAttributeSticker { - var packReference: StickerPackReference? - if let reference = attribute.packReference as? TGStickerPackIdReference { - packReference = .id(id: reference.packId, accessHash: reference.packAccessHash) - } else if let reference = attribute.packReference as? TGStickerPackShortnameReference { - packReference = .name(reference.shortName ?? "") - } - attributes.append(.Sticker(displayText: attribute.alt ?? "", packReference: packReference, maskData: nil)) - } else if let attribute = attribute as? TGDocumentAttributeImageSize { - attributes.append(.ImageSize(size: PixelDimensions(attribute.size))) - } - } - } - - let documentUri = item.documentUri ?? "" - - let size: Int32 = item.size - if documentUri.hasPrefix("file://"), let path = URL(string: documentUri)?.path { - copyLocalFiles.append((resource, path)) - } else if let (path, updatedResource) = pathAndResourceFromEncryptedFileUrl(basePath: basePath, url: documentUri, type: .document(fileName: fileName)) { - resource = updatedResource - copyLocalFiles.append((resource, path)) - } else if item.localDocumentId != 0 { - copyLocalFiles.append((resource, pathFromLegacyFile(basePath: basePath, fileId: item.localDocumentId, isLocal: true, fileName: TGDocumentMediaAttachment.safeFileName(forFileName: fileName) ?? ""))) - } else if item.documentId != 0 { - copyLocalFiles.append((resource, pathFromLegacyFile(basePath: basePath, fileId: item.documentId, isLocal: false, fileName: TGDocumentMediaAttachment.safeFileName(forFileName: fileName) ?? ""))) - } - parsedMedia.append(TelegramMediaFile(fileId: mediaId, partialReference: nil, resource: resource, previewRepresentations: representations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: item.mimeType ?? "application/octet-stream", size: size == 0 ? nil : Int(size), attributes: attributes)) - } else if let item = item as? TGActionMediaAttachment { - if item.actionType == TGMessageActionEncryptedChatMessageLifetime, let actionData = item.actionData, let timeout = actionData["messageLifetime"] as? Int32 { - - parsedMedia.append(TelegramMediaAction(action: .messageAutoremoveTimeoutUpdated(timeout))) - } - } else if let item = item as? TGContactMediaAttachment { - parsedMedia.append(TelegramMediaContact(firstName: item.firstName ?? "", lastName: item.lastName ?? "", phoneNumber: item.phoneNumber ?? "", peerId: nil, vCardData: nil)) - } else if let item = item as? TGLocationMediaAttachment { - var venue: MapVenue? - if let v = item.venue { - venue = MapVenue(title: v.title ?? "", address: v.address ?? "", provider: v.provider == "" ? nil : v.provider, id: v.venueId == "" ? nil : v.venueId, type: v.type == "" ? nil : v.type) - } - parsedMedia.append(TelegramMediaMap(latitude: item.latitude, longitude: item.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: venue, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil)) - } - } - } - - //Logger.shared.log("loadLegacyMessages", "message \(messageId) read media") - - if autoremoveTimeout != 0 { - var countdownBeginTime: Int32? - database.select("SELECT date FROM selfdestruct_v29 where mid=\(messageId)", { innerCursor in - countdownBeginTime = innerCursor.getInt32(at: 0) - autoremoveTimeout - return false - }) - parsedAttributes.append(AutoremoveTimeoutMessageAttribute(timeout: autoremoveTimeout, countdownBeginTime: countdownBeginTime)) - } - - let (parsedTags, parsedGlobalTags) = tagsForStoreMessage(incoming: parsedFlags.contains(.Incoming), attributes: parsedAttributes, media: parsedMedia, textEntities: nil, isPinned: false) - messages.append(StoreMessage(id: parsedId, globallyUniqueId: globallyUniqueId, groupingKey: parsedGroupingKey, threadId: nil, timestamp: timestamp, flags: parsedFlags, tags: parsedTags, globalTags: parsedGlobalTags, localTags: [], forwardInfo: nil, authorId: parsedAuthorId, text: text, attributes: parsedAttributes, media: parsedMedia)) - - //Logger.shared.log("loadLegacyMessages", "message \(messageId) completed") - - return true - }) - - let disposable = (account.postbox.transaction { transaction -> Void in - //Logger.shared.log("loadLegacyMessages", "conversation \(conversationId) storing messages") - let _ = transaction.addMessages(messages, location: .UpperHistoryBlock) - - //Logger.shared.log("loadLegacyMessages", "conversation \(conversationId) copying \(copyLocalFiles.count) files") - - for (resource, path) in copyLocalFiles { - account.postbox.mediaBox.copyResourceData(resource.id, fromTempPath: path) - } - - Logger.shared.log("loadLegacyMessages", "conversation \(conversationId) done") - }).start(completed: { - subscriber.putCompletion() - }) - - return disposable - } -} - -private func importChannelBroadcastPreferences(account: TemporaryAccount, basePath: String, database: SqliteInterface) -> Signal { - return deferred { () -> Signal in - var peerIds: [Int64] = [] - database.select("SELECT cid FROM channel_conversations_v29", { cursor in - peerIds.append(cursor.getInt64(at: 0)) - return true - }) - var peerIdsWithMutedMessages: [Int64] = [] - for peerId in peerIds { - if let data = loadLegacyPeerCustomProperyData(database: database, peerId: peerId, key: .hash(0x374BF349)), !data.isEmpty { - let reader = LegacyBufferReader(LegacyBuffer(data: data)) - guard let version = reader.readBytesAsInt32(1) else { - continue - } - guard let _ = reader.readBytesAsInt32(1) else { - continue - } - if version >= 2 { - guard let messagesMuted = reader.readBytesAsInt32(1) else { - continue - } - if messagesMuted == 1 { - peerIdsWithMutedMessages.append(peerId) - } - } - } - } - - return .complete() - } -} - -func loadLegacySecretChats(account: TemporaryAccount, basePath: String, accountPeerId: PeerId, database: SqliteInterface) -> Signal { - return deferred { () -> Signal in - var peerIdToConversationId: [PeerId: Int64] = [:] - database.select("SELECT encrypted_id, cid FROM encrypted_cids_v29", { cursor in - peerIdToConversationId[PeerId(namespace: Namespaces.Peer.SecretChat, id: cursor.getInt32(at: 0))] = cursor.getInt64(at: 1) - return true - }) - var chatInfos: [(TelegramSecretChat, SecretChatState, Int32?, [MessageId.Namespace: PeerReadState], Int64)] = [] - for (peerId, conversationId) in peerIdToConversationId { - database.select("SELECT chat_photo, unread_count, participants, date FROM convesations_v29 WHERE cid=\(conversationId)", { cursor in - guard let (secretChatData, readStates, minMessageDate) = parseSecretChatData(peerId: peerId, data: cursor.getData(at: 0), unreadCount: cursor.getInt32(at: 1)) else { - return false - } - guard let (role, userPeerId) = readSecretChatParticipantData(accountPeerId: accountPeerId, data: cursor.getData(at: 2)) else { - return false - } - let chatMessageDate = cursor.getInt32(at: 3) - let messageDate = min(minMessageDate, chatMessageDate) - - let messageLifetime = loadLegacyPeerCustomProperyInt32(database: database, peerId: conversationId, key: .string("messageLifetime")) ?? 0 - - let state: SecretChatState - var seqOut: Int32? - - switch secretChatData.handshakeState { - case 1: //requested - guard let a = loadLegacyPeerCustomProperyData(database: database, peerId: conversationId, key: .string("a")), !a.isEmpty else { - return false - } - state = SecretChatState(role: .creator, embeddedState: .handshake(.requested(g: 3, p: MemoryBuffer(data: defaultPrime), a: MemoryBuffer(data: a))), keychain: SecretChatKeychain(keys: []), keyFingerprint: nil, messageAutoremoveTimeout: nil) - case 2: //accepting - return false - case 3: //terminated - state = SecretChatState(role: .creator, embeddedState: .terminated, keychain: SecretChatKeychain(keys: []), keyFingerprint: nil, messageAutoremoveTimeout: nil) - case 4: - guard let sha1Fingerprint = loadLegacyPeerCustomProperyData(database: database, peerId: conversationId, key: .string("encryptionKeySha1")) else { - return false - } - guard let sha256Fingerprint = loadLegacyPeerCustomProperyData(database: database, peerId: conversationId, key: .string("encryptionKeySha256")) else { - return false - } - - guard let keysData = loadLegacyPeerCustomProperyData(database: database, peerId: conversationId, key: .string("encryptionKeys")) else { - return false - } - guard let keysArray = NSKeyedUnarchiver.unarchiveObject(with: keysData) as? [TGEncryptionKeyData] else { - return false - } - let parsedKeys: [SecretChatKey] = keysArray.map({ key in - return SecretChatKey(fingerprint: key.keyId, key: MemoryBuffer(data: key.key), validity: .sequenceBasedIndexRange(fromCanonicalIndex: key.firstSeqOut), useCount: 1) - }) - let requestedLayerValue = loadLegacyPeerCustomProperyInt32(database: database, peerId: conversationId, key: .hash(reportedLayer_hash)) ?? 0 - let appliedSeqInValue = loadLegacyPeerCustomProperyInt32(database: database, peerId: conversationId, key: .hash(seq_in_hash)) ?? 0 - guard let seqOutValue = loadLegacyPeerCustomProperyInt32(database: database, peerId: conversationId, key: .hash(seq_out_hash)) else { - return false - } - seqOut = seqOutValue - guard let activeLayerValue = loadLegacyPeerCustomProperyInt32(database: database, peerId: conversationId, key: .hash(layer_hash)) else { - return false - } - guard let activeLayer = SecretChatSequenceBasedLayer(rawValue: activeLayerValue) else { - return false - } - let rekeyState: SecretChatRekeySessionState? = secretChatData.rekeyState - let embeddedState: SecretChatEmbeddedState = .sequenceBasedLayer(SecretChatSequenceBasedLayerState(layerNegotiationState: SecretChatLayerNegotiationState(activeLayer: activeLayer, locallyRequestedLayer: requestedLayerValue == 0 ? nil : requestedLayerValue, remotelyRequestedLayer: nil), rekeyState: rekeyState, baseIncomingOperationIndex: 0, baseOutgoingOperationIndex: 0, topProcessedCanonicalIncomingOperationIndex: appliedSeqInValue == 0 ? nil : max(0, appliedSeqInValue - 1))) - state = SecretChatState(role: role, embeddedState: embeddedState, keychain: SecretChatKeychain(keys: parsedKeys), keyFingerprint: SecretChatKeyFingerprint(sha1: SecretChatKeySha1Fingerprint(digest: sha1Fingerprint), sha256: SecretChatKeySha256Fingerprint(digest: sha256Fingerprint)), messageAutoremoveTimeout: messageLifetime == 0 ? nil : messageLifetime) - default: - return false - } - - let secretChat = TelegramSecretChat(id: peerId, creationDate: messageDate, regularPeerId: userPeerId, accessHash: secretChatData.accessHash, role: role, embeddedState: state.embeddedState.peerState, messageAutoremoveTimeout: messageLifetime == 0 ? nil : messageLifetime) - - chatInfos.append((secretChat, state, seqOut, readStates, conversationId)) - - return false - }) - } - var userPeers: [PeerId: Peer] = [:] - var presences: [PeerId: PeerPresence] = [:] - for info in chatInfos { - if let (peer, presence) = loadLegacyUser(database: database, id: info.0.regularPeerId.id) { - userPeers[peer.id] = peer - presences[peer.id] = presence - } - } - - let storedChats = account.postbox.transaction { transaction -> Void in - updatePeers(transaction: transaction, peers: Array(userPeers.values), update: { _, updated in - return updated - }) - transaction.updatePeerPresencesInternal(presences: presences, merge: { _, updated in return updated }) - for (peer, state, seqOutValue, readStates, _) in chatInfos { - if userPeers[peer.regularPeerId] == nil { - continue - } - updatePeers(transaction: transaction, peers: [peer], update: { _, updated in - return updated - }) - transaction.setPeerChatState(peer.id, state: state) - switch state.embeddedState { - case .sequenceBasedLayer: - if let seqOutValue = seqOutValue { - transaction.operationLogResetIndices(peerId: peer.id, tag: OperationLogTags.SecretOutgoing, nextTagLocalIndex: seqOutValue + 1) - } - default: - break - } - transaction.resetIncomingReadStates([peer.id: readStates]) - } - } - |> ignoreValues - - let _ = registeredAttachmentParsers - - var countByConversationId: [Int64: Int32] = [:] - var totalCount: Int32 = 0 - - for info in chatInfos { - database.select("SELECT COUNT(*) FROM messages_v29 WHERE cid=\(info.4)", { cursor in - let count = cursor.getInt32(at: 0) - countByConversationId[info.4] = count - totalCount += count - return true - }) - } - - var storedMessagesSignals: Signal = .single(0.0) - var cumulativeCount: Int32 = 0 - for info in chatInfos { - let localBaseline = cumulativeCount - let localCount = countByConversationId[info.4] ?? 0 - storedMessagesSignals = storedMessagesSignals - |> then( - loadLegacyMessages(account: account, basePath: basePath, accountPeerId: accountPeerId, peerId: info.0.id, userPeerId: info.0.regularPeerId, database: database, conversationId: info.4, expectedTotalCount: localCount) - |> map { localProgress -> Float in - if totalCount <= 0 { - return 0.0 - } - let globalCount = localBaseline + Int32(localProgress * Float(localCount)) - return Float(globalCount) / Float(totalCount) - } - ) - cumulativeCount += countByConversationId[info.4] ?? 0 - } - - return storedChats - |> map { _ -> Float in return 0.0 } - |> then(storedMessagesSignals) - } -} diff --git a/submodules/LegacyDataImport/Sources/LegacyDataImport.swift b/submodules/LegacyDataImport/Sources/LegacyDataImport.swift deleted file mode 100644 index 4676e4b16a..0000000000 --- a/submodules/LegacyDataImport/Sources/LegacyDataImport.swift +++ /dev/null @@ -1,245 +0,0 @@ -import Foundation -import UIKit -import TelegramCore -import SyncCore -import SwiftSignalKit -import Postbox -import MtProtoKit -import LegacyDataImportImpl - -public enum AccountImportError: Error { - case generic -} - -public enum AccountImportProgressType { - case generic - case messages - case media -} - -private func importedAccountData(basePath: String, documentsPath: String, accountManager: AccountManager, account: TemporaryAccount, database: SqliteInterface) -> Signal<(AccountImportProgressType, Float), AccountImportError> { - return deferred { () -> Signal<(AccountImportProgressType, Float), AccountImportError> in - let keychain = MTFileBasedKeychain(name: "Telegram", documentsPath: documentsPath) - guard let masterDatacenterId = keychain.object(forKey: "defaultDatacenterId", group: "persistent") as? Int else { - return .fail(.generic) - } - let keychainContents = keychain.contents(forGroup: "persistent") - - let importKeychain = account.postbox.transaction { transaction -> Void in - for (key, value) in keychainContents { - let data = NSKeyedArchiver.archivedData(withRootObject: value) - transaction.setKeychainEntry(data, forKey: "persistent" + ":" + key) - } - } - |> ignoreValues - |> castError(AccountImportError.self) - - let importData = importPreferencesData(documentsPath: documentsPath, masterDatacenterId: Int32(masterDatacenterId), account: account, database: database) - |> mapToSignal { accountUserId -> Signal<(AccountImportProgressType, Float), AccountImportError> in - return importDatabaseData(accountManager: accountManager, account: account, basePath: basePath, database: database, accountUserId: accountUserId) - } - - return importKeychain - |> map { _ -> (AccountImportProgressType, Float) in return (.generic, 0.0) } - |> then(importData) - } -} - -private func importPreferencesData(documentsPath: String, masterDatacenterId: Int32, account: TemporaryAccount, database: SqliteInterface) -> Signal { - return deferred { () -> Signal in - let defaultsPath = documentsPath + "/standard.defaults" - var parsedAccountUserId: Int32? - if let data = try? Data(contentsOf: URL(fileURLWithPath: defaultsPath)), let dict = NSKeyedUnarchiver.unarchiveObject(with: data) as? [String: Any], let id = dict["telegraphUserId"] as? Int { - parsedAccountUserId = Int32(id) - } - if parsedAccountUserId == nil { - if let id = UserDefaults.standard.object(forKey: "telegraphUserId") as? Int { - parsedAccountUserId = Int32(id) - } - } - - if let parsedAccountUserId = parsedAccountUserId { - return account.postbox.transaction { transaction -> Int32 in - transaction.setState(AuthorizedAccountState(isTestingEnvironment: false, masterDatacenterId: masterDatacenterId, peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: parsedAccountUserId), state: nil)) - return parsedAccountUserId - } - |> castError(AccountImportError.self) - } else { - return .fail(.generic) - } - } -} - -private func importDatabaseData(accountManager: AccountManager, account: TemporaryAccount, basePath: String, database: SqliteInterface, accountUserId: Int32) -> Signal<(AccountImportProgressType, Float), AccountImportError> { - return deferred { () -> Signal<(AccountImportProgressType, Float), AccountImportError> in - var importedAccountUser: Signal = .complete() - if let (user, presence) = loadLegacyUser(database: database, id: accountUserId) { - importedAccountUser = account.postbox.transaction { transaction -> Void in - updatePeers(transaction: transaction, peers: [user], update: { _, updated in updated }) - transaction.updatePeerPresencesInternal(presences: [user.id: presence], merge: { _, updated in return updated }) - } - |> ignoreValues - |> castError(AccountImportError.self) - } - - let importedSecretChats = loadLegacySecretChats(account: account, basePath: basePath, accountPeerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: accountUserId), database: database) - |> castError(AccountImportError.self) - - /*let importedFiles = loadLegacyFiles(account: account, basePath: basePath, accountPeerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: accountUserId), database: database) - |> castError(AccountImportError.self)*/ - - let importedLegacyPreferences = importLegacyPreferences(accountManager: accountManager, account: account, documentsPath: basePath + "/Documents", database: database) - |> castError(AccountImportError.self) - - return importedAccountUser - |> map { _ -> (AccountImportProgressType, Float) in return (.generic, 0.0) } - |> then( - importedLegacyPreferences - |> map { _ -> (AccountImportProgressType, Float) in return (.generic, 0.0) } - ) - |> then( - importedSecretChats - |> map { value -> (AccountImportProgressType, Float) in return (.messages, value) } - ) - } -} - -public enum ImportedLegacyAccountEvent { - case progress(AccountImportProgressType, Float) - case result(AccountRecordId?) -} - -public func importedLegacyAccount(basePath: String, accountManager: AccountManager, encryptionParameters: ValueBoxEncryptionParameters, present: @escaping (UIViewController) -> Void) -> Signal { - let queue = Queue() - return deferred { () -> Signal in - let documentsPath = basePath + "/Documents" - if FileManager.default.fileExists(atPath: documentsPath + "/importcompleted") { - return .single(.result(nil)) - } - - let unlockedDatabasePathAndKey: Signal<(String, Data?)?, AccountImportError> - if FileManager.default.fileExists(atPath: documentsPath + "/tgdata.db.y") { - let databasePath = documentsPath + "/tgdata.db.y" - let unlockDatabase = Signal<(String, Data?)?, AccountImportError> { subscriber in - let alertController = UIAlertController(title: nil, message: "Enter your passcode", preferredStyle: .alert) - - let confirmAction = UIAlertAction(title: "Enter", style: .default) { _ in - let passcode = alertController.textFields?[0].text - - func checkPasscode(_ value: String) -> Bool { - guard let database = SqliteInterface(databasePath: databasePath) else { - return false - } - let key = value.data(using: .utf8)! - if !database.unlock(password: hexString(key).data(using: .utf8)!) { - return false - } - - return true - } - - if checkPasscode(passcode ?? "") { - subscriber.putNext((databasePath, (passcode ?? "").data(using: .utf8)!)) - subscriber.putCompletion() - } else { - let alertController = UIAlertController(title: nil, message: "Invalid passcode. Please try again.", preferredStyle: .alert) - - let confirmAction = UIAlertAction(title: "OK", style: .default) { _ in - subscriber.putCompletion() - } - - alertController.addAction(confirmAction) - - present(alertController) - } - } - - let cancelAction = UIAlertAction(title: "Skip", style: .cancel) { _ in - subscriber.putNext(nil) - subscriber.putCompletion() - } - - alertController.addTextField { textField in - textField.placeholder = "Passcode" - } - - alertController.addAction(confirmAction) - alertController.addAction(cancelAction) - - present(alertController) - return EmptyDisposable - } - |> runOn(Queue.mainQueue()) - - unlockedDatabasePathAndKey = (unlockDatabase - |> mapToSignal { result -> Signal<(String, Data?)?, AccountImportError> in - if let result = result { - return .single(result) - } else { - let askAgain = Signal<(String, Data?)?, AccountImportError> { subscriber in - let alertController = UIAlertController(title: "Warning", message: "If you continue without entering your passcode, all your secret chats will be lost.", preferredStyle: .alert) - - let confirmAction = UIAlertAction(title: "Skip", style: .destructive) { _ in - subscriber.putError(.generic) - } - - let cancelAction = UIAlertAction(title: "Try Again", style: .cancel) { _ in - subscriber.putCompletion() - } - - alertController.addAction(confirmAction) - alertController.addAction(cancelAction) - - present(alertController) - return EmptyDisposable - } - |> runOn(Queue.mainQueue()) - return askAgain - } - }) - |> restart - |> take(1) - } else if FileManager.default.fileExists(atPath: documentsPath + "/tgdata.db") { - unlockedDatabasePathAndKey = .single((documentsPath + "/tgdata.db", nil)) - } else { - return .single(.result(nil)) - } - - return unlockedDatabasePathAndKey - |> mapToSignal { pathAndKey -> Signal in - guard let pathAndKey = pathAndKey else { - return .fail(.generic) - } - - guard let database = SqliteInterface(databasePath: pathAndKey.0) else { - return .fail(.generic) - } - - if let key = pathAndKey.1 { - if !database.unlock(password: hexString(key).data(using: .utf8)!) { - return .fail(.generic) - } - } - - return temporaryAccount(manager: accountManager, rootPath: rootPathForBasePath(basePath), encryptionParameters: encryptionParameters) - |> castError(AccountImportError.self) - |> mapToSignal { account -> Signal in - let actions = importedAccountData(basePath: basePath, documentsPath: documentsPath, accountManager: accountManager, account: account, database: database) - var result = actions - |> map { typeAndProgress -> ImportedLegacyAccountEvent in - return .progress(typeAndProgress.0, typeAndProgress.1) - } - #if DEBUG - //result = result - //|> then(.never()) - #endif - - result = result - |> then(.single(.result(account.id))) - - return result - } - } - } - |> runOn(queue) -} diff --git a/submodules/LegacyDataImport/Sources/LegacyDataImportSplash.swift b/submodules/LegacyDataImport/Sources/LegacyDataImportSplash.swift deleted file mode 100644 index f121307d0e..0000000000 --- a/submodules/LegacyDataImport/Sources/LegacyDataImportSplash.swift +++ /dev/null @@ -1,89 +0,0 @@ -import Foundation -import Display -import AsyncDisplayKit -import TelegramPresentationData -import RadialStatusNode - -public protocol LegacyDataImportSplash: WindowCoveringView { - var progress: (AccountImportProgressType, Float) { get set } - var serviceAction: (() -> Void)? { get set } -} - -private final class LegacyDataImportSplashImpl: WindowCoveringView, LegacyDataImportSplash { - private let theme: PresentationTheme? - private let strings: PresentationStrings? - - public var progress: (AccountImportProgressType, Float) = (.generic, 0.0) { - didSet { - if self.progress.0 != oldValue.0 { - if let size = self.validSize { - switch self.progress.0 { - case .generic: - self.textNode.attributedText = NSAttributedString(string: self.strings?.AppUpgrade_Running ?? "Optimizing...", font: Font.regular(17.0), textColor: self.theme?.list.itemPrimaryTextColor ?? .black) - case .media: - self.textNode.attributedText = NSAttributedString(string: "Optimizing cache", font: Font.regular(17.0), textColor: self.theme?.list.itemPrimaryTextColor ?? .black) - case .messages: - self.textNode.attributedText = NSAttributedString(string: "Optimizing database", font: Font.regular(17.0), textColor: self.theme?.list.itemPrimaryTextColor ?? .black) - } - self.updateLayout(size) - } - } - self.progressNode.transitionToState(.progress(color: self.theme?.list.itemAccentColor ?? UIColor(rgb: 0x007ee5), lineWidth: 2.0, value: CGFloat(max(0.025, self.progress.1)), cancelEnabled: false, animateRotation: true), animated: false, completion: {}) - } - } - - public var serviceAction: (() -> Void)? - - private let progressNode: RadialStatusNode - private let textNode: ImmediateTextNode - - private var validSize: CGSize? - - public init(theme: PresentationTheme?, strings: PresentationStrings?) { - self.theme = theme - self.strings = strings - - self.progressNode = RadialStatusNode(backgroundNodeColor: theme?.list.plainBackgroundColor ?? .white) - self.textNode = ImmediateTextNode() - self.textNode.maximumNumberOfLines = 0 - self.textNode.textAlignment = .center - self.textNode.attributedText = NSAttributedString(string: self.strings?.AppUpgrade_Running ?? "Optimizing...", font: Font.regular(17.0), textColor: self.theme?.list.itemPrimaryTextColor ?? .black) - - super.init(frame: CGRect()) - - self.backgroundColor = self.theme?.list.plainBackgroundColor ?? .white - - self.addSubnode(self.progressNode) - self.progressNode.isUserInteractionEnabled = false - self.addSubnode(self.textNode) - self.textNode.isUserInteractionEnabled = false - - self.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(self.longPressGesture(_:)))) - } - - required public init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override public func updateLayout(_ size: CGSize) { - self.validSize = size - - let progressSize = CGSize(width: 60.0, height: 60.0) - - let textSize = self.textNode.updateLayout(CGSize(width: size.width - 20.0, height: .greatestFiniteMagnitude)) - - let progressFrame = CGRect(origin: CGPoint(x: floor((size.width - progressSize.width) / 2.0), y: floor((size.height - progressSize.height - 15.0 - textSize.height) / 2.0)), size: progressSize) - self.progressNode.frame = progressFrame - self.textNode.frame = CGRect(origin: CGPoint(x: floor((size.width - textSize.width) / 2.0), y: progressFrame.maxY + 15.0), size: textSize) - } - - @objc private func longPressGesture(_ recognizer: UILongPressGestureRecognizer) { - if case .began = recognizer.state { - self.serviceAction?() - } - } -} - -public func makeLegacyDataImportSplash(theme: PresentationTheme?, strings: PresentationStrings?) -> LegacyDataImportSplash { - return LegacyDataImportSplashImpl(theme: theme, strings: strings) -} diff --git a/submodules/LegacyDataImport/Sources/LegacyFileImport.swift b/submodules/LegacyDataImport/Sources/LegacyFileImport.swift deleted file mode 100644 index 56308641f2..0000000000 --- a/submodules/LegacyDataImport/Sources/LegacyFileImport.swift +++ /dev/null @@ -1,189 +0,0 @@ -import Foundation -import TelegramCore -import SyncCore -import SwiftSignalKit -import Postbox -import LegacyComponents - -private func importMediaFromMessageData(_ data: Data, basePath: String, copyLocalFiles: inout [(MediaResource, String)], cache: TGCache) { - if let message = TGMessage(keyValueCoder: PSKeyValueDecoder(data: data)) { - if let mediaAttachments = message.mediaAttachments { - importMediaFromMediaList(mediaAttachments, basePath: basePath, copyLocalFiles: ©LocalFiles, cache: cache) - } - } -} - -private func importMediaFromMediaData(_ data: Data, basePath: String, copyLocalFiles: inout [(MediaResource, String)], cache: TGCache) { - if let mediaAttachments = TGMessage.parseMediaAttachments(data) { - importMediaFromMediaList(mediaAttachments, basePath: basePath, copyLocalFiles: ©LocalFiles, cache: cache) - } -} - -private func importMediaFromMediaList(_ mediaAttachments: [Any], basePath: String, copyLocalFiles: inout [(MediaResource, String)], cache: TGCache) { - for media in mediaAttachments { - if let media = media as? TGDocumentMediaAttachment { - var fileName = "file" - if let itemAttributes = media.attributes { - for attribute in itemAttributes { - if let attribute = attribute as? TGDocumentAttributeFilename { - fileName = attribute.filename ?? "file" - } - } - } - - if media.documentId != 0 { - let filePath = pathFromLegacyFile(basePath: basePath, fileId: media.documentId, isLocal: false, fileName: TGDocumentMediaAttachment.safeFileName(forFileName: fileName) ?? "") - if FileManager.default.fileExists(atPath: filePath) { - copyLocalFiles.append((CloudDocumentMediaResource(datacenterId: Int(media.datacenterId), fileId: media.documentId, accessHash: media.accessHash, size: nil, fileReference: nil, fileName: nil), filePath)) - } - } - } else if let media = media as? TGVideoMediaAttachment { - if media.videoId != 0, let videoUrl = media.videoInfo?.url(withQuality: 1, actualQuality: nil, actualSize: nil) { - if let (id, accessHash, datacenterId, path) = pathFromLegacyVideoUrl(basePath: basePath, url: videoUrl) { - copyLocalFiles.append((CloudDocumentMediaResource(datacenterId: Int(datacenterId), fileId: id, accessHash: accessHash, size: nil, fileReference: nil, fileName: nil), path)) - } - } - } else if let media = media as? TGImageMediaAttachment { - if let allSizes = media.imageInfo?.allSizes() as? [String: NSValue] { - for (imageUrl, _) in allSizes { - if let path = cache.path(forCachedData: imageUrl), let resource = resourceFromLegacyImageUrl(imageUrl), FileManager.default.fileExists(atPath: path) { - copyLocalFiles.append((resource, path)) - } - } - } - } - } -} - -private func makeMessageSortKey(tag: Int32, conversationId: Int64, space: Int8, timestamp: Int32, messageId: Int32) -> Data { - let key = ValueBoxKey(length: 4 + 8 + 1 + 4 + 4) - key.setInt32(0, value: tag.byteSwapped) - key.setInt64(4, value: conversationId.byteSwapped) - key.setInt8(4 + 8, value: space) - key.setInt32(4 + 8 + 1, value: timestamp) - key.setInt32(4 + 8 + 1 + 4, value: messageId.byteSwapped) - return Data(bytes: key.memory, count: key.length) -} - -func loadLegacyFiles(account: TemporaryAccount, basePath: String, accountPeerId: PeerId, database: SqliteInterface) -> Signal { - return Signal { subscriber in - let _ = registeredAttachmentParsers - - subscriber.putNext(0.0) - - var channelIds: [Int64] = [] - database.select("SELECT DISTINCT cid FROM channel_message_tags_v29", { cursor in - channelIds.append(cursor.getInt64(at: 0)) - return true - }) - print(database.explain("SELECT DISTINCT cid FROM channel_message_tags_v29")) - - var channelMessageIds: [(Int64, Int32)] = [] - - print(database.explain("SELECT mid FROM channel_message_tags_v29 WHERE tag_sort_key<100 AND tag_sort_key>0 ORDER BY tag_sort_key DESC LIMIT 4000")) - - if !channelIds.isEmpty { - /* - TGSharedMediaCacheItemTypePhoto = 0, - TGSharedMediaCacheItemTypeVideo = 1, - TGSharedMediaCacheItemTypeFile = 2, - TGSharedMediaCacheItemTypePhotoVideo = 3, - TGSharedMediaCacheItemTypePhotoVideoFile = 4, - TGSharedMediaCacheItemTypeAudio = 5, - TGSharedMediaCacheItemTypeLink = 6, - TGSharedMediaCacheItemTypeSticker = 7, - TGSharedMediaCacheItemTypeGif = 8, - TGSharedMediaCacheItemTypeVoiceVideoMessage = 9 - */ - let tags: [Int32] = [ - 2, // File - 5, // Audio - 3, // PhotoVideo - ] - database.withStatement("SELECT mid FROM channel_message_tags_v29 WHERE tag_sort_key? ORDER BY tag_sort_key DESC LIMIT 4000", { select in - for channelId in channelIds { - for tag in tags { - select([.data(makeMessageSortKey(tag: tag, conversationId: channelId, space: 0, timestamp: Int32.max - 1, messageId: 0)), .data(makeMessageSortKey(tag: tag, conversationId: channelId, space: 0, timestamp: 0, messageId: 0))], { cursor in - channelMessageIds.append((channelId, cursor.getInt32(at: 0))) - return true - }) - select([.data(makeMessageSortKey(tag: tag, conversationId: channelId, space: 1, timestamp: Int32.max - 1, messageId: 0)), .data(makeMessageSortKey(tag: tag, conversationId: channelId, space: 1, timestamp: 0, messageId: 0))], { cursor in - channelMessageIds.append((channelId, cursor.getInt32(at: 0))) - return true - }) - } - } - }) - } - - var chatMessageIds: [Int32] = [] - let mediaTypes: [Int32] = [ - 1, // video - 2, // image - 3, // file - ] - for type in mediaTypes { - database.select("SELECT mids FROM media_cache_v29 WHERE media_type=\(type) ORDER BY date DESC LIMIT 32000", { cursor in - let midsData = cursor.getData(at: 0) - let reader = LegacyBufferReader(LegacyBuffer(data: midsData)) - while true { - if let mid = reader.readInt32() { - chatMessageIds.append(mid) - } else { - break - } - } - return true - }) - } - - var copyLocalFiles: [(MediaResource, String)] = [] - - let totalCount = channelMessageIds.count + chatMessageIds.count - let reportBase = max(1, totalCount / 100) - - var itemIndex = -1 - - let cache = TGCache(cachesPath: basePath + "/Caches")! - - if !channelMessageIds.isEmpty { - database.withStatement("SELECT data FROM channel_messages_v29 WHERE cid=? AND mid=?", { select in - for (peerId, messageId) in channelMessageIds { - itemIndex += 1 - if itemIndex % reportBase == 0 { - subscriber.putNext(Float(itemIndex) / Float(totalCount)) - } - select([.int64(peerId), .int32(messageId)], { cursor in - let data = cursor.getData(at: 0) - importMediaFromMessageData(data, basePath: basePath, copyLocalFiles: ©LocalFiles, cache: cache) - return true - }) - } - }) - } - - if !chatMessageIds.isEmpty { - database.withStatement("SELECT media FROM messages_v29 WHERE mid=?", { select in - for messageId in chatMessageIds { - itemIndex += 1 - if itemIndex % reportBase == 0 { - subscriber.putNext(Float(itemIndex) / Float(totalCount)) - } - select([.int32(messageId)], { cursor in - let data = cursor.getData(at: 0) - importMediaFromMediaData(data, basePath: basePath, copyLocalFiles: ©LocalFiles, cache: cache) - return true - }) - } - }) - } - - for (resource, path) in copyLocalFiles { - account.postbox.mediaBox.copyResourceData(resource.id, fromTempPath: path) - } - - subscriber.putCompletion() - - return EmptyDisposable - } -} diff --git a/submodules/LegacyDataImport/Sources/LegacyPreferencesImport.swift b/submodules/LegacyDataImport/Sources/LegacyPreferencesImport.swift deleted file mode 100644 index 019bb540ac..0000000000 --- a/submodules/LegacyDataImport/Sources/LegacyPreferencesImport.swift +++ /dev/null @@ -1,438 +0,0 @@ -import Foundation -import UIKit -import TelegramCore -import SyncCore -import SwiftSignalKit -import MtProtoKit -import TelegramUIPreferences -import LegacyComponents -import TelegramNotices -import LegacyDataImportImpl - -@objc(TGPresentationState) private final class TGPresentationState: NSObject, NSCoding { - let pallete: Int32 - let userInfo: Int32 - let fontSize: Int32 - - init?(coder aDecoder: NSCoder) { - self.pallete = aDecoder.decodeInt32(forKey: "p") - self.userInfo = aDecoder.decodeInt32(forKey: "u") - self.fontSize = aDecoder.decodeInt32(forKey: "f") - } - - func encode(with aCoder: NSCoder) { - assertionFailure() - } -} - -private enum PreferencesProvider { - case dict([String: Any]) - case standard(UserDefaults) - - subscript(_ key: String) -> Any? { - get { - switch self { - case let .dict(dict): - return dict[key] - case let .standard(standard): - return standard.object(forKey: key) - } - } - } -} - -private func loadLegacyCustomProperyData(database: SqliteInterface, key: String) -> Data? { - var result: Data? - database.select("SELECT value FROM service_v29 WHERE key=\(HashFunctions.murMurHash32(key))", { cursor in - result = cursor.getData(at: 0) - return false - }) - return result -} - -private func convertLegacyProxyPort(_ value: Int) -> Int32 { - if value < 0 { - return Int32(UInt16(bitPattern: Int16(clamping: value))) - } else { - return Int32(clamping: value) - } -} - -func importLegacyPreferences(accountManager: AccountManager, account: TemporaryAccount, documentsPath: String, database: SqliteInterface) -> Signal { - return deferred { () -> Signal in - var presentationState: TGPresentationState? - if let value = NSKeyedUnarchiver.unarchiveObject(withFile: documentsPath + "/presentation.dat") as? TGPresentationState { - presentationState = value - } - - var autoNightPreferences: TGPresentationAutoNightPreferences? - if let value = NSKeyedUnarchiver.unarchiveObject(withFile: documentsPath + "/autonight.dat") as? TGPresentationAutoNightPreferences { - autoNightPreferences = value - } - - let autoDownloadPreferences: TGAutoDownloadPreferences? = NSKeyedUnarchiver.unarchiveObject(withFile: documentsPath + "/autoDownload.pref") as? TGAutoDownloadPreferences - - let preferencesProvider: PreferencesProvider - let defaultsPath = documentsPath + "/standard.defaults" - - let standardPreferences = PreferencesProvider.standard(UserDefaults.standard) - if let data = try? Data(contentsOf: URL(fileURLWithPath: defaultsPath)), let dict = NSKeyedUnarchiver.unarchiveObject(with: data) as? [String: Any] { - preferencesProvider = .dict(dict) - } else { - preferencesProvider = standardPreferences - } - - var showCallsTab: Bool? - if let data = try? Data(contentsOf: URL(fileURLWithPath: documentsPath + "/enablecalls.tab")), !data.isEmpty { - showCallsTab = data.withUnsafeBytes { (bytes: UnsafePointer) -> Bool in - return bytes.pointee != 0 - } - } - - let parsedAutoplayGifs: Bool? = preferencesProvider["autoPlayAnimations"] as? Bool - let soundEnabled: Bool? = preferencesProvider["soundEnabled"] as? Bool - let vibrationEnabled: Bool? = preferencesProvider["vibrationEnabled"] as? Bool - let bannerEnabled: Bool? = preferencesProvider["bannerEnabled"] as? Bool - let callsDataUsageMode: Int? = preferencesProvider["callsDataUsageMode"] as? Int - let callsDisableCallKit: Bool? = preferencesProvider["callsDisableCallKit"] as? Bool - let callsUseProxy: Bool? = preferencesProvider["callsUseProxy"] as? Bool - let contactsInhibitSync: Bool? = preferencesProvider["contactsInhibitSync"] as? Bool - let stickersSuggestMode: Int? = preferencesProvider["stickersSuggestMode"] as? Int - - let allowSecretWebpages: Bool? = preferencesProvider["allowSecretWebpages"] as? Bool - let allowSecretWebpagesInitialized: Bool? = preferencesProvider["allowSecretWebpagesInitialized"] as? Bool - let secretInlineBotsInitialized: Bool? = preferencesProvider["secretInlineBotsInitialized"] as? Bool - - let musicPlayerOrderType: Int? = standardPreferences["musicPlayerOrderType_v1"] as? Int - let musicPlayerRepeatType: Int? = standardPreferences["musicPlayerRepeatType_v1"] as? Int - - let instantPageFontSize: Float? = standardPreferences["instantPage_fontMultiplier_v0"] as? Float - let instantPageFontSerif: Int? = standardPreferences["instantPage_fontSerif_v0"] as? Int - let instantPageTheme: Int? = standardPreferences["instantPage_theme_v0"] as? Int - let instantPageAutoNightMode: Int? = standardPreferences["instantPage_autoNightTheme_v0"] as? Int - - let proxyList = NSKeyedUnarchiver.unarchiveObject(withFile: documentsPath + "/proxies.data") as? [TGProxyItem] - var selectedProxy: (ProxyServerSettings, Bool)? - if let data = loadLegacyCustomProperyData(database: database, key: "socksProxyData"), let dict = NSKeyedUnarchiver.unarchiveObject(with: data) as? [String: Any], let host = dict["ip"] as? String, let port = dict["port"] as? Int { - let inactive = (dict["inactive"] as? Bool) ?? true - var connection: ProxyServerConnection? - if let secretString = dict["secret"] as? String { - let secret = MTProxySecret.parse(secretString) - if let secret = secret { - connection = .mtp(secret: secret.serialize()) - } - } else { - connection = .socks5(username: (dict["username"] as? String) ?? "", password: (dict["password"] as? String) ?? "") - } - if let connection = connection { - selectedProxy = (ProxyServerSettings(host: host, port: convertLegacyProxyPort(port), connection: connection), !inactive) - } - } - - var passcodeChallenge: PostboxAccessChallengeData? - if let data = try? Data(contentsOf: URL(fileURLWithPath: documentsPath + "/x.y")) { - let reader = LegacyBufferReader(LegacyBuffer(data: data)) - if let mode = reader.readBytesAsInt32(1), let length = reader.readInt32(), let passwordData = reader.readBuffer(Int(length))?.makeData(), let passwordText = String(data: passwordData, encoding: .utf8) { - var lockTimeout: Int32? - if let value = UserDefaults.standard.object(forKey: "Passcode_lockTimeout") as? Int { - if value == 0 { - lockTimeout = nil - } else { - lockTimeout = max(60, Int32(clamping: value)) - } - } else { - lockTimeout = 1 * 60 * 60 - } - - if mode == 3 { - passcodeChallenge = .numericalPassword(value: passwordText) - } else if mode == 4 { - passcodeChallenge = PostboxAccessChallengeData.plaintextPassword(value: passwordText) - } - } - } - - var passcodeEnableBiometrics: Bool = true - if let value = UserDefaults.standard.object(forKey: "Passcode_useTouchId") as? Bool { - passcodeEnableBiometrics = value - } - - var localization: TGLocalization? - if let nativeDocumentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first { - localization = NSKeyedUnarchiver.unarchiveObject(withFile: nativeDocumentsPath + "/localization") as? TGLocalization - } - - return accountManager.transaction { transaction -> Signal in - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.presentationThemeSettings, { current in - var settings = (current as? PresentationThemeSettings) ?? PresentationThemeSettings.defaultSettings - if let presentationState = presentationState { - switch presentationState.pallete { - case 1: - settings.theme = .builtin(.day) - - if presentationState.userInfo != 0 { - //themeSpecificAccentColors: current.themeSpecificAccentColors - //settings.themeAccentColor = presentationState.userInfo - } - settings.themeSpecificChatWallpapers[settings.theme.index] = .color(0xffffff) - case 2: - settings.theme = .builtin(.night) - settings.themeSpecificChatWallpapers[settings.theme.index] = .color(0x000000) - case 3: - settings.theme = .builtin(.nightAccent) - settings.themeSpecificChatWallpapers[settings.theme.index] = .color(0x18222d) - default: - settings.theme = .builtin(.dayClassic) - settings.themeSpecificChatWallpapers[settings.theme.index] = .builtin(WallpaperSettings()) - } - let fontSizeMap: [Int32: PresentationFontSize] = [ - 14: .extraSmall, - 15: .small, - 16: .medium, - 17: .regular, - 19: .large, - 23: .extraLarge, - 26: .extraLargeX2 - ] - settings.fontSize = fontSizeMap[presentationState.fontSize] ?? .regular - - if presentationState.userInfo != 0 { - //themeSpecificAccentColors: current.themeSpecificAccentColors - //settings.themeAccentColor = presentationState.userInfo - } - } - - if let autoNightPreferences = autoNightPreferences { - let nightTheme: PresentationBuiltinThemeReference - switch autoNightPreferences.preferredPalette { - case 1: - nightTheme = .night - default: - nightTheme = .nightAccent - } - switch autoNightPreferences.mode { - case TGPresentationAutoNightModeSunsetSunrise: - settings.automaticThemeSwitchSetting = AutomaticThemeSwitchSetting(trigger: .timeBased(setting: .automatic(latitude: Double(autoNightPreferences.latitude), longitude: Double(autoNightPreferences.longitude), localizedName: autoNightPreferences.cachedLocationName)), theme: .builtin(nightTheme)) - case TGPresentationAutoNightModeScheduled: - settings.automaticThemeSwitchSetting = AutomaticThemeSwitchSetting(trigger: .timeBased(setting: .manual(fromSeconds: autoNightPreferences.scheduleStart, toSeconds: autoNightPreferences.scheduleEnd)), theme: .builtin(nightTheme)) - case TGPresentationAutoNightModeBrightness: - settings.automaticThemeSwitchSetting = AutomaticThemeSwitchSetting(trigger: .brightness(threshold: Double(autoNightPreferences.brightnessThreshold)), theme: .builtin(nightTheme)) - default: - break - } - } - - return settings - }) - - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings, { current in - var settings: MediaAutoDownloadSettings = current as? MediaAutoDownloadSettings ?? .defaultSettings - - if let preferences = autoDownloadPreferences, !preferences.isDefaultPreferences() { - settings.cellular.enabled = !preferences.disabled - settings.wifi.enabled = !preferences.disabled - } - - if let parsedAutoplayGifs = parsedAutoplayGifs { - settings.autoplayGifs = parsedAutoplayGifs - } - - return settings - }) - - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.inAppNotificationSettings, { current in - var settings: InAppNotificationSettings = current as? InAppNotificationSettings ?? .defaultSettings - if let soundEnabled = soundEnabled { - settings.playSounds = soundEnabled - } - if let vibrationEnabled = vibrationEnabled { - settings.vibrate = vibrationEnabled - } - if let bannerEnabled = bannerEnabled { - settings.displayPreviews = bannerEnabled - } - return settings - }) - - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.voiceCallSettings, { current in - var settings: VoiceCallSettings = current as? VoiceCallSettings ?? .defaultSettings - if let callsDataUsageMode = callsDataUsageMode { - switch callsDataUsageMode { - case 1: - settings.dataSaving = .cellular - case 2: - settings.dataSaving = .always - default: - settings.dataSaving = .never - } - } - if let callsDisableCallKit = callsDisableCallKit, callsDisableCallKit { - settings.enableSystemIntegration = false - } - return settings - }) - - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.callListSettings, { current in - var settings: CallListSettings = current as? CallListSettings ?? .defaultSettings - if let showCallsTab = showCallsTab { - settings.showTab = showCallsTab - } - return settings - }) - - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.presentationPasscodeSettings, { current in - var settings: PresentationPasscodeSettings = current as? PresentationPasscodeSettings ?? .defaultSettings - if let passcodeChallenge = passcodeChallenge { - transaction.setAccessChallengeData(passcodeChallenge) - settings.enableBiometrics = passcodeEnableBiometrics - } - return settings - }) - - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.stickerSettings, { current in - var settings: StickerSettings = current as? StickerSettings ?? .defaultSettings - if let stickersSuggestMode = stickersSuggestMode { - switch stickersSuggestMode { - case 1: - settings.emojiStickerSuggestionMode = .installed - case 2: - settings.emojiStickerSuggestionMode = .none - default: - settings.emojiStickerSuggestionMode = .all - } - } - return settings - }) - - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.musicPlaybackSettings, { current in - var settings: MusicPlaybackSettings = current as? MusicPlaybackSettings ?? .defaultSettings - if let musicPlayerOrderType = musicPlayerOrderType { - switch musicPlayerOrderType { - case 1: - settings.order = .reversed - case 2: - settings.order = .random - default: - settings.order = .regular - } - } - if let musicPlayerRepeatType = musicPlayerRepeatType { - switch musicPlayerRepeatType { - case 1: - settings.looping = .all - case 2: - settings.looping = .item - default: - settings.looping = .none - } - } - return settings - }) - - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.instantPagePresentationSettings, { current in - let settings: InstantPagePresentationSettings = current as? InstantPagePresentationSettings ?? .defaultSettings - if let instantPageFontSize = instantPageFontSize { - switch instantPageFontSize { - case 0.85: - settings.fontSize = .small - case 1.15: - settings.fontSize = .large - case 1.30: - settings.fontSize = .xlarge - case 1.50: - settings.fontSize = .xxlarge - default: - settings.fontSize = .standard - } - } - if let instantPageFontSerif = instantPageFontSerif { - settings.forceSerif = instantPageFontSerif == 1 - } - if let instantPageTheme = instantPageTheme { - switch instantPageTheme { - case 1: - settings.themeType = .sepia - case 2: - settings.themeType = .gray - case 3: - settings.themeType = .dark - default: - settings.themeType = .light - } - } - if let instantPageAutoNightMode = instantPageAutoNightMode { - settings.autoNightMode = instantPageAutoNightMode == 1 - } - return settings - }) - - if let localization = localization { - transaction.updateSharedData(SharedDataKeys.localizationSettings, { _ in - var entries: [LocalizationEntry] = [] - for (key, value) in localization.dict() { - entries.append(LocalizationEntry.string(key: key, value: value)) - } - return LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: localization.code, localizedName: "", localization: Localization(version: 0, entries: entries), customPluralizationCode: nil), secondaryComponent: nil) - }) - } - - transaction.updateSharedData(SharedDataKeys.proxySettings, { current in - var settings: ProxySettings = current as? ProxySettings ?? .defaultSettings - if let callsUseProxy = callsUseProxy { - settings.useForCalls = callsUseProxy - } - - if let proxyList = proxyList { - for item in proxyList { - let connection: ProxyServerConnection? - if item.isMTProxy, let secret = item.secret { - let parsedSecret = MTProxySecret.parse(secret) - if let parsedSecret = parsedSecret { - connection = .mtp(secret: parsedSecret.serialize()) - } else { - connection = nil - } - } else if !item.isMTProxy { - connection = .socks5(username: item.username ?? "", password: item.password ?? "") - } else { - connection = nil - } - if let connection = connection { - settings.servers.append(ProxyServerSettings(host: item.server, port: convertLegacyProxyPort(Int(item.port)), connection: connection)) - } - } - } - - if let (server, active) = selectedProxy { - if !settings.servers.contains(server) { - settings.servers.insert(server, at: 0) - } - settings.activeServer = server - settings.enabled = active - } - - return settings - }) - - if let secretInlineBotsInitialized = secretInlineBotsInitialized, secretInlineBotsInitialized { - ApplicationSpecificNotice.setSecretChatInlineBotUsage(transaction: transaction) - } - - if let allowSecretWebpagesInitialized = allowSecretWebpagesInitialized, allowSecretWebpagesInitialized, let allowSecretWebpages = allowSecretWebpages { - ApplicationSpecificNotice.setSecretChatLinkPreviews(transaction: transaction, value: allowSecretWebpages) - } - - return account.postbox.transaction { transaction -> Void in - transaction.updatePreferencesEntry(key: PreferencesKeys.contactsSettings, { current in - var settings = current as? ContactsSettings ?? ContactsSettings.defaultSettings - if let contactsInhibitSync = contactsInhibitSync, contactsInhibitSync { - settings.synchronizeContacts = false - } - return settings - }) - } - } - |> switchToLatest - |> ignoreValues - } -} diff --git a/submodules/LegacyDataImport/Sources/LegacyResourceImport.swift b/submodules/LegacyDataImport/Sources/LegacyResourceImport.swift deleted file mode 100644 index 4fc129c16f..0000000000 --- a/submodules/LegacyDataImport/Sources/LegacyResourceImport.swift +++ /dev/null @@ -1,137 +0,0 @@ -import Foundation -import TelegramCore -import SyncCore -import SwiftSignalKit -import LegacyComponents - -func resourceFromLegacyImageUrl(_ fileRef: String) -> TelegramMediaResource? { - if fileRef.isEmpty { - return nil - } - let components = fileRef.components(separatedBy: "_") - if components.count != 4 { - return nil - } - - guard let datacenterId = Int32(components[0]) else { - return nil - } - guard let volumeId = Int64(components[1]) else { - return nil - } - guard let localId = Int32(components[2]) else { - return nil - } - guard let secret = Int64(components[3]) else { - return nil - } - - return CloudFileMediaResource(datacenterId: Int(datacenterId), volumeId: volumeId, localId: localId, secret: secret, size: nil, fileReference: nil) -} - -func pathFromLegacyImageUrl(basePath: String, url: String) -> String { - let cache = TGCache(cachesPath: basePath + "/Caches")! - return cache.path(forCachedData: url) -} - -func pathFromLegacyVideoUrl(basePath: String, url: String) -> (id: Int64, accessHash: Int64, datacenterId: Int32, path: String)? { - if !url.hasPrefix("video:") { - return nil - } - //[videoInfo addVideoWithQuality:1 url:[[NSString alloc] initWithFormat:@"video:%lld:%lld:%d:%d", videoMedia.videoId, videoMedia.accessHash, concreteResult.document.datacenterId, concreteResult.document.size] size:concreteResult.document.size]; - let components = url.components(separatedBy: ":") - if components.count != 5 { - return nil - } - guard let videoId = Int64(components[1]) else { - return nil - } - guard let accessHash = Int64(components[2]) else { - return nil - } - guard let datacenterId = Int32(components[3]) else { - return nil - } - let documentsPath = basePath + "/Documents" - let videoPath = documentsPath + "/video/remote\(String(videoId, radix: 16)).mov" - return (videoId, accessHash, datacenterId, videoPath) -} - -func pathFromLegacyLocalVideoUrl(basePath: String, url: String) -> String? { - let documentsPath = basePath + "/Documents" - if !url.hasPrefix("local-video:") { - return nil - } - let videoPath = documentsPath + "/video/" + String(url[url.index(url.startIndex, offsetBy: "local-video:".count)...]) - return videoPath -} - -func pathFromLegacyFile(basePath: String, fileId: Int64, isLocal: Bool, fileName: String) -> String { - let documentsPath = basePath + "/Documents" - let filePath = documentsPath + "/files/" + (isLocal ? "local" : "") + "\(String(fileId, radix: 16))/\(fileName)" - return filePath -} - -enum EncryptedFileType { - case image - case video - case document(fileName: String) - case audio -} - -func pathAndResourceFromEncryptedFileUrl(basePath: String, url: String, type: EncryptedFileType) -> (String, TelegramMediaResource)? { - let cache = TGCache(cachesPath: basePath + "/Caches")! - - if url.hasPrefix("encryptedThumbnail:") { - let path = cache.path(forCachedData: url)! - return (path, LocalFileMediaResource(fileId: arc4random64())) - } - - if !url.hasPrefix("mt-encrypted-file://?") { - return nil - } - guard let dict = TGStringUtils.argumentDictionary(inUrlString: String(url[url.index(url.startIndex, offsetBy: "mt-encrypted-file://?".count)...])) else { - return nil - } - guard let idString = dict["id"] as? String, let id = Int64(idString) else { - return nil - } - guard let datacenterIdString = dict["dc"] as? String, let datacenterId = Int32(datacenterIdString) else { - return nil - } - guard let accessHashString = dict["accessHash"] as? String, let accessHash = Int64(accessHashString) else { - return nil - } - guard let sizeString = dict["size"] as? String, let size = Int32(sizeString) else { - return nil - } - guard let decryptedSizeString = dict["decryptedSize"] as? String, let decryptedSize = Int32(decryptedSizeString) else { - return nil - } - guard let keyFingerprintString = dict["fingerprint"] as? String, let _ = Int32(keyFingerprintString) else { - return nil - } - guard let keyString = dict["key"] as? String else { - return nil - } - let keyData = dataWithHexString(keyString) - guard keyData.count == 64 else { - return nil - } - - let resource = SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: decryptedSize, datacenterId: Int(datacenterId), key: SecretFileEncryptionKey(aesKey: keyData.subdata(in: 0 ..< 32), aesIv: keyData.subdata(in: 32 ..< 64))) - - let filePath: String - switch type { - case .video: - filePath = basePath + "Documents/video/remote\(String(id, radix: 16)).mov" - case .image: - filePath = cache.path(forCachedData: url) - case let .document(fileName): - filePath = basePath + "Documents/files/\(String(id, radix: 16))/\(TGDocumentMediaAttachment.safeFileName(forFileName: fileName)!)" - case .audio: - filePath = basePath + "Documents/audio/\(String(id, radix: 16))" - } - - return (filePath, resource) -} diff --git a/submodules/LegacyDataImport/Sources/LegacyUserDataImport.swift b/submodules/LegacyDataImport/Sources/LegacyUserDataImport.swift deleted file mode 100644 index 79c198549d..0000000000 --- a/submodules/LegacyDataImport/Sources/LegacyUserDataImport.swift +++ /dev/null @@ -1,47 +0,0 @@ -import Foundation -import UIKit -import TelegramCore -import SyncCore -import SwiftSignalKit - -func loadLegacyUser(database: SqliteInterface, id: Int32) -> (TelegramUser, TelegramUserPresence)? { - var result: (TelegramUser, TelegramUserPresence)? - database.select("SELECT uid, first_name, last_name, phone_number, access_hash, photo_small, photo_big, last_seen, username FROM users_v29 WHERE uid=\(id)", { cursor in - let accessHash = cursor.getInt64(at: 4) - let firstName = cursor.getString(at: 1) - let lastName = cursor.getString(at: 2) - let username = cursor.getString(at: 8) - let phone = cursor.getString(at: 3) - - let photoSmall = cursor.getString(at: 5) - let photoBig = cursor.getString(at: 6) - var photo: [TelegramMediaImageRepresentation] = [] - if let resource = resourceFromLegacyImageUrl(photoSmall) { - photo.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 80, height: 80), resource: resource, progressiveSizes: [])) - } - if let resource = resourceFromLegacyImageUrl(photoBig) { - photo.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 600, height: 600), resource: resource, progressiveSizes: [])) - } - - let user = TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: cursor.getInt32(at: 0)), accessHash: accessHash == 0 ? nil : .personal(accessHash), firstName: firstName.isEmpty ? nil : firstName, lastName: lastName.isEmpty ? nil : lastName, username: username.isEmpty ? nil : username, phone: phone.isEmpty ? nil : phone, photo: photo, botInfo: nil, restrictionInfo: nil, flags: []) - - let status: UserPresenceStatus - let lastSeen = cursor.getInt32(at: 7) - if lastSeen == -2 { - status = .recently - } else if lastSeen == -3 { - status = .lastWeek - } else if lastSeen == -4 { - status = .lastMonth - } else if lastSeen <= 0 { - status = .none - } else { - status = .present(until: lastSeen) - } - - let presence = TelegramUserPresence(status: status, lastActivity: 0) - result = (user, presence) - return false - }) - return result -} diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift index a4ebc8517e..ed09858c52 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift @@ -361,48 +361,6 @@ public func legacyEnqueueGifMessage(account: Account, data: Data, correlationId: } |> runOn(Queue.concurrentDefaultQueue()) } -public func legacyEnqueueVideoMessage(account: Account, data: Data, correlationId: Int64? = nil) -> Signal { - return Signal { subscriber in - if let previewImage = UIImage(data: data) { - let dimensions = previewImage.size - var previewRepresentations: [TelegramMediaImageRepresentation] = [] - - let thumbnailSize = dimensions.aspectFitted(CGSize(width: 320.0, height: 320.0)) - let thumbnailImage = TGScaleImageToPixelSize(previewImage, thumbnailSize)! - if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { - let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)) - } - - var randomId: Int64 = 0 - arc4random_buf(&randomId, 8) - let tempFilePath = NSTemporaryDirectory() + "\(randomId).mp4" - - let _ = try? FileManager.default.removeItem(atPath: tempFilePath) - let _ = try? data.write(to: URL(fileURLWithPath: tempFilePath), options: [.atomic]) - - let resource = LocalFileGifMediaResource(randomId: Int64.random(in: Int64.min ... Int64.max), path: tempFilePath) - let fileName: String = "video.mp4" - - let finalDimensions = TGMediaVideoConverter.dimensions(for: dimensions, adjustments: nil, preset: TGMediaVideoConversionPresetAnimation) - - var fileAttributes: [TelegramMediaFileAttribute] = [] - fileAttributes.append(.Video(duration: 0.0, size: PixelDimensions(finalDimensions), flags: [.supportsStreaming], preloadSize: nil, coverTime: nil, videoCodec: nil)) - fileAttributes.append(.FileName(fileName: fileName)) - fileAttributes.append(.Animated) - - let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: resource, previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: fileAttributes, alternativeRepresentations: []) - subscriber.putNext(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), threadId: nil, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])) - subscriber.putCompletion() - } else { - subscriber.putError(Void()) - } - - return EmptyDisposable - } |> runOn(Queue.concurrentDefaultQueue()) -} - public struct LegacyAssetPickerEnqueueMessage { public var message: EnqueueMessage public var uniqueId: String? diff --git a/submodules/ListMessageItem/Sources/ListMessageItem.swift b/submodules/ListMessageItem/Sources/ListMessageItem.swift index 3a764bd287..e02baf6996 100644 --- a/submodules/ListMessageItem/Sources/ListMessageItem.swift +++ b/submodules/ListMessageItem/Sources/ListMessageItem.swift @@ -4,34 +4,33 @@ import AsyncDisplayKit import Display import TelegramCore import SwiftSignalKit -import Postbox import TelegramPresentationData import AccountContext import TelegramUIPreferences import ItemListUI public final class ListMessageItemInteraction { - public let openMessage: (Message, ChatControllerInteractionOpenMessageMode) -> Bool - public let openMessageContextMenu: (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?) -> Void - public let toggleMessagesSelection: ([MessageId], Bool) -> Void - public let toggleMediaPlayback: ((Message) -> Void)? - let openUrl: (String, Bool, Bool?, Message?) -> Void - let openInstantPage: (Message, ChatMessageItemAssociatedData?) -> Void - let longTap: (ChatControllerInteractionLongTapAction, Message?) -> Void - let getHiddenMedia: () -> [MessageId: [Media]] + public let openMessage: (EngineRawMessage, ChatControllerInteractionOpenMessageMode) -> Bool + public let openMessageContextMenu: (EngineRawMessage, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?) -> Void + public let toggleMessagesSelection: ([EngineMessage.Id], Bool) -> Void + public let toggleMediaPlayback: ((EngineRawMessage) -> Void)? + let openUrl: (String, Bool, Bool?, EngineRawMessage?) -> Void + let openInstantPage: (EngineRawMessage, ChatMessageItemAssociatedData?) -> Void + let longTap: (ChatControllerInteractionLongTapAction, EngineRawMessage?) -> Void + let getHiddenMedia: () -> [EngineMessage.Id: [EngineRawMedia]] public var searchTextHighightState: String? public var preferredStoryHighQuality: Bool = false public init( - openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool, - openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?) -> Void, - toggleMediaPlayback: ((Message) -> Void)?, - toggleMessagesSelection: @escaping ([MessageId], Bool) -> Void, - openUrl: @escaping (String, Bool, Bool?, Message?) -> Void, - openInstantPage: @escaping (Message, ChatMessageItemAssociatedData?) -> Void, - longTap: @escaping (ChatControllerInteractionLongTapAction, Message?) -> Void, - getHiddenMedia: @escaping () -> [MessageId: [Media]] + openMessage: @escaping (EngineRawMessage, ChatControllerInteractionOpenMessageMode) -> Bool, + openMessageContextMenu: @escaping (EngineRawMessage, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?) -> Void, + toggleMediaPlayback: ((EngineRawMessage) -> Void)?, + toggleMessagesSelection: @escaping ([EngineMessage.Id], Bool) -> Void, + openUrl: @escaping (String, Bool, Bool?, EngineRawMessage?) -> Void, + openInstantPage: @escaping (EngineRawMessage, ChatMessageItemAssociatedData?) -> Void, + longTap: @escaping (ChatControllerInteractionLongTapAction, EngineRawMessage?) -> Void, + getHiddenMedia: @escaping () -> [EngineMessage.Id: [EngineRawMedia]] ) { self.openMessage = openMessage self.openMessageContextMenu = openMessageContextMenu @@ -51,7 +50,7 @@ public final class ListMessageItemInteraction { openUrl: { _, _, _, _ in }, openInstantPage: { _, _ in }, longTap: { _, _ in - }, getHiddenMedia: { () -> [MessageId : [Media]] in + }, getHiddenMedia: { () -> [EngineMessage.Id : [EngineRawMedia]] in return [:] }) } @@ -67,7 +66,7 @@ public final class ListMessageItem: ListViewItem, ItemListItem { let context: AccountContext let chatLocation: ChatLocation let interaction: ListMessageItemInteraction - let message: Message? + let message: EngineRawMessage? let translateToLanguage: String? public let selection: ChatHistoryMessageSelection public let selectionSide: ListMessageItemSelectionSide @@ -94,7 +93,7 @@ public final class ListMessageItem: ListViewItem, ItemListItem { context: AccountContext, chatLocation: ChatLocation, interaction: ListMessageItemInteraction, - message: Message?, + message: EngineRawMessage?, translateToLanguage: String? = nil, selection: ChatHistoryMessageSelection, selectionSide: ListMessageItemSelectionSide = .right, diff --git a/submodules/ListMessageItem/Sources/ListMessageNode.swift b/submodules/ListMessageItem/Sources/ListMessageNode.swift index 19d1b2ee17..625908c2f7 100644 --- a/submodules/ListMessageItem/Sources/ListMessageNode.swift +++ b/submodules/ListMessageItem/Sources/ListMessageNode.swift @@ -2,7 +2,7 @@ import Foundation import UIKit import Display import AsyncDisplayKit -import Postbox +import TelegramCore import AccountContext public class ListMessageNode: ListViewItemNode { @@ -28,7 +28,7 @@ public class ListMessageNode: ListViewItemNode { } } - public func transitionNode(id: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + public func transitionNode(id: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { return nil } diff --git a/submodules/LocalMediaResources/BUILD b/submodules/LocalMediaResources/BUILD index b0f3f832fe..cc0d5b719a 100644 --- a/submodules/LocalMediaResources/BUILD +++ b/submodules/LocalMediaResources/BUILD @@ -11,7 +11,6 @@ swift_library( ], deps = [ "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", - "//submodules/Postbox:Postbox", "//submodules/TelegramCore:TelegramCore", "//submodules/ImageCompression:ImageCompression", "//submodules/PersistentStringHash:PersistentStringHash", diff --git a/submodules/LocalMediaResources/Sources/MediaResources.swift b/submodules/LocalMediaResources/Sources/MediaResources.swift index 6e4d1490bf..9cf14404ee 100644 --- a/submodules/LocalMediaResources/Sources/MediaResources.swift +++ b/submodules/LocalMediaResources/Sources/MediaResources.swift @@ -1,27 +1,26 @@ import Foundation import UIKit -import Postbox import TelegramCore import PersistentStringHash -public final class VideoMediaResourceAdjustments: PostboxCoding, Equatable { - public let data: MemoryBuffer - public let digest: MemoryBuffer +public final class VideoMediaResourceAdjustments: EnginePostboxCoding, Equatable { + public let data: EngineMemoryBuffer + public let digest: EngineMemoryBuffer public let isStory: Bool - public init(data: MemoryBuffer, digest: MemoryBuffer, isStory: Bool = false) { + public init(data: EngineMemoryBuffer, digest: EngineMemoryBuffer, isStory: Bool = false) { self.data = data self.digest = digest self.isStory = isStory } - public init(decoder: PostboxDecoder) { + public init(decoder: EnginePostboxDecoder) { self.data = decoder.decodeBytesForKey("d")! self.digest = decoder.decodeBytesForKey("h")! self.isStory = decoder.decodeBoolForKey("s", orElse: false) } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeBytes(self.data, forKey: "d") encoder.encodeBytes(self.digest, forKey: "h") encoder.encodeBool(self.isStory, forKey: "s") @@ -34,7 +33,7 @@ public final class VideoMediaResourceAdjustments: PostboxCoding, Equatable { public struct VideoLibraryMediaResourceId { public let localIdentifier: String - public let adjustmentsDigest: MemoryBuffer? + public let adjustmentsDigest: EngineMemoryBuffer? public var uniqueId: String { if let adjustmentsDigest = self.adjustmentsDigest { @@ -49,11 +48,11 @@ public struct VideoLibraryMediaResourceId { } } -public enum VideoLibraryMediaResourceConversion: PostboxCoding, Equatable { +public enum VideoLibraryMediaResourceConversion: EnginePostboxCoding, Equatable { case passthrough case compress(VideoMediaResourceAdjustments?) - public init(decoder: PostboxDecoder) { + public init(decoder: EnginePostboxDecoder) { switch decoder.decodeInt32ForKey("v", orElse: 0) { case 0: self = .passthrough @@ -64,7 +63,7 @@ public enum VideoLibraryMediaResourceConversion: PostboxCoding, Equatable { } } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { switch self { case .passthrough: encoder.encodeInt32(0, forKey: "v") @@ -113,28 +112,28 @@ public final class VideoLibraryMediaResource: TelegramMediaResource { self.conversion = conversion } - public required init(decoder: PostboxDecoder) { + public required init(decoder: EnginePostboxDecoder) { self.localIdentifier = decoder.decodeStringForKey("i", orElse: "") self.conversion = (decoder.decodeObjectForKey("conv", decoder: { VideoLibraryMediaResourceConversion(decoder: $0) }) as? VideoLibraryMediaResourceConversion) ?? .compress(nil) } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeString(self.localIdentifier, forKey: "i") encoder.encodeObject(self.conversion, forKey: "conv") } - public var id: MediaResourceId { - var adjustmentsDigest: MemoryBuffer? + public var id: EngineRawMediaResourceId { + var adjustmentsDigest: EngineMemoryBuffer? switch self.conversion { case .passthrough: break case let .compress(adjustments): adjustmentsDigest = adjustments?.digest } - return MediaResourceId(VideoLibraryMediaResourceId(localIdentifier: self.localIdentifier, adjustmentsDigest: adjustmentsDigest).uniqueId) + return EngineRawMediaResourceId(VideoLibraryMediaResourceId(localIdentifier: self.localIdentifier, adjustmentsDigest: adjustmentsDigest).uniqueId) } - public func isEqual(to: MediaResource) -> Bool { + public func isEqual(to: EngineRawMediaResource) -> Bool { if let to = to as? VideoLibraryMediaResource { return self.localIdentifier == to.localIdentifier && self.conversion == to.conversion } else { @@ -180,7 +179,7 @@ public final class LocalFileVideoMediaResource: TelegramMediaResource { self.adjustments = adjustments } - public required init(decoder: PostboxDecoder) { + public required init(decoder: EnginePostboxDecoder) { self.randomId = decoder.decodeInt64ForKey("i", orElse: 0) let paths = decoder.decodeStringArrayForKey("ps") if !paths.isEmpty { @@ -191,7 +190,7 @@ public final class LocalFileVideoMediaResource: TelegramMediaResource { self.adjustments = decoder.decodeObjectForKey("a", decoder: { VideoMediaResourceAdjustments(decoder: $0) }) as? VideoMediaResourceAdjustments } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeInt64(self.randomId, forKey: "i") encoder.encodeStringArray(self.paths, forKey: "ps") if let adjustments = self.adjustments { @@ -201,11 +200,11 @@ public final class LocalFileVideoMediaResource: TelegramMediaResource { } } - public var id: MediaResourceId { - return MediaResourceId(LocalFileVideoMediaResourceId(randomId: self.randomId).uniqueId) + public var id: EngineRawMediaResourceId { + return EngineRawMediaResourceId(LocalFileVideoMediaResourceId(randomId: self.randomId).uniqueId) } - public func isEqual(to: MediaResource) -> Bool { + public func isEqual(to: EngineRawMediaResource) -> Bool { if let to = to as? LocalFileVideoMediaResource { return self.randomId == to.randomId && self.paths == to.paths && self.adjustments == to.adjustments } else { @@ -245,7 +244,7 @@ public final class LocalFileAudioMediaResource: TelegramMediaResource { self.trimRange = trimRange } - public required init(decoder: PostboxDecoder) { + public required init(decoder: EnginePostboxDecoder) { self.randomId = decoder.decodeInt64ForKey("i", orElse: 0) self.path = decoder.decodeStringForKey("p", orElse: "") @@ -256,7 +255,7 @@ public final class LocalFileAudioMediaResource: TelegramMediaResource { } } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeInt64(self.randomId, forKey: "i") encoder.encodeString(self.path, forKey: "p") @@ -269,11 +268,11 @@ public final class LocalFileAudioMediaResource: TelegramMediaResource { } } - public var id: MediaResourceId { - return MediaResourceId(LocalFileAudioMediaResourceId(randomId: self.randomId).uniqueId) + public var id: EngineRawMediaResourceId { + return EngineRawMediaResourceId(LocalFileAudioMediaResourceId(randomId: self.randomId).uniqueId) } - public func isEqual(to: MediaResource) -> Bool { + public func isEqual(to: EngineRawMediaResource) -> Bool { if let to = to as? LocalFileAudioMediaResource { return self.randomId == to.randomId && self.path == to.path && self.trimRange == to.trimRange } else { @@ -327,7 +326,7 @@ public class PhotoLibraryMediaResource: TelegramMediaResource { self.forceHd = forceHd } - public required init(decoder: PostboxDecoder) { + public required init(decoder: EnginePostboxDecoder) { self.localIdentifier = decoder.decodeStringForKey("i", orElse: "") self.uniqueId = decoder.decodeInt64ForKey("uid", orElse: 0) self.width = decoder.decodeOptionalInt32ForKey("w") @@ -337,7 +336,7 @@ public class PhotoLibraryMediaResource: TelegramMediaResource { self.forceHd = decoder.decodeBoolForKey("hd", orElse: false) } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeString(self.localIdentifier, forKey: "i") encoder.encodeInt64(self.uniqueId, forKey: "uid") if let width = self.width { @@ -363,11 +362,11 @@ public class PhotoLibraryMediaResource: TelegramMediaResource { encoder.encodeBool(self.forceHd, forKey: "hd") } - public var id: MediaResourceId { - return MediaResourceId(PhotoLibraryMediaResourceId(localIdentifier: self.localIdentifier, resourceId: self.uniqueId).uniqueId) + public var id: EngineRawMediaResourceId { + return EngineRawMediaResourceId(PhotoLibraryMediaResourceId(localIdentifier: self.localIdentifier, resourceId: self.uniqueId).uniqueId) } - public func isEqual(to: MediaResource) -> Bool { + public func isEqual(to: EngineRawMediaResource) -> Bool { if let to = to as? PhotoLibraryMediaResource { if self.localIdentifier != to.localIdentifier { return false @@ -426,21 +425,21 @@ public final class LocalFileGifMediaResource: TelegramMediaResource { self.path = path } - public required init(decoder: PostboxDecoder) { + public required init(decoder: EnginePostboxDecoder) { self.randomId = decoder.decodeInt64ForKey("i", orElse: 0) self.path = decoder.decodeStringForKey("p", orElse: "") } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeInt64(self.randomId, forKey: "i") encoder.encodeString(self.path, forKey: "p") } - public var id: MediaResourceId { - return MediaResourceId(LocalFileGifMediaResourceId(randomId: self.randomId).uniqueId) + public var id: EngineRawMediaResourceId { + return EngineRawMediaResourceId(LocalFileGifMediaResourceId(randomId: self.randomId).uniqueId) } - public func isEqual(to: MediaResource) -> Bool { + public func isEqual(to: EngineRawMediaResource) -> Bool { if let to = to as? LocalFileGifMediaResource { return self.randomId == to.randomId && self.path == to.path } else { @@ -475,21 +474,21 @@ public class BundleResource: TelegramMediaResource { self.path = path } - public required init(decoder: PostboxDecoder) { + public required init(decoder: EnginePostboxDecoder) { self.nameHash = decoder.decodeInt64ForKey("h", orElse: 0) self.path = decoder.decodeStringForKey("p", orElse: "") } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeInt64(self.nameHash, forKey: "h") encoder.encodeString(self.path, forKey: "p") } - public var id: MediaResourceId { - return MediaResourceId(BundleResourceId(nameHash: self.nameHash).uniqueId) + public var id: EngineRawMediaResourceId { + return EngineRawMediaResourceId(BundleResourceId(nameHash: self.nameHash).uniqueId) } - public func isEqual(to: MediaResource) -> Bool { + public func isEqual(to: EngineRawMediaResource) -> Bool { if let to = to as? BundleResource { return self.nameHash == to.nameHash } else { diff --git a/submodules/MediaResources/BUILD b/submodules/MediaResources/BUILD index 16e9f6ac37..5ce6f52464 100644 --- a/submodules/MediaResources/BUILD +++ b/submodules/MediaResources/BUILD @@ -11,7 +11,6 @@ swift_library( ], deps = [ "//submodules/TelegramCore:TelegramCore", - "//submodules/Postbox:Postbox", "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/TelegramUIPreferences:TelegramUIPreferences", ], diff --git a/submodules/MediaResources/Sources/CachedResourceRepresentations.swift b/submodules/MediaResources/Sources/CachedResourceRepresentations.swift index e18def94d7..2483da6dd4 100644 --- a/submodules/MediaResources/Sources/CachedResourceRepresentations.swift +++ b/submodules/MediaResources/Sources/CachedResourceRepresentations.swift @@ -1,11 +1,11 @@ import Foundation import UIKit import SwiftSignalKit -import Postbox +import TelegramCore -public final class CachedStickerAJpegRepresentation: CachedMediaResourceRepresentation { +public final class CachedStickerAJpegRepresentation: EngineRawCachedMediaResourceRepresentation { public let size: CGSize? - public let keepDuration: CachedMediaRepresentationKeepDuration = .general + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public var uniqueId: String { if let size = self.size { @@ -19,7 +19,7 @@ public final class CachedStickerAJpegRepresentation: CachedMediaResourceRepresen self.size = size } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedStickerAJpegRepresentation { return self.size == to.size } else { @@ -33,8 +33,8 @@ public enum CachedScaledImageRepresentationMode: Int32 { case aspectFit = 1 } -public final class CachedScaledImageRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedScaledImageRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public let size: CGSize public let mode: CachedScaledImageRepresentationMode @@ -48,7 +48,7 @@ public final class CachedScaledImageRepresentation: CachedMediaResourceRepresent self.mode = mode } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedScaledImageRepresentation { return self.size == to.size && self.mode == to.mode } else { @@ -57,8 +57,8 @@ public final class CachedScaledImageRepresentation: CachedMediaResourceRepresent } } -public final class CachedVideoFirstFrameRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedVideoFirstFrameRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public var uniqueId: String { return "first-frame" @@ -67,7 +67,7 @@ public final class CachedVideoFirstFrameRepresentation: CachedMediaResourceRepre public init() { } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if to is CachedVideoFirstFrameRepresentation { return true } else { @@ -76,8 +76,8 @@ public final class CachedVideoFirstFrameRepresentation: CachedMediaResourceRepre } } -public final class CachedVideoPrefixFirstFrameRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedVideoPrefixFirstFrameRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public var uniqueId: String { return "prefix-first-frame" @@ -89,7 +89,7 @@ public final class CachedVideoPrefixFirstFrameRepresentation: CachedMediaResourc self.prefixLength = prefixLength } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedVideoPrefixFirstFrameRepresentation { if self.prefixLength != to.prefixLength { return false @@ -101,8 +101,8 @@ public final class CachedVideoPrefixFirstFrameRepresentation: CachedMediaResourc } } -public final class CachedScaledVideoFirstFrameRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedScaledVideoFirstFrameRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public let size: CGSize @@ -114,7 +114,7 @@ public final class CachedScaledVideoFirstFrameRepresentation: CachedMediaResourc self.size = size } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedScaledVideoFirstFrameRepresentation { return self.size == to.size } else { @@ -123,8 +123,8 @@ public final class CachedScaledVideoFirstFrameRepresentation: CachedMediaResourc } } -public final class CachedBlurredWallpaperRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedBlurredWallpaperRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public var uniqueId: String { return "blurred-wallpaper" @@ -133,7 +133,7 @@ public final class CachedBlurredWallpaperRepresentation: CachedMediaResourceRepr public init() { } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if to is CachedBlurredWallpaperRepresentation { return true } else { @@ -142,8 +142,8 @@ public final class CachedBlurredWallpaperRepresentation: CachedMediaResourceRepr } } -public final class CachedAlbumArtworkRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedAlbumArtworkRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public let size: CGSize? @@ -159,7 +159,7 @@ public final class CachedAlbumArtworkRepresentation: CachedMediaResourceRepresen self.size = size } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedAlbumArtworkRepresentation { return self.size == to.size } else { @@ -168,8 +168,8 @@ public final class CachedAlbumArtworkRepresentation: CachedMediaResourceRepresen } } -public final class CachedEmojiThumbnailRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedEmojiThumbnailRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public let outline: Bool @@ -181,7 +181,7 @@ public final class CachedEmojiThumbnailRepresentation: CachedMediaResourceRepres self.outline = outline } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedEmojiThumbnailRepresentation { return self.outline == to.outline } else { @@ -190,8 +190,8 @@ public final class CachedEmojiThumbnailRepresentation: CachedMediaResourceRepres } } -public final class CachedEmojiRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedEmojiRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public let tile: UInt8 public let outline: Bool @@ -205,7 +205,7 @@ public final class CachedEmojiRepresentation: CachedMediaResourceRepresentation self.outline = outline } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if let to = to as? CachedEmojiRepresentation { return self.tile == to.tile && self.outline == to.outline } else { @@ -239,8 +239,8 @@ public enum EmojiFitzModifier: Int32, Equatable { } } -public final class CachedAnimatedStickerFirstFrameRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedAnimatedStickerFirstFrameRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public let width: Int32 public let height: Int32 @@ -261,7 +261,7 @@ public final class CachedAnimatedStickerFirstFrameRepresentation: CachedMediaRes } } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if let other = to as? CachedAnimatedStickerFirstFrameRepresentation { if other.width != self.width { return false @@ -279,8 +279,8 @@ public final class CachedAnimatedStickerFirstFrameRepresentation: CachedMediaRes } } -public final class CachedAnimatedStickerRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .shortLived +public final class CachedAnimatedStickerRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .shortLived public let width: Int32 public let height: Int32 @@ -301,7 +301,7 @@ public final class CachedAnimatedStickerRepresentation: CachedMediaResourceRepre self.fitzModifier = fitzModifier } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if let other = to as? CachedAnimatedStickerRepresentation { if other.width != self.width { return false @@ -319,8 +319,8 @@ public final class CachedAnimatedStickerRepresentation: CachedMediaResourceRepre } } -public final class CachedVideoStickerRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .shortLived +public final class CachedVideoStickerRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .shortLived public let width: Int32 public let height: Int32 @@ -336,7 +336,7 @@ public final class CachedVideoStickerRepresentation: CachedMediaResourceRepresen self.height = height } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if let other = to as? CachedVideoStickerRepresentation { if other.width != self.width { return false @@ -351,8 +351,8 @@ public final class CachedVideoStickerRepresentation: CachedMediaResourceRepresen } } -public final class CachedPreparedPatternWallpaperRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedPreparedPatternWallpaperRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public var uniqueId: String { return "prepared-pattern-wallpaper" @@ -361,7 +361,7 @@ public final class CachedPreparedPatternWallpaperRepresentation: CachedMediaReso public init() { } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if to is CachedPreparedPatternWallpaperRepresentation { return true } else { @@ -371,8 +371,8 @@ public final class CachedPreparedPatternWallpaperRepresentation: CachedMediaReso } -public final class CachedPreparedSvgRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .general +public final class CachedPreparedSvgRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .general public var uniqueId: String { return "prepared-svg" @@ -381,7 +381,7 @@ public final class CachedPreparedSvgRepresentation: CachedMediaResourceRepresent public init() { } - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if to is CachedPreparedSvgRepresentation { return true } else { diff --git a/submodules/PassportUI/Sources/LegacySecureIdAttachmentMenu.swift b/submodules/PassportUI/Sources/LegacySecureIdAttachmentMenu.swift index a3ef9dc4fc..2264149d6d 100644 --- a/submodules/PassportUI/Sources/LegacySecureIdAttachmentMenu.swift +++ b/submodules/PassportUI/Sources/LegacySecureIdAttachmentMenu.swift @@ -76,7 +76,7 @@ func presentLegacySecureIdAttachmentMenu(context: AccountContext, present: @esca |> runOn(.mainQueue()) |> delay(0.1, queue: .mainQueue())).start() - let _ = (processedLegacySecureIdAttachmentItems(postbox: context.account.postbox, signal: signal) + let _ = (processedLegacySecureIdAttachmentItems(signal: signal) |> mapToSignal { resources -> Signal<([TelegramMediaResource], SecureIdRecognizedDocumentData?), NoError> in switch type { case .generic, .idCard: @@ -116,7 +116,7 @@ private enum AttachmentItem { case iCloud(URL) } -private func processedLegacySecureIdAttachmentItems(postbox: Postbox, signal: SSignal) -> Signal<[TelegramMediaResource], NoError> { +private func processedLegacySecureIdAttachmentItems(signal: SSignal) -> Signal<[TelegramMediaResource], NoError> { let nativeSignal = Signal { subscriber in let disposable = signal.start(next: { next in if let dict = next as? [String: Any], let image = dict["image"] as? UIImage { diff --git a/submodules/PhotoResources/Sources/PhotoResources.swift b/submodules/PhotoResources/Sources/PhotoResources.swift index 86a270792e..e4305b2f2c 100644 --- a/submodules/PhotoResources/Sources/PhotoResources.swift +++ b/submodules/PhotoResources/Sources/PhotoResources.swift @@ -844,24 +844,6 @@ private func chatMessageVideoDatas(postbox: Postbox, userLocation: MediaResource return signal } -public func rawMessagePhoto(postbox: Postbox, userLocation: MediaResourceUserLocation, photoReference: ImageMediaReference) -> Signal { - return chatMessagePhotoDatas(postbox: postbox, userLocation: userLocation, photoReference: photoReference, autoFetchFullSize: true) - |> map { value -> UIImage? in - let thumbnailData = value._0 - let fullSizeData = value._1 - let fullSizeComplete = value._3 - if let fullSizeData = fullSizeData { - if fullSizeComplete { - return UIImage(data: fullSizeData)?.precomposed() - } - } - if let thumbnailData = thumbnailData { - return UIImage(data: thumbnailData)?.precomposed() - } - return nil - } -} - public func chatMessagePhoto(postbox: Postbox, userLocation: MediaResourceUserLocation, userContentType customUserContentType: MediaResourceUserContentType? = nil, photoReference: ImageMediaReference, synchronousLoad: Bool = false, highQuality: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { return chatMessagePhotoInternal(photoData: chatMessagePhotoDatas(postbox: postbox, userLocation: userLocation, customUserContentType: customUserContentType, photoReference: photoReference, tryAdditionalRepresentations: true, synchronousLoad: synchronousLoad), synchronousLoad: synchronousLoad) |> map { _, _, generate in @@ -1766,79 +1748,6 @@ public func mediaGridMessagePhoto(account: Account, userLocation: MediaResourceU } } -public func gifPaneVideoThumbnail(account: Account, videoReference: FileMediaReference) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { - if let smallestRepresentation = smallestImageRepresentation(videoReference.media.previewRepresentations) { - let thumbnailResource = smallestRepresentation.resource - - let thumbnail = Signal { subscriber in - let data = account.postbox.mediaBox.resourceData(thumbnailResource).start(next: { data in - subscriber.putNext(data) - }, completed: { - subscriber.putCompletion() - }) - let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .other, reference: videoReference.resourceReference(thumbnailResource)).start() - return ActionDisposable { - data.dispose() - fetched.dispose() - } - } - - return thumbnail - |> map { data in - let thumbnailData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) - return { arguments in - guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { - return nil - } - - let drawingRect = arguments.drawingRect - let fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize) - let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize) - - var thumbnailImage: CGImage? - if let thumbnailData = thumbnailData, let imageSource = CGImageSourceCreateWithData(thumbnailData as CFData, nil), let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) { - thumbnailImage = image - } - - var blurredThumbnailImage: UIImage? - if let thumbnailImage = thumbnailImage { - let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height) - let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0)) - if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) - } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - blurredThumbnailImage = thumbnailContext.generateImage() - } - } - - context.withFlippedContext { c in - c.setBlendMode(.copy) - if arguments.boundingSize != arguments.imageSize { - c.fill(arguments.drawingRect) - } - - c.setBlendMode(.copy) - if let blurredThumbnailImage = blurredThumbnailImage, let cgImage = blurredThumbnailImage.cgImage { - c.interpolationQuality = .low - drawImage(context: c, image: cgImage, orientation: .up, in: fittedRect) - c.setBlendMode(.normal) - } - } - - addCorners(context, arguments: arguments) - - return context - } - } - } else { - return .never() - } -} - public func mediaGridMessageVideo(postbox: Postbox, userLocation: MediaResourceUserLocation, userContentType customUserContentType: MediaResourceUserContentType? = nil, videoReference: FileMediaReference, hlsFiles: [(playlist: TelegramMediaFile, video: TelegramMediaFile)] = [], onlyFullSize: Bool = false, useLargeThumbnail: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false, overlayColor: UIColor? = nil, nilForEmptyResult: Bool = false, useMiniThumbnailIfAvailable: Bool = false, blurred: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { return internalMediaGridMessageVideo(postbox: postbox, userLocation: userLocation, customUserContentType: customUserContentType, videoReference: videoReference, hlsFiles: hlsFiles, onlyFullSize: onlyFullSize, useLargeThumbnail: useLargeThumbnail, synchronousLoad: synchronousLoad, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail, overlayColor: overlayColor, nilForEmptyResult: nilForEmptyResult, useMiniThumbnailIfAvailable: useMiniThumbnailIfAvailable) |> map { @@ -2703,25 +2612,6 @@ public func chatMessageImageFile(account: Account, userLocation: MediaResourceUs } } -public func preloadedBotIcon(account: Account, fileReference: FileMediaReference) -> Signal { - let signal = Signal { subscriber in - let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: MediaResourceUserContentType(file: fileReference.media), reference: fileReference.resourceReference(fileReference.media.resource)).start() - let dataDisposable = account.postbox.mediaBox.resourceData(fileReference.media.resource, option: .incremental(waitUntilFetchStatus: false)).start(next: { data in - if data.complete { - subscriber.putNext(true) - subscriber.putCompletion() - } else { - subscriber.putNext(false) - } - }) - return ActionDisposable { - fetched.dispose() - dataDisposable.dispose() - } - } - return signal -} - public func instantPageImageFile(account: Account, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference, fetched: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { return chatMessageFileDatas(account: account, userLocation: userLocation, fileReference: fileReference, progressive: false, fetched: fetched) |> map { value in diff --git a/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift b/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift index cdafe9a37c..79e6ffaa8a 100644 --- a/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift +++ b/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift @@ -1,8 +1,7 @@ import Foundation import TelegramCore -import Postbox -public extension Message { +public extension EngineRawMessage { func isRestricted(platform: String, contentSettings: ContentSettings) -> Bool { return self.restrictionReason(platform: platform, contentSettings: contentSettings) != nil } diff --git a/submodules/PremiumUI/Sources/PremiumGiftScreen.swift b/submodules/PremiumUI/Sources/PremiumGiftScreen.swift index c11551e0ef..1e58c28be8 100644 --- a/submodules/PremiumUI/Sources/PremiumGiftScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumGiftScreen.swift @@ -142,7 +142,7 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent { jsonString += "]}}" if let data = jsonString.data(using: .utf8), let json = JSON(data: data) { - addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium_gift.promo_screen_show", data: json) + strongSelf.context.engine.accountData.addAppLogEvent(type: "premium_gift.promo_screen_show", data: json) } } @@ -568,7 +568,7 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent { controller?.dismiss(animated: true, completion: nil) } - addAppLogEvent(postbox: accountContext.account.postbox, type: "premium_gift.promo_screen_tap", data: ["item": perk.identifier]) + accountContext.engine.accountData.addAppLogEvent(type: "premium_gift.promo_screen_tap", data: ["item": perk.identifier]) } )) i += 1 @@ -900,7 +900,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent { let (currency, amount) = product.storeProduct.priceCurrencyAndAmount let duration = product.months - addAppLogEvent(postbox: self.context.account.postbox, type: "premium_gift.promo_screen_accept") + self.context.engine.accountData.addAppLogEvent(type: "premium_gift.promo_screen_accept") self.inProgress = true self.updateInProgress(true) @@ -968,7 +968,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent { } if let errorText = errorText { - addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium_gift.promo_screen_fail") + strongSelf.context.engine.accountData.addAppLogEvent(type: "premium_gift.promo_screen_fail") let alertController = textAlertController(context: strongSelf.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]) strongSelf.present(alertController) diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index d4bef601c4..c7c0c12e3e 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -1682,7 +1682,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent { jsonString += "]}}" if let context = screenContext.context, let data = jsonString.data(using: .utf8), let json = JSON(data: data) { - addAppLogEvent(postbox: context.account.postbox, type: "premium.promo_screen_show", data: json) + context.engine.accountData.addAppLogEvent(type: "premium.promo_screen_show", data: json) } } }) @@ -2260,7 +2260,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent { } updateIsFocused(true) - addAppLogEvent(postbox: accountContext.account.postbox, type: "premium.promo_screen_tap", data: ["item": perk.identifier]) + accountContext.engine.accountData.addAppLogEvent(type: "premium.promo_screen_tap", data: ["item": perk.identifier]) }, highlighting: accountContext != nil ? .default : .disabled )))) @@ -3262,7 +3262,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent { } if let context = self.screenContext.context { - addAppLogEvent(postbox: context.account.postbox, type: "premium.promo_screen_accept") + context.engine.accountData.addAppLogEvent(type: "premium.promo_screen_accept") } self.inProgress = true @@ -3316,7 +3316,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent { self.updated(transition: .immediate) if let context = self.screenContext.context { - addAppLogEvent(postbox: context.account.postbox, type: "premium.promo_screen_fail") + context.engine.accountData.addAppLogEvent(type: "premium.promo_screen_fail") } let errorText = presentationData.strings.Premium_Purchase_ErrorUnknown @@ -3368,7 +3368,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent { if let errorText = errorText { if let context = self.screenContext.context { - addAppLogEvent(postbox: context.account.postbox, type: "premium.promo_screen_fail") + context.engine.accountData.addAppLogEvent(type: "premium.promo_screen_fail") } let alertController = textAlertController(sharedContext: self.screenContext.sharedContext, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]) diff --git a/submodules/SettingsUI/Sources/DeleteAccountDataController.swift b/submodules/SettingsUI/Sources/DeleteAccountDataController.swift index f7517c7427..d2c0a1b293 100644 --- a/submodules/SettingsUI/Sources/DeleteAccountDataController.swift +++ b/submodules/SettingsUI/Sources/DeleteAccountDataController.swift @@ -296,15 +296,15 @@ func deleteAccountDataController(context: AccountContext, mode: DeleteAccountDat switch mode { case .peers: - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_cloud_cancel") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_cloud_cancel") case .groups: - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_groups_cancel") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_groups_cancel") case .messages: - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_messages_cancel") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_messages_cancel") case .phone: - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_phone_cancel") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_phone_cancel") case .password: - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_2fa_cancel") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_2fa_cancel") } } @@ -437,10 +437,10 @@ func deleteAccountDataController(context: AccountContext, mode: DeleteAccountDat let controller = deleteAccountDataController(context: context, mode: nextMode, twoStepAuthData: twoStepAuthData) replaceTopControllerImpl?(controller) } else { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_confirmation_show") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_confirmation_show") presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.DeleteAccount_ConfirmationAlertTitle, text: presentationData.strings.DeleteAccount_ConfirmationAlertText, actions: [TextAlertAction(type: .destructiveAction, title: presentationData.strings.DeleteAccount_ConfirmationAlertDelete, action: { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.final") + context.engine.accountData.addAppLogEvent(type: "deactivate.final") invokeAppLogEventsSynchronization(postbox: context.account.postbox) @@ -473,7 +473,7 @@ func deleteAccountDataController(context: AccountContext, mode: DeleteAccountDat }) }) }), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_confirmation_cancel") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_confirmation_cancel") dismissImpl?() })], actionLayout: .vertical)) @@ -581,15 +581,15 @@ func deleteAccountDataController(context: AccountContext, mode: DeleteAccountDat switch mode { case .peers: - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_cloud_show") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_cloud_show") case .groups: - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_groups_show") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_groups_show") case .messages: - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_messages_show") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_messages_show") case .phone: - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_phone_show") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_phone_show") case .password: - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.step_2fa_show") + context.engine.accountData.addAppLogEvent(type: "deactivate.step_2fa_show") } return controller diff --git a/submodules/SettingsUI/Sources/DeleteAccountOptionsController.swift b/submodules/SettingsUI/Sources/DeleteAccountOptionsController.swift index 0e23345ba7..af79d8966e 100644 --- a/submodules/SettingsUI/Sources/DeleteAccountOptionsController.swift +++ b/submodules/SettingsUI/Sources/DeleteAccountOptionsController.swift @@ -181,7 +181,7 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo let supportPeerDisposable = MetaDisposable() let arguments = DeleteAccountOptionsArguments(changePhoneNumber: { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_phone_change_tap") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_phone_change_tap") let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.engine.account.peerId)) |> deliverOnMainQueue).start(next: { accountPeer in @@ -195,7 +195,7 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo dismissImpl?() }) }, addAccount: { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_add_account_tap") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_add_account_tap") let _ = (activeAccountsAndPeers(context: context) |> take(1) @@ -233,11 +233,11 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo } }) }, setupPrivacy: { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_privacy_tap") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_privacy_tap") replaceTopControllerImpl?(makePrivacyAndSecurityController(context: context), false) }, setupTwoStepAuth: { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_2fa_tap") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_2fa_tap") if let data = twoStepAuthData { switch data { @@ -263,7 +263,7 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo let controller = twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: false, data: twoStepAuthData.flatMap({ Signal.single(.access(configuration: $0)) }))) replaceTopControllerImpl?(controller, false) }, setPasscode: { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_passcode_tap") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_passcode_tap") let _ = passcodeOptionsAccessController(context: context, pushController: { controller in replaceTopControllerImpl?(controller, false) @@ -276,18 +276,18 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo }) dismissImpl?() }, clearCache: { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_clear_cache_tap") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_clear_cache_tap") pushControllerImpl?(StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in return storageUsageExceptionsScreen(context: context, category: category) })) dismissImpl?() }, clearSyncedContacts: { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_clear_contacts_tap") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_clear_contacts_tap") replaceTopControllerImpl?(dataPrivacyController(context: context), false) }, deleteChats: { - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_delete_chats_tap") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_delete_chats_tap") let presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -325,7 +325,7 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo openFaq(resolvedUrlPromise) }, contactSupport: { [weak navigationController] in - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_support_tap") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_support_tap") let presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -394,7 +394,7 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo ] ) alertController.dismissed = { _ in - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_support_cancel") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_support_cancel") } presentControllerImpl?(alertController, nil) }, deleteAccount: { @@ -464,7 +464,7 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo let _ = controller?.dismiss() } - addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_show") + context.engine.accountData.addAppLogEvent(type: "deactivate.options_show") return controller } diff --git a/submodules/SettingsUI/Sources/ThemePickerController.swift b/submodules/SettingsUI/Sources/ThemePickerController.swift index 986b79cc0b..5da8ce64b3 100644 --- a/submodules/SettingsUI/Sources/ThemePickerController.swift +++ b/submodules/SettingsUI/Sources/ThemePickerController.swift @@ -363,10 +363,10 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme var selectAccentColorImpl: ((TelegramBaseTheme?, PresentationThemeAccentColor?) -> Void)? var openAccentColorPickerImpl: ((PresentationThemeReference, Bool) -> Void)? - let _ = telegramWallpapers(postbox: context.account.postbox, network: context.account.network).start() + let _ = context.engine.themes.wallpapers().start() let cloudThemes = Promise<[TelegramTheme]>() - let updatedCloudThemes = telegramThemes(postbox: context.account.postbox, network: context.account.network, accountManager: context.sharedContext.accountManager) + let updatedCloudThemes = context.engine.themes.themes(accountManager: context.sharedContext.accountManager) cloudThemes.set(updatedCloudThemes) let removedThemeIndexesPromise = Promise>(Set()) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift index bc300e2812..799c42fb69 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift @@ -565,7 +565,7 @@ public func themeAutoNightSettingsController(context: AccountContext) -> ViewCon }) let cloudThemes = Promise<[TelegramTheme]>() - let updatedCloudThemes = telegramThemes(postbox: context.account.postbox, network: context.account.network, accountManager: context.sharedContext.accountManager) + let updatedCloudThemes = context.engine.themes.themes(accountManager: context.sharedContext.accountManager) cloudThemes.set(updatedCloudThemes) let signal = combineLatest(context.sharedContext.presentationData |> deliverOnMainQueue, sharedData |> deliverOnMainQueue, cloudThemes.get() |> deliverOnMainQueue, stagingSettingsPromise.get() |> deliverOnMainQueue) diff --git a/submodules/SettingsUI/Sources/Themes/ThemePreviewController.swift b/submodules/SettingsUI/Sources/Themes/ThemePreviewController.swift index a251af569a..80bcb63874 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemePreviewController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemePreviewController.swift @@ -284,7 +284,7 @@ public final class ThemePreviewController: ViewController { switch theme { case let .cloud(info): resolvedWallpaper = info.resolvedWallpaper - return telegramThemes(postbox: context.account.postbox, network: context.account.network, accountManager: context.sharedContext.accountManager) + return context.engine.themes.themes(accountManager: context.sharedContext.accountManager) |> take(1) |> map { themes -> Bool in if let _ = themes.first(where: { $0.id == info.theme.id }) { @@ -317,7 +317,7 @@ public final class ThemePreviewController: ViewController { }, scale: 1.0) let themeThumbnailData = themeThumbnail?.jpegData(compressionQuality: 0.6) - return telegramThemes(postbox: context.account.postbox, network: context.account.network, accountManager: context.sharedContext.accountManager) + return context.engine.themes.themes(accountManager: context.sharedContext.accountManager) |> take(1) |> mapToSignal { themes -> Signal<(PresentationThemeReference, Bool), NoError> in let similarTheme = themes.first(where: { $0.isCreator && $0.title == info.title }) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift index 9fcf97c4a6..965bca3666 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift @@ -520,7 +520,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The var selectAccentColorImpl: ((PresentationThemeAccentColor?) -> Void)? var openAccentColorPickerImpl: ((PresentationThemeReference, Bool) -> Void)? - let _ = telegramWallpapers(postbox: context.account.postbox, network: context.account.network).start() + let _ = context.engine.themes.wallpapers().start() let currentAppIcon: PresentationAppIcon? var appIcons = context.sharedContext.applicationBindings.getAvailableAlternateIcons() @@ -540,7 +540,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The currentAppIconName.set(currentAppIcon?.name ?? "Blue") let cloudThemes = Promise<[TelegramTheme]>() - let updatedCloudThemes = telegramThemes(postbox: context.account.postbox, network: context.account.network, accountManager: context.sharedContext.accountManager) + let updatedCloudThemes = context.engine.themes.themes(accountManager: context.sharedContext.accountManager) cloudThemes.set(updatedCloudThemes) let removedThemeIndexesPromise = Promise>(Set()) diff --git a/submodules/SpotlightSupport/BUILD b/submodules/SpotlightSupport/BUILD deleted file mode 100644 index ff77db99c2..0000000000 --- a/submodules/SpotlightSupport/BUILD +++ /dev/null @@ -1,18 +0,0 @@ -load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") - -swift_library( - name = "SpotlightSupport", - module_name = "SpotlightSupport", - srcs = glob([ - "Sources/**/*.swift", - ]), - deps = [ - "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", - "//submodules/SyncCore:SyncCore", - "//submodules/TelegramCore:TelegramCore", - "//submodules/Display:Display", - ], - visibility = [ - "//visibility:public", - ], -) diff --git a/submodules/StatisticsUI/Sources/StoryIconNode.swift b/submodules/StatisticsUI/Sources/StoryIconNode.swift index 7fec70ab34..7246e29bc6 100644 --- a/submodules/StatisticsUI/Sources/StoryIconNode.swift +++ b/submodules/StatisticsUI/Sources/StoryIconNode.swift @@ -4,7 +4,6 @@ import Display import AsyncDisplayKit import ComponentFlow import SwiftSignalKit -import Postbox import TelegramCore import PhotoResources import AvatarStoryIndicatorComponent @@ -15,7 +14,7 @@ final class StoryIconNode: ASDisplayNode { private let imageNode = TransformImageNode() private let storyIndicator = ComponentView() - init(context: AccountContext, theme: PresentationTheme, peer: Peer, storyItem: EngineStoryItem) { + init(context: AccountContext, theme: PresentationTheme, peer: EngineRawPeer, storyItem: EngineStoryItem) { self.imageNode.displaysAsynchronously = false super.init() @@ -29,7 +28,7 @@ final class StoryIconNode: ASDisplayNode { self.imageNode.frame = bounds.insetBy(dx: 3.0, dy: 3.0) self.frame = bounds - let media: Media? + let media: EngineRawMedia? switch storyItem.media { case let .image(image): media = image diff --git a/submodules/StickerPackPreviewUI/BUILD b/submodules/StickerPackPreviewUI/BUILD index 67a5eab359..32e8851557 100644 --- a/submodules/StickerPackPreviewUI/BUILD +++ b/submodules/StickerPackPreviewUI/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/Display:Display", - "//submodules/Postbox:Postbox", "//submodules/TelegramCore:TelegramCore", "//submodules/TelegramPresentationData:TelegramPresentationData", "//submodules/AccountContext:AccountContext", diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift index 538b72044c..4a968b8c6f 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift @@ -2,7 +2,6 @@ import Foundation import UIKit import Display import AsyncDisplayKit -import Postbox import TelegramCore import SwiftSignalKit import AccountContext @@ -802,19 +801,19 @@ private final class StickerPackContainer: ASDisplayNode { private func emojiSuggestionPeekContent(itemLayer: CALayer, file: TelegramMediaFile) -> Signal<(UIView, CGRect, PeekControllerContent)?, NoError> { let context = self.context - var collectionId: ItemCollectionId? + var collectionId: EngineItemCollectionId? for attribute in file.attributes { if case let .CustomEmoji(_, _, _, packReference) = attribute { switch packReference { case let .id(id, _): - collectionId = ItemCollectionId(namespace: Namespaces.ItemCollection.CloudEmojiPacks, id: id) + collectionId = EngineItemCollectionId(namespace: Namespaces.ItemCollection.CloudEmojiPacks, id: id) default: break } } } - var bubbleUpEmojiOrStickersets: [ItemCollectionId] = [] + var bubbleUpEmojiOrStickersets: [EngineItemCollectionId] = [] if let collectionId { bubbleUpEmojiOrStickersets.append(collectionId) } @@ -859,9 +858,9 @@ private final class StickerPackContainer: ASDisplayNode { case let .CustomEmoji(_, _, displayText, stickerPackReference): text = displayText - var packId: ItemCollectionId? + var packId: EngineItemCollectionId? if case let .id(id, _) = stickerPackReference { - packId = ItemCollectionId(namespace: Namespaces.ItemCollection.CloudEmojiPacks, id: id) + packId = EngineItemCollectionId(namespace: Namespaces.ItemCollection.CloudEmojiPacks, id: id) } emojiAttribute = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: packId, fileId: file.fileId.id, file: file) break loop @@ -1468,12 +1467,12 @@ private final class StickerPackContainer: ASDisplayNode { } if installedCount == self.currentStickerPacks.count { - var removedPacks: Signal<[(info: ItemCollectionInfo, index: Int, items: [ItemCollectionItem])], NoError> = .single([]) + var removedPacks: Signal<[(info: EngineRawItemCollectionInfo, index: Int, items: [EngineRawItemCollectionItem])], NoError> = .single([]) for (info, _, _) in self.currentStickerPacks { removedPacks = removedPacks - |> mapToSignal { current -> Signal<[(info: ItemCollectionInfo, index: Int, items: [ItemCollectionItem])], NoError> in + |> mapToSignal { current -> Signal<[(info: EngineRawItemCollectionInfo, index: Int, items: [EngineRawItemCollectionItem])], NoError> in return self.context.engine.stickers.removeStickerPackInteractively(id: info.id, option: .delete) - |> map { result -> [(info: ItemCollectionInfo, index: Int, items: [ItemCollectionItem])] in + |> map { result -> [(info: EngineRawItemCollectionInfo, index: Int, items: [EngineRawItemCollectionItem])] in if let result = result { return current + [(info, result.0, result.1)] } else { @@ -2968,13 +2967,6 @@ public final class StickerPackScreenImpl: ViewController, StickerPackScreen { } return .single(result) } - |> mapToSignal { peer -> Signal in - if let peer = peer { - return .single(peer._asPeer()) - } else { - return .single(nil) - } - } |> deliverOnMainQueue).start(next: { peer in guard let strongSelf = self else { return @@ -2982,7 +2974,7 @@ public final class StickerPackScreenImpl: ViewController, StickerPackScreen { if let peer { if let parentNavigationController = strongSelf.parentNavigationController { strongSelf.controllerNode.dismiss() - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: parentNavigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)), keepStack: .always, animated: true)) + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: parentNavigationController, context: strongSelf.context, chatLocation: .peer(peer), keepStack: .always, animated: true)) } } else { strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.Resolve_ErrorNotFound, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) diff --git a/submodules/StickerResources/Sources/StickerResources.swift b/submodules/StickerResources/Sources/StickerResources.swift index 229dbc7f6b..d435924b58 100644 --- a/submodules/StickerResources/Sources/StickerResources.swift +++ b/submodules/StickerResources/Sources/StickerResources.swift @@ -260,74 +260,6 @@ public func chatMessageAnimatedStickerBackingData(postbox: Postbox, fileReferenc } } -public func chatMessageLegacySticker(account: Account, userLocation: MediaResourceUserLocation, file: TelegramMediaFile, small: Bool, fitSize: CGSize, fetched: Bool = false, onlyFullSize: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { - let signal = chatMessageStickerDatas(postbox: account.postbox, userLocation: userLocation, file: file, small: small, fetched: fetched, onlyFullSize: onlyFullSize, synchronousLoad: false) - return signal |> map { value in - let fullSizeData = value._1 - let fullSizeComplete = value._2 - return { preArguments in - var fullSizeImage: (UIImage, UIImage)? - if let fullSizeData = fullSizeData, fullSizeComplete { - if let image = imageFromAJpeg(data: fullSizeData) { - fullSizeImage = image - } - } - - if let fullSizeImage = fullSizeImage { - var updatedFitSize = fitSize - if updatedFitSize.width.isEqual(to: 1.0) { - updatedFitSize = fullSizeImage.0.size - } - - let contextSize = fullSizeImage.0.size.aspectFitted(updatedFitSize) - - let arguments = TransformImageArguments(corners: preArguments.corners, imageSize: contextSize, boundingSize: contextSize, intrinsicInsets: preArguments.intrinsicInsets) - - guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { - return nil - } - - let thumbnailImage: CGImage? = nil - - var blurredThumbnailImage: UIImage? - if let thumbnailImage = thumbnailImage { - let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height) - let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0)) - if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) - } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - blurredThumbnailImage = thumbnailContext.generateImage() - } - } - - context.withFlippedContext { c in - c.setBlendMode(.copy) - if let blurredThumbnailImage = blurredThumbnailImage { - c.interpolationQuality = .low - c.draw(blurredThumbnailImage.cgImage!, in: arguments.drawingRect) - } - - if let cgImage = fullSizeImage.0.cgImage, let cgImageAlpha = fullSizeImage.1.cgImage { - c.setBlendMode(.normal) - c.interpolationQuality = .medium - - let mask = CGImage(maskWidth: cgImageAlpha.width, height: cgImageAlpha.height, bitsPerComponent: cgImageAlpha.bitsPerComponent, bitsPerPixel: cgImageAlpha.bitsPerPixel, bytesPerRow: cgImageAlpha.bytesPerRow, provider: cgImageAlpha.dataProvider!, decode: nil, shouldInterpolate: true) - - c.draw(cgImage.masking(mask!)!, in: arguments.drawingRect) - } - } - - return context - } else { - return nil - } - } - } -} public func chatMessageSticker(account: Account, userLocation: MediaResourceUserLocation, file: TelegramMediaFile, small: Bool, fetched: Bool = false, onlyFullSize: Bool = false, thumbnail: Bool = false, synchronousLoad: Bool = false, colorSpace: CGColorSpace? = nil) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { return chatMessageSticker(postbox: account.postbox, userLocation: userLocation, file: file, small: small, fetched: fetched, onlyFullSize: onlyFullSize, thumbnail: thumbnail, synchronousLoad: synchronousLoad, colorSpace: colorSpace) diff --git a/submodules/SvgRendering/BUILD b/submodules/SvgRendering/BUILD deleted file mode 100644 index 20e1b4b487..0000000000 --- a/submodules/SvgRendering/BUILD +++ /dev/null @@ -1,14 +0,0 @@ -load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") - -swift_library( - name = "SvgRendering", - module_name = "SvgRendering", - srcs = glob([ - "Sources/**/*.swift", - ]), - deps = [ - ], - visibility = [ - "//visibility:public", - ], -) diff --git a/submodules/SvgRendering/Sources/SvgParser.swift b/submodules/SvgRendering/Sources/SvgParser.swift deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/submodules/TelegramCallsUI/Sources/LegacyCallControllerNode.swift b/submodules/TelegramCallsUI/Sources/LegacyCallControllerNode.swift index 90c82ea124..1bb34d814e 100644 --- a/submodules/TelegramCallsUI/Sources/LegacyCallControllerNode.swift +++ b/submodules/TelegramCallsUI/Sources/LegacyCallControllerNode.swift @@ -2,7 +2,6 @@ import Foundation import UIKit import Display import AsyncDisplayKit -import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData diff --git a/submodules/TelegramCore/Sources/ApiUtils/ChatContextResult.swift b/submodules/TelegramCore/Sources/ApiUtils/ChatContextResult.swift index 2a56151233..81b3454c13 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/ChatContextResult.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/ChatContextResult.swift @@ -5,10 +5,6 @@ import TelegramApi import MtProtoKit -public enum ChatContextResultMessageDecodingError: Error { - case generic -} - public enum ChatContextResultMessage: PostboxCoding, Equatable, Codable { enum CodingKeys: String, CodingKey { case data diff --git a/submodules/TelegramCore/Sources/ApiUtils/CloudMediaResourceParameters.swift b/submodules/TelegramCore/Sources/ApiUtils/CloudMediaResourceParameters.swift deleted file mode 100644 index e9e165bf24..0000000000 --- a/submodules/TelegramCore/Sources/ApiUtils/CloudMediaResourceParameters.swift +++ /dev/null @@ -1,8 +0,0 @@ -import Foundation - -public enum CloudMediaResourceLocation: Equatable { - case photo(id: Int64, accessHash: Int64, fileReference: Data, thumbSize: String) - case file(id: Int64, accessHash: Int64, fileReference: Data, thumbSize: String) - case peerPhoto(peer: PeerReference, fullSize: Bool, volumeId: Int64, localId: Int64) - case stickerPackThumbnail(packReference: StickerPackReference, volumeId: Int64, localId: Int64) -} diff --git a/submodules/TelegramCore/Sources/Authorization.swift b/submodules/TelegramCore/Sources/Authorization.swift index 5bc16112de..61c1d41955 100644 --- a/submodules/TelegramCore/Sources/Authorization.swift +++ b/submodules/TelegramCore/Sources/Authorization.swift @@ -1321,16 +1321,6 @@ public func authorizeWithPasskey(accountManager: AccountManager switchToLatest } -public enum AuthorizationStateReset { - case empty -} - -public func resetAuthorizationState(account: UnauthorizedAccount, to value: AuthorizationStateReset) -> Signal { - return account.postbox.transaction { transaction -> Void in - if let state = transaction.getState() as? UnauthorizedAccountState { - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: state.isTestingEnvironment, masterDatacenterId: state.masterDatacenterId, contents: .empty)) - } - } -} - public func togglePreviousCodeEntry(account: UnauthorizedAccount) -> Signal { return account.postbox.transaction { transaction -> Void in if let state = transaction.getState() as? UnauthorizedAccountState { diff --git a/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift b/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift index c6e524f8b8..494ff54652 100644 --- a/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift +++ b/submodules/TelegramCore/Sources/Network/FetchedMediaResource.swift @@ -671,7 +671,7 @@ final class MediaReferenceRevalidationContext { } |> map { [$0] } } else { - signal = telegramWallpapers(postbox: postbox, network: network, forceUpdate: true) + signal = _internal_telegramWallpapers(postbox: postbox, network: network, forceUpdate: true) |> last |> mapError { _ -> RevalidateMediaReferenceError in } @@ -697,7 +697,7 @@ final class MediaReferenceRevalidationContext { func themes(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramTheme], RevalidateMediaReferenceError> { return self.genericItem(key: .themes, background: background, request: { next, error in - return (telegramThemes(postbox: postbox, network: network, accountManager: nil, forceUpdate: true) + return (_internal_telegramThemes(postbox: postbox, network: network, accountManager: nil, forceUpdate: true) |> take(1) |> mapError { _ -> RevalidateMediaReferenceError in }).start(next: { value in diff --git a/submodules/TelegramCore/Sources/Network/NetworkStatsContext.swift b/submodules/TelegramCore/Sources/Network/NetworkStatsContext.swift index 9b23e2aafa..5c5f0d885f 100644 --- a/submodules/TelegramCore/Sources/Network/NetworkStatsContext.swift +++ b/submodules/TelegramCore/Sources/Network/NetworkStatsContext.swift @@ -87,7 +87,7 @@ final class NetworkStatsContext { for (targetKey, averageStats) in self.averageTargetStats { if averageStats.count >= 1000 || averageStats.size >= 4 * 1024 * 1024 { if let postbox = self.postbox { - addAppLogEvent(postbox: postbox, type: "download", data: .dictionary([ + _internal_addAppLogEvent(postbox: postbox, type: "download", data: .dictionary([ "n": .number(Double(targetKey.networkType.rawValue)), "d": .number(Double(targetKey.datacenterId)), "b": .number(averageStats.networkBps / Double(averageStats.count)), diff --git a/submodules/TelegramCore/Sources/PendingMessages/EnqueueMessage.swift b/submodules/TelegramCore/Sources/PendingMessages/EnqueueMessage.swift index 9d7be75ab7..13fdd45ad0 100644 --- a/submodules/TelegramCore/Sources/PendingMessages/EnqueueMessage.swift +++ b/submodules/TelegramCore/Sources/PendingMessages/EnqueueMessage.swift @@ -408,37 +408,6 @@ public func enqueueMessages(account: Account, peerId: PeerId, messages: [Enqueue } } -public func enqueueMessagesToMultiplePeers(account: Account, peerIds: [PeerId], threadIds: [PeerId: Int64], messages: [EnqueueMessage]) -> Signal<[MessageId], NoError> { - let signal: Signal<[(Bool, EnqueueMessage)], NoError> - if let transformOutgoingMessageMedia = account.transformOutgoingMessageMedia { - signal = opportunisticallyTransformOutgoingMedia(network: account.network, postbox: account.postbox, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messages: messages, userInteractive: true) - } else { - signal = .single(messages.map { (false, $0) }) - } - return signal - |> mapToSignal { messages -> Signal<[MessageId], NoError> in - return account.postbox.transaction { transaction -> [MessageId] in - var messageIds: [MessageId] = [] - for peerId in peerIds { - var replyToMessageId: EngineMessageReplySubject? - if let threadIds = threadIds[peerId] { - replyToMessageId = EngineMessageReplySubject(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadIds)), quote: nil, innerSubject: nil) - } - var messages = messages - if let replyToMessageId = replyToMessageId { - messages = messages.map { ($0.0, $0.1.withUpdatedReplyToMessageId(replyToMessageId)) } - } - for id in enqueueMessages(transaction: transaction, account: account, peerId: peerId, messages: messages, disableAutoremove: false, transformGroupingKeysWithPeerId: true) { - if let id = id { - messageIds.append(id) - } - } - } - return messageIds - } - } -} - public func resendMessages(account: Account, messageIds: [MessageId]) -> Signal { return account.postbox.transaction { transaction -> Void in var removeMessageIds: [MessageId] = [] diff --git a/submodules/TelegramCore/Sources/PendingMessages/StandaloneUploadedMedia.swift b/submodules/TelegramCore/Sources/PendingMessages/StandaloneUploadedMedia.swift index 1362d20c6e..4c2f0cfdd0 100644 --- a/submodules/TelegramCore/Sources/PendingMessages/StandaloneUploadedMedia.swift +++ b/submodules/TelegramCore/Sources/PendingMessages/StandaloneUploadedMedia.swift @@ -8,12 +8,6 @@ public enum StandaloneUploadMediaError { case generic } -public struct StandaloneUploadSecretFile { - let file: Api.InputEncryptedFile - let size: Int32 - let key: SecretFileEncryptionKey -} - public enum StandaloneUploadMediaThumbnailResult { case pending case file(Api.InputFile) diff --git a/submodules/TelegramCore/Sources/Settings/ContentPrivacySettings.swift b/submodules/TelegramCore/Sources/Settings/ContentPrivacySettings.swift deleted file mode 100644 index 02487dc5c5..0000000000 --- a/submodules/TelegramCore/Sources/Settings/ContentPrivacySettings.swift +++ /dev/null @@ -1,20 +0,0 @@ -import Foundation -import Postbox -import SwiftSignalKit -import MtProtoKit - - -public func updateContentPrivacySettings(postbox: Postbox, _ f: @escaping (ContentPrivacySettings) -> ContentPrivacySettings) -> Signal { - return postbox.transaction { transaction -> Void in - var updated: ContentPrivacySettings? - transaction.updatePreferencesEntry(key: PreferencesKeys.contentPrivacySettings, { current in - if let current = current?.get(ContentPrivacySettings.self) { - updated = f(current) - return PreferencesEntry(updated) - } else { - updated = f(ContentPrivacySettings.defaultSettings) - return PreferencesEntry(updated) - } - }) - } -} diff --git a/submodules/TelegramCore/Sources/SplitTest.swift b/submodules/TelegramCore/Sources/SplitTest.swift index 84f6211ee6..4bce45abdd 100644 --- a/submodules/TelegramCore/Sources/SplitTest.swift +++ b/submodules/TelegramCore/Sources/SplitTest.swift @@ -24,7 +24,7 @@ extension SplitTest { public func addEvent(_ event: Self.Event, data: JSON = []) { if let bucket = self.bucket { //TODO: merge additional data - addAppLogEvent(postbox: self.postbox, type: event.rawValue, data: ["bucket": bucket]) + _internal_addAppLogEvent(postbox: self.postbox, type: event.rawValue, data: ["bucket": bucket]) } } } diff --git a/submodules/TelegramCore/Sources/State/CallSessionManager.swift b/submodules/TelegramCore/Sources/State/CallSessionManager.swift index f5eb58ef58..3c5bfd89ba 100644 --- a/submodules/TelegramCore/Sources/State/CallSessionManager.swift +++ b/submodules/TelegramCore/Sources/State/CallSessionManager.swift @@ -1423,10 +1423,6 @@ private final class CallSessionManagerContext { } } -public enum CallRequestError { - case generic -} - public final class CallSessionManager { public static func getStableIncomingUUID(stableId: Int64) -> UUID { return StableIncomingUUIDs.shared.with { impl in diff --git a/submodules/TelegramCore/Sources/State/SynchronizeAppLogEventsOperation.swift b/submodules/TelegramCore/Sources/State/SynchronizeAppLogEventsOperation.swift index 2a537b4eca..25aa617acf 100644 --- a/submodules/TelegramCore/Sources/State/SynchronizeAppLogEventsOperation.swift +++ b/submodules/TelegramCore/Sources/State/SynchronizeAppLogEventsOperation.swift @@ -4,7 +4,7 @@ import SwiftSignalKit import MtProtoKit -public func addAppLogEvent(postbox: Postbox, time: Double = Date().timeIntervalSince1970, type: String, peerId: PeerId? = nil, data: JSON = .dictionary([:])) { +func _internal_addAppLogEvent(postbox: Postbox, time: Double = Date().timeIntervalSince1970, type: String, peerId: PeerId? = nil, data: JSON = .dictionary([:])) { let tag: PeerOperationLogTag = OperationLogTags.SynchronizeAppLogEvents let peerId = PeerId(0) let _ = (postbox.transaction { transaction in diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_ArchivedStickerPacksInfo.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_ArchivedStickerPacksInfo.swift deleted file mode 100644 index 351efd445d..0000000000 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_ArchivedStickerPacksInfo.swift +++ /dev/null @@ -1,42 +0,0 @@ -import Foundation -import Postbox - -public struct ArchivedStickerPacksInfoId { - public let rawValue: MemoryBuffer - public let id: Int32 - - init(_ rawValue: MemoryBuffer) { - self.rawValue = rawValue - assert(rawValue.length == 4) - var idValue: Int32 = 0 - memcpy(&idValue, rawValue.memory, 4) - self.id = idValue - } - - init(_ id: Int32) { - self.id = id - var idValue: Int32 = id - self.rawValue = MemoryBuffer(memory: malloc(4)!, capacity: 4, length: 4, freeWhenDone: true) - memcpy(self.rawValue.memory, &idValue, 4) - } -} - -public final class ArchivedStickerPacksInfo: Codable { - public let count: Int32 - - init(count: Int32) { - self.count = count - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: StringCodingKey.self) - - self.count = try container.decode(Int32.self, forKey: "c") - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: StringCodingKey.self) - - try container.encode(self.count, forKey: "c") - } -} diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_AutodownloadSettings.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_AutodownloadSettings.swift index 0af53f8312..5e4d50bd4d 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_AutodownloadSettings.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_AutodownloadSettings.swift @@ -1,11 +1,5 @@ import Postbox -public enum AutodownloadPreset { - case low - case medium - case high -} - public struct AutodownloadPresetSettings: Codable { public let disabled: Bool public let photoSizeMax: Int64 diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_LocalMediaPlaybackInfoAttribute.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_LocalMediaPlaybackInfoAttribute.swift deleted file mode 100644 index ecc83d4a59..0000000000 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_LocalMediaPlaybackInfoAttribute.swift +++ /dev/null @@ -1,18 +0,0 @@ -import Foundation -import Postbox - -public class LocalMediaPlaybackInfoAttribute: MessageAttribute { - public let data: Data - - public init(data: Data) { - self.data = data - } - - required public init(decoder: PostboxDecoder) { - self.data = decoder.decodeDataForKey("d") ?? Data() - } - - public func encode(_ encoder: PostboxEncoder) { - encoder.encodeData(self.data, forKey: "d") - } -} diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_NewSessionReview.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_NewSessionReview.swift index 71e3094910..639434860b 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_NewSessionReview.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_NewSessionReview.swift @@ -114,23 +114,6 @@ public func newSessionReviews(postbox: Postbox) -> Signal<[NewSessionReview], No } } -public func addNewSessionReview(postbox: Postbox, item: NewSessionReview) -> Signal { - return postbox.transaction { transaction -> Void in - guard let entry = CodableEntry(item) else { - return - } - transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.NewSessionReviews, item: OrderedItemListEntry(id: NewSessionReview.Id(id: item.id).rawValue, contents: entry), removeTailIfCountExceeds: 200) - } - |> ignoreValues -} - -public func clearNewSessionReviews(postbox: Postbox) -> Signal { - return postbox.transaction { transaction -> Void in - transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.NewSessionReviews, items: []) - } - |> ignoreValues -} - public func removeNewSessionReviews(postbox: Postbox, ids: [Int64]) -> Signal { return postbox.transaction { transaction -> Void in for id in ids { diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaFile.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaFile.swift index c999ba735b..ad6480a0d2 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaFile.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaFile.swift @@ -653,34 +653,6 @@ public enum TelegramMediaFileAttribute: PostboxCoding, Equatable { } } -public enum TelegramMediaFileReference: PostboxCoding, Equatable { - case cloud(fileId: Int64, accessHash: Int64, fileReference: Data?) - - public init(decoder: PostboxDecoder) { - switch decoder.decodeInt32ForKey("_v", orElse: 0) { - case 0: - self = .cloud(fileId: decoder.decodeInt64ForKey("i", orElse: 0), accessHash: decoder.decodeInt64ForKey("h", orElse: 0), fileReference: decoder.decodeBytesForKey("fr")?.makeData()) - default: - self = .cloud(fileId: 0, accessHash: 0, fileReference: nil) - assertionFailure() - } - } - - public func encode(_ encoder: PostboxEncoder) { - switch self { - case let .cloud(imageId, accessHash, fileReference): - encoder.encodeInt32(0, forKey: "_v") - encoder.encodeInt64(imageId, forKey: "i") - encoder.encodeInt64(accessHash, forKey: "h") - if let fileReference = fileReference { - encoder.encodeBytes(MemoryBuffer(data: fileReference), forKey: "fr") - } else { - encoder.encodeNil(forKey: "fr") - } - } - } -} - public enum TelegramMediaFileDecodingError: Error { case generic } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_VoipConfiguration.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_VoipConfiguration.swift index c91b598a8b..76f3957519 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_VoipConfiguration.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_VoipConfiguration.swift @@ -1,12 +1,6 @@ import Foundation import Postbox -public enum VoiceCallP2PMode: Int32 { - case never = 0 - case contacts = 1 - case always = 2 -} - public struct VoipConfiguration: Codable, Equatable { public var serializedData: String? diff --git a/submodules/TelegramCore/Sources/TelegramEngine/AccountData/TelegramEngineAccountData.swift b/submodules/TelegramCore/Sources/TelegramEngine/AccountData/TelegramEngineAccountData.swift index aeda4da023..7b4e1d2a21 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/AccountData/TelegramEngineAccountData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/AccountData/TelegramEngineAccountData.swift @@ -15,6 +15,10 @@ public extension TelegramEngine { return _internal_acceptTermsOfService(account: self.account, id: id) } + public func addAppLogEvent(time: Double = Date().timeIntervalSince1970, type: String, data: JSON = .dictionary([:])) { + _internal_addAppLogEvent(postbox: self.account.postbox, time: time, type: type, peerId: nil, data: data) + } + public func requestChangeAccountPhoneNumberVerification(apiId: Int32, apiHash: String, phoneNumber: String, pushNotificationConfiguration: AuthorizationCodePushNotificationConfiguration?, firebaseSecretStream: Signal<[String: String], NoError>) -> Signal { return _internal_requestChangeAccountPhoneNumberVerification(account: self.account, apiId: apiId, apiHash: apiHash, phoneNumber: phoneNumber, pushNotificationConfiguration: pushNotificationConfiguration, firebaseSecretStream: firebaseSecretStream) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Auth/TwoStepVerification.swift b/submodules/TelegramCore/Sources/TelegramEngine/Auth/TwoStepVerification.swift index d0e005a8ae..1fd31b354e 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Auth/TwoStepVerification.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Auth/TwoStepVerification.swift @@ -337,13 +337,6 @@ func _internal_requestTwoStepVerificationPasswordRecoveryCode(network: Network) } } -public enum RecoverTwoStepVerificationPasswordError { - case generic - case codeExpired - case limitExceeded - case invalidCode -} - func _internal_cachedTwoStepPasswordToken(postbox: Postbox) -> Signal { return postbox.transaction { transaction -> TemporaryTwoStepPasswordToken? in let key = ValueBoxKey(length: 1) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift b/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift index c82eabeb16..711546a2fc 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift @@ -3415,10 +3415,6 @@ func _internal_revokeConferenceInviteLink(account: Account, reference: InternalG } } -public enum ConfirmAddConferenceParticipantError { - case generic -} - func _internal_pollConferenceCallBlockchain(network: Network, reference: InternalGroupCallReference, subChainId: Int, offset: Int, limit: Int) -> Signal<(blocks: [Data], nextOffset: Int)?, NoError> { return network.request(Api.functions.phone.getGroupCallChainBlocks(call: reference.apiInputGroupCall, subChainId: Int32(subChainId), offset: Int32(offset), limit: Int32(limit))) |> map(Optional.init) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/AppStore.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/AppStore.swift index cb765c543f..e874239521 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/AppStore.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/AppStore.swift @@ -202,10 +202,6 @@ func _internal_sendAppStoreReceipt(postbox: Postbox, network: Network, stateMana } } -public enum RestoreAppStoreReceiptError { - case generic -} - func _internal_canPurchasePremium(postbox: Postbox, network: Network, purpose: AppStoreTransactionPurpose) -> Signal { return apiInputStorePaymentPurpose(postbox: postbox, purpose: purpose) |> mapToSignal { purpose -> Signal in diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChatListFiltering.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChatListFiltering.swift index 8629381181..efa36b984c 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChatListFiltering.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChatListFiltering.swift @@ -4,18 +4,6 @@ import SwiftSignalKit import TelegramApi -public struct ChatListFilteringConfiguration: Equatable { - public let isEnabled: Bool - - public init(appConfiguration: AppConfiguration) { - var isEnabled = false - if let data = appConfiguration.data, let value = data["dialog_filters_enabled"] as? Bool, value { - isEnabled = true - } - self.isEnabled = isEnabled - } -} - public struct ChatListFilterPeerCategories: OptionSet, Hashable { public var rawValue: Int32 diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ResolvePeerByName.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ResolvePeerByName.swift index 2e290468fb..21698d63bf 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ResolvePeerByName.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ResolvePeerByName.swift @@ -3,17 +3,6 @@ import Postbox import TelegramApi import SwiftSignalKit -public enum ResolvePeerByNameOptionCached { - case none - case cached - case cachedIfLaterThan(timestamp: Int32) -} - -public enum ResolvePeerByNameOptionRemote { - case updateIfEarlierThan(timestamp: Int32) - case update -} - public enum ResolvePeerIdByNameResult { case progress case result(PeerId?) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SaveSecureIdValue.swift b/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SaveSecureIdValue.swift index 818d662be9..a629a77757 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SaveSecureIdValue.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SaveSecureIdValue.swift @@ -276,44 +276,6 @@ public func deleteSecureIdValues(network: Network, keys: Set) } } -public func dropSecureId(network: Network, currentPassword: String) -> Signal { - return _internal_twoStepAuthData(network) - |> mapError { _ -> AuthorizationPasswordVerificationError in - return .generic - } - |> mapToSignal { authData -> Signal in - let checkPassword: Api.InputCheckPasswordSRP - if let currentPasswordDerivation = authData.currentPasswordDerivation, let srpSessionData = authData.srpSessionData { - let kdfResult = passwordKDF(encryptionProvider: network.encryptionProvider, password: currentPassword, derivation: currentPasswordDerivation, srpSessionData: srpSessionData) - if let kdfResult = kdfResult { - checkPassword = .inputCheckPasswordSRP(.init(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1))) - } else { - return .fail(.generic) - } - } else { - checkPassword = .inputCheckPasswordEmpty - } - - let settings = network.request(Api.functions.account.getPasswordSettings(password: checkPassword), automaticFloodWait: false) - |> mapError { error in - return AuthorizationPasswordVerificationError.generic - } - - return settings - |> mapToSignal { value -> Signal in - switch value { - case .passwordSettings: - var flags: Int32 = 0 - flags |= (1 << 2) - return network.request(Api.functions.account.updatePasswordSettings(password: .inputCheckPasswordEmpty, newSettings: .passwordInputSettings(.init(flags: flags, newAlgo: nil, newPasswordHash: nil, hint: nil, email: nil, newSecureSettings: nil))), automaticFloodWait: false) - |> map { _ in } - |> mapError { _ in - return AuthorizationPasswordVerificationError.generic - } - } - } - } -} public enum GetAllSecureIdValuesError { case generic diff --git a/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SecureIdValueAccessContext.swift b/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SecureIdValueAccessContext.swift index 88bc31d1ff..90c64deab8 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SecureIdValueAccessContext.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SecureIdValueAccessContext.swift @@ -15,10 +15,6 @@ public struct SecureIdValueAccessContext: Equatable { } } -public func generateSecureIdValueEmptyAccessContext() -> SecureIdValueAccessContext? { - return SecureIdValueAccessContext(secret: Data(), id: 0) -} - public func generateSecureIdValueAccessContext() -> SecureIdValueAccessContext? { guard let secret = generateSecureSecretData() else { return nil diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Themes/TelegramEngineThemes.swift b/submodules/TelegramCore/Sources/TelegramEngine/Themes/TelegramEngineThemes.swift index b6b890c3a7..c4c5f760c8 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Themes/TelegramEngineThemes.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Themes/TelegramEngineThemes.swift @@ -12,6 +12,14 @@ public extension TelegramEngine { public func getChatThemes(accountManager: AccountManager, forceUpdate: Bool = false, onlyCached: Bool = false) -> Signal<[TelegramTheme], NoError> { return _internal_getChatThemes(accountManager: accountManager, network: self.account.network, forceUpdate: forceUpdate, onlyCached: onlyCached) } + + public func themes(accountManager: AccountManager, forceUpdate: Bool = false) -> Signal<[TelegramTheme], NoError> { + return _internal_telegramThemes(postbox: self.account.postbox, network: self.account.network, accountManager: accountManager, forceUpdate: forceUpdate) + } + + public func wallpapers(forceUpdate: Bool = false) -> Signal<[TelegramWallpaper], NoError> { + return _internal_telegramWallpapers(postbox: self.account.postbox, network: self.account.network, forceUpdate: forceUpdate) + } public func setChatTheme(peerId: PeerId, chatTheme: ChatTheme?) -> Signal { return _internal_setChatTheme(account: self.account, peerId: peerId, chatTheme: chatTheme) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Utils/EnginePostboxCoding.swift b/submodules/TelegramCore/Sources/TelegramEngine/Utils/EnginePostboxCoding.swift index 9d0752d94e..23714d0d0a 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Utils/EnginePostboxCoding.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Utils/EnginePostboxCoding.swift @@ -4,6 +4,7 @@ public typealias EngineMemoryBuffer = MemoryBuffer public typealias EnginePostboxDecoder = PostboxDecoder public typealias EnginePostboxEncoder = PostboxEncoder public typealias EngineAdaptedPostboxDecoder = AdaptedPostboxDecoder +public typealias EngineAdaptedPostboxEncoder = AdaptedPostboxEncoder public typealias EngineItemCollectionId = ItemCollectionId public typealias EngineStoryId = StoryId public typealias EngineFetchResourceSourceType = FetchResourceSourceType @@ -18,6 +19,7 @@ public typealias EngineValueBoxEncryptionParameters = ValueBoxEncryptionParamete public typealias EngineMessageAndThreadId = MessageAndThreadId public typealias EnginePeerStoryStats = PeerStoryStats public typealias EngineMessageHistoryAnchorIndex = MessageHistoryAnchorIndex +public typealias EngineMessageHistoryEntryLocation = MessageHistoryEntryLocation public typealias EngineChatListTotalUnreadStateCategory = ChatListTotalUnreadStateCategory public typealias EngineChatListTotalUnreadStateStats = ChatListTotalUnreadStateStats public typealias EngineChatListTotalUnreadState = ChatListTotalUnreadState @@ -28,8 +30,28 @@ public typealias EngineCachedMediaResourceRepresentationResult = CachedMediaReso public typealias EngineMediaResourceDataFetchResult = MediaResourceDataFetchResult public typealias EngineMediaResourceDataFetchError = MediaResourceDataFetchError public typealias EngineMediaResourceStatus = MediaResourceStatus +public typealias EnginePostboxCoding = PostboxCoding +public typealias EngineRawItemCollectionInfo = ItemCollectionInfo +public typealias EngineRawItemCollectionItem = ItemCollectionItem +public typealias EngineRawMedia = Media +public typealias EngineRawMessage = Message +public typealias EngineRawPeer = Peer +public typealias EngineRawMediaResource = MediaResource +public typealias EngineRawMediaResourceId = MediaResourceId +public typealias EngineRawMediaResourceData = MediaResourceData +public typealias EngineRawMediaResourceDataFetchCopyLocalItem = MediaResourceDataFetchCopyLocalItem +public typealias EngineRawCachedMediaResourceRepresentation = CachedMediaResourceRepresentation +public typealias EngineCachedMediaRepresentationKeepDuration = CachedMediaRepresentationKeepDuration public typealias EngineCachedPeerData = CachedPeerData public func engineFileSize(_ path: String, useTotalFileAllocatedSize: Bool = false) -> Int64? { return fileSize(path, useTotalFileAllocatedSize: useTotalFileAllocatedSize) } + +public func enginePersistentHash32(_ string: String) -> Int32 { + return persistentHash32(string) +} + +public func engineDeclareEncodable(_ type: Any.Type, f: @escaping (EnginePostboxDecoder) -> EnginePostboxCoding) { + declareEncodable(type, f: f) +} diff --git a/submodules/TelegramCore/Sources/Themes.swift b/submodules/TelegramCore/Sources/Themes.swift index 4d8b2d4124..b7d49d7a19 100644 --- a/submodules/TelegramCore/Sources/Themes.swift +++ b/submodules/TelegramCore/Sources/Themes.swift @@ -11,7 +11,7 @@ let telegramThemeFormat = "ios" let telegramThemeFileExtension = "tgios-theme" #endif -public func telegramThemes(postbox: Postbox, network: Network, accountManager: AccountManager?, forceUpdate: Bool = false) -> Signal<[TelegramTheme], NoError> { +func _internal_telegramThemes(postbox: Postbox, network: Network, accountManager: AccountManager?, forceUpdate: Bool = false) -> Signal<[TelegramTheme], NoError> { let fetch: ([TelegramTheme]?, Int64?) -> Signal<[TelegramTheme], NoError> = { current, hash in network.request(Api.functions.account.getThemes(format: telegramThemeFormat, hash: hash ?? 0)) |> retryRequest @@ -145,7 +145,7 @@ private func saveUnsaveTheme(account: Account, accountManager: AccountManager mapToSignal { _ -> Signal in - return telegramThemes(postbox: account.postbox, network: account.network, accountManager: accountManager, forceUpdate: true) + return _internal_telegramThemes(postbox: account.postbox, network: account.network, accountManager: accountManager, forceUpdate: true) |> take(1) |> mapToSignal { _ -> Signal in return .complete() @@ -542,7 +542,7 @@ func managedThemesUpdates(accountManager: AccountManager take(1)).start() } }.start() diff --git a/submodules/TelegramCore/Sources/Utils/PeerUtils.swift b/submodules/TelegramCore/Sources/Utils/PeerUtils.swift index df30e8c937..955b0eccd7 100644 --- a/submodules/TelegramCore/Sources/Utils/PeerUtils.swift +++ b/submodules/TelegramCore/Sources/Utils/PeerUtils.swift @@ -478,18 +478,6 @@ public func peerViewMainPeer(_ view: PeerView) -> Peer? { } } -public func peerViewMonoforumMainPeer(_ view: PeerView) -> Peer? { - if let peer = peerViewMainPeer(view) { - if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum), let linkedMonoforumId = channel.linkedMonoforumId { - return view.peers[linkedMonoforumId] - } else { - return nil - } - } else { - return nil - } -} - public extension RenderedPeer { convenience init(peer: EnginePeer) { self.init(peer: peer._asPeer()) diff --git a/submodules/TelegramCore/Sources/Wallpapers.swift b/submodules/TelegramCore/Sources/Wallpapers.swift index 84985dc5dd..670afaa857 100644 --- a/submodules/TelegramCore/Sources/Wallpapers.swift +++ b/submodules/TelegramCore/Sources/Wallpapers.swift @@ -4,7 +4,7 @@ import SwiftSignalKit import TelegramApi -public func telegramWallpapers(postbox: Postbox, network: Network, forceUpdate: Bool = false) -> Signal<[TelegramWallpaper], NoError> { +func _internal_telegramWallpapers(postbox: Postbox, network: Network, forceUpdate: Bool = false) -> Signal<[TelegramWallpaper], NoError> { let fetch: ([TelegramWallpaper]?, Int64?) -> Signal<[TelegramWallpaper], NoError> = { current, hash in network.request(Api.functions.account.getWallPapers(hash: hash ?? 0)) |> retryRequestIfNotFrozen diff --git a/submodules/TelegramCore/Sources/WebpagePreview.swift b/submodules/TelegramCore/Sources/WebpagePreview.swift index 926417f85e..770233baff 100644 --- a/submodules/TelegramCore/Sources/WebpagePreview.swift +++ b/submodules/TelegramCore/Sources/WebpagePreview.swift @@ -39,10 +39,6 @@ public enum WebpagePreviewWithProgressResult { case progress(Float) } -public func normalizedWebpagePreviewUrl(url: String) -> String { - return url -} - public func webpagePreviewWithProgress(account: Account, urls: [String], webpageId: MediaId? = nil, forPeerId: PeerId? = nil) -> Signal { return account.postbox.transaction { transaction -> Signal in if let webpageId = webpageId, let webpage = transaction.getMedia(webpageId) as? TelegramMediaWebpage, let url = webpage.content.url { diff --git a/submodules/TelegramPresentationData/Sources/PresentationData.swift b/submodules/TelegramPresentationData/Sources/PresentationData.swift index ca3e549ff3..f557750fd4 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationData.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationData.swift @@ -504,11 +504,6 @@ private func automaticThemeShouldSwitchNow(_ parameters: AutomaticThemeSwitchPar } } -public func automaticThemeShouldSwitchNow(settings: AutomaticThemeSwitchSetting, systemUserInterfaceStyle: WindowUserInterfaceStyle) -> Bool { - let parameters = AutomaticThemeSwitchParameters(settings: settings) - return automaticThemeShouldSwitchNow(parameters, systemUserInterfaceStyle: systemUserInterfaceStyle) -} - private func automaticThemeShouldSwitch(_ settings: AutomaticThemeSwitchSetting, systemUserInterfaceStyle: WindowUserInterfaceStyle) -> Signal { if settings.force { return .single(true) diff --git a/submodules/TelegramUI/Components/Chat/ChatButtonKeyboardInputNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatButtonKeyboardInputNode/BUILD index d124e45634..9396769890 100644 --- a/submodules/TelegramUI/Components/Chat/ChatButtonKeyboardInputNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatButtonKeyboardInputNode/BUILD @@ -12,7 +12,6 @@ swift_library( deps = [ "//submodules/Display", "//submodules/AsyncDisplayKit", - "//submodules/Postbox", "//submodules/TelegramCore", "//submodules/SSignalKit/SwiftSignalKit", "//submodules/TelegramPresentationData", diff --git a/submodules/TelegramUI/Components/Chat/ChatHistorySearchContainerNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatHistorySearchContainerNode/BUILD index f192f2f409..4bba448043 100644 --- a/submodules/TelegramUI/Components/Chat/ChatHistorySearchContainerNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatHistorySearchContainerNode/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/AsyncDisplayKit", "//submodules/Display", "//submodules/SSignalKit/SwiftSignalKit", - "//submodules/Postbox", "//submodules/TelegramCore", "//submodules/TelegramPresentationData", "//submodules/MergeLists", diff --git a/submodules/TelegramUI/Components/Chat/ChatHistorySearchContainerNode/Sources/ChatHistorySearchContainerNode.swift b/submodules/TelegramUI/Components/Chat/ChatHistorySearchContainerNode/Sources/ChatHistorySearchContainerNode.swift index 8e857273f7..c9ca8638b1 100644 --- a/submodules/TelegramUI/Components/Chat/ChatHistorySearchContainerNode/Sources/ChatHistorySearchContainerNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatHistorySearchContainerNode/Sources/ChatHistorySearchContainerNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import TelegramPresentationData import MergeLists @@ -35,11 +34,11 @@ private extension ListMessageItemInteraction { } private enum ChatHistorySearchEntryStableId: Hashable { - case messageId(MessageId) + case messageId(EngineMessage.Id) } private enum ChatHistorySearchEntry: Comparable, Identifiable { - case message(Message, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationFontSize) + case message(EngineRawMessage, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationFontSize) var stableId: ChatHistorySearchEntryStableId { switch self { @@ -88,7 +87,7 @@ private enum ChatHistorySearchEntry: Comparable, Identifiable { } } - func item(context: AccountContext, peerId: PeerId, interaction: ChatControllerInteraction) -> ListViewItem { + func item(context: AccountContext, peerId: EnginePeer.Id, interaction: ChatControllerInteraction) -> ListViewItem { switch self { case let .message(message, theme, strings, dateTimeFormat, fontSize): return ListMessageItem(presentationData: ChatPresentationData(theme: ChatPresentationThemeData(theme: theme, wallpaper: .builtin(WallpaperSettings())), fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: .firstLast, disableAnimations: false, largeEmoji: false, chatBubbleCorners: PresentationChatBubbleCorners(mainRadius: 0.0, auxiliaryRadius: 0.0, mergeBubbleCorners: false)), context: context, chatLocation: .peer(id: peerId), interaction: ListMessageItemInteraction(controllerInteraction: interaction), message: message, selection: .none, displayHeader: true) @@ -104,7 +103,7 @@ private struct ChatHistorySearchContainerTransition { let displayingResults: Bool } -private func chatHistorySearchContainerPreparedTransition(from fromEntries: [ChatHistorySearchEntry], to toEntries: [ChatHistorySearchEntry], query: String, displayingResults: Bool, context: AccountContext, peerId: PeerId, interaction: ChatControllerInteraction) -> ChatHistorySearchContainerTransition { +private func chatHistorySearchContainerPreparedTransition(from fromEntries: [ChatHistorySearchEntry], to toEntries: [ChatHistorySearchEntry], query: String, displayingResults: Bool, context: AccountContext, peerId: EnginePeer.Id, interaction: ChatControllerInteraction) -> ChatHistorySearchContainerTransition { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } @@ -126,7 +125,7 @@ public final class ChatHistorySearchContainerNode: SearchDisplayControllerConten private var containerLayout: (ContainerViewLayout, CGFloat)? private var currentEntries: [ChatHistorySearchEntry]? - public var currentMessages: [MessageId: Message]? + public var currentMessages: [EngineMessage.Id: EngineRawMessage]? private var currentQuery: String? private let searchQuery = Promise() @@ -149,7 +148,7 @@ public final class ChatHistorySearchContainerNode: SearchDisplayControllerConten return true } - public init(context: AccountContext, peerId: PeerId, threadId: Int64?, tagMask: MessageTags, interfaceInteraction: ChatControllerInteraction) { + public init(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64?, tagMask: EngineMessage.Tags, interfaceInteraction: ChatControllerInteraction) { self.context = context let presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -194,14 +193,14 @@ public final class ChatHistorySearchContainerNode: SearchDisplayControllerConten self.searchQueryDisposable.set((self.searchQuery.get() |> deliverOnMainQueue).startStrict(next: { [weak self] query in if let strongSelf = self { - let signal: Signal<([ChatHistorySearchEntry], [MessageId: Message])?, NoError> + let signal: Signal<([ChatHistorySearchEntry], [EngineMessage.Id: EngineRawMessage])?, NoError> if let query = query, !query.isEmpty { - let foundRemoteMessages: Signal<[Message], NoError> = context.engine.messages.searchMessages(location: .peer(peerId: peerId, fromId: nil, tags: tagMask, reactions: nil, threadId: threadId, minDate: nil, maxDate: nil), query: query, state: nil) + let foundRemoteMessages: Signal<[EngineRawMessage], NoError> = context.engine.messages.searchMessages(location: .peer(peerId: peerId, fromId: nil, tags: tagMask, reactions: nil, threadId: threadId, minDate: nil, maxDate: nil), query: query, state: nil) |> map { $0.0.messages } |> delay(0.2, queue: Queue.concurrentDefaultQueue()) signal = combineLatest(foundRemoteMessages, themeAndStringsPromise.get()) - |> map { messages, themeAndStrings -> ([ChatHistorySearchEntry], [MessageId: Message])? in + |> map { messages, themeAndStrings -> ([ChatHistorySearchEntry], [EngineMessage.Id: EngineRawMessage])? in if messages.isEmpty { return ([], [:]) } else { @@ -377,7 +376,7 @@ public final class ChatHistorySearchContainerNode: SearchDisplayControllerConten } } - public func transitionNodeForGallery(messageId: MessageId, media: Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + public func transitionNodeForGallery(messageId: EngineMessage.Id, media: EngineRawMedia) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { var transitionNode: (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? self.listNode.forEachItemNode { itemNode in if let itemNode = itemNode as? ChatMessageItemView { diff --git a/submodules/TelegramUI/Components/Chat/ChatMediaInputStickerGridItem/BUILD b/submodules/TelegramUI/Components/Chat/ChatMediaInputStickerGridItem/BUILD index 9c809d2612..3804ac777b 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMediaInputStickerGridItem/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMediaInputStickerGridItem/BUILD @@ -14,7 +14,6 @@ swift_library( "//submodules/TelegramCore", "//submodules/SSignalKit/SwiftSignalKit", "//submodules/AsyncDisplayKit", - "//submodules/Postbox", "//submodules/TelegramPresentationData", "//submodules/StickerResources", "//submodules/AccountContext", diff --git a/submodules/TelegramUI/Components/Chat/ChatMediaInputStickerGridItem/Sources/ChatMediaInputStickerGridItem.swift b/submodules/TelegramUI/Components/Chat/ChatMediaInputStickerGridItem/Sources/ChatMediaInputStickerGridItem.swift index 8a888df6a5..4ce9960037 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMediaInputStickerGridItem/Sources/ChatMediaInputStickerGridItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMediaInputStickerGridItem/Sources/ChatMediaInputStickerGridItem.swift @@ -4,7 +4,6 @@ import Display import TelegramCore import SwiftSignalKit import AsyncDisplayKit -import Postbox import TelegramPresentationData import StickerResources import AccountContext @@ -21,7 +20,7 @@ public enum ChatMediaInputStickerGridSectionAccessory { } public final class ChatMediaInputStickerGridSection: GridSection { - public let collectionId: ItemCollectionId + public let collectionId: EngineItemCollectionId public let collectionInfo: StickerPackCollectionInfo? public let accessory: ChatMediaInputStickerGridSectionAccessory public let interaction: ChatMediaInputNodeInteraction @@ -32,7 +31,7 @@ public final class ChatMediaInputStickerGridSection: GridSection { return self.collectionId.hashValue } - public init(collectionId: ItemCollectionId, collectionInfo: StickerPackCollectionInfo?, accessory: ChatMediaInputStickerGridSectionAccessory, theme: PresentationTheme, interaction: ChatMediaInputNodeInteraction) { + public init(collectionId: EngineItemCollectionId, collectionInfo: StickerPackCollectionInfo?, accessory: ChatMediaInputStickerGridSectionAccessory, theme: PresentationTheme, interaction: ChatMediaInputNodeInteraction) { self.collectionId = collectionId self.collectionInfo = collectionInfo self.accessory = accessory @@ -118,7 +117,7 @@ public final class ChatMediaInputStickerGridSectionNode: ASDisplayNode { public final class ChatMediaInputStickerGridItem: GridItem { public let context: AccountContext - public let index: ItemCollectionViewEntryIndex + public let index: EngineItemCollectionViewEntryIndex public let stickerItem: StickerPackItem public let selected: () -> Void public let interfaceInteraction: ChatControllerInteraction? @@ -129,7 +128,7 @@ public final class ChatMediaInputStickerGridItem: GridItem { public let section: GridSection? - public init(context: AccountContext, collectionId: ItemCollectionId, stickerPackInfo: StickerPackCollectionInfo?, index: ItemCollectionViewEntryIndex, stickerItem: StickerPackItem, canManagePeerSpecificPack: Bool?, interfaceInteraction: ChatControllerInteraction?, inputNodeInteraction: ChatMediaInputNodeInteraction, hasAccessory: Bool, theme: PresentationTheme, large: Bool = false, isLocked: Bool = false, selected: @escaping () -> Void) { + public init(context: AccountContext, collectionId: EngineItemCollectionId, stickerPackInfo: StickerPackCollectionInfo?, index: EngineItemCollectionViewEntryIndex, stickerItem: StickerPackItem, canManagePeerSpecificPack: Bool?, interfaceInteraction: ChatControllerInteraction?, inputNodeInteraction: ChatMediaInputNodeInteraction, hasAccessory: Bool, theme: PresentationTheme, large: Bool = false, isLocked: Bool = false, selected: @escaping () -> Void) { self.context = context self.index = index self.stickerItem = stickerItem diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift index 72528395d0..6f923f5d50 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import AccountContext import TelegramPresentationData @@ -26,7 +25,7 @@ import ComponentFlow import ReactionSelectionNode import MultilineTextComponent -private func attributedServiceMessageString(theme: ChatPresentationThemeData, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: Message, messageCount: Int? = nil, accountPeerId: PeerId, forForumOverview: Bool) -> NSAttributedString? { +private func attributedServiceMessageString(theme: ChatPresentationThemeData, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: EngineRawMessage, messageCount: Int? = nil, accountPeerId: EnginePeer.Id, forForumOverview: Bool) -> NSAttributedString? { return universalServiceMessageString(presentationData: (theme.theme, theme.wallpaper), strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: EngineMessage(message), messageCount: messageCount, accountPeerId: accountPeerId, forChatList: false, forForumOverview: forForumOverview) } @@ -108,7 +107,7 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { super.didLoad() } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if let imageNode = self.imageNode, self.item?.message.id == messageId { return (imageNode, imageNode.bounds, { [weak self] in guard let strongSelf = self, let imageNode = strongSelf.imageNode else { @@ -137,9 +136,9 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { } } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { var mediaHidden = false - var currentMedia: Media? + var currentMedia: EngineRawMedia? if let item = item { mediaLoop: for media in item.message.media { if let media = media as? TelegramMediaAction { @@ -552,7 +551,7 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { strongSelf.mediaBackgroundNode.image = backgroundImage if let image = image, let video = image.videoRepresentations.last, let id = image.id?.id { - let videoFileReference = FileMediaReference.message(message: MessageReference(item.message), media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.resource, previewRepresentations: image.representations, videoThumbnails: [], immediateThumbnailData: image.immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.dimensions, flags: [], preloadSize: nil, coverTime: nil, videoCodec: nil)], alternativeRepresentations: [])) + let videoFileReference = FileMediaReference.message(message: MessageReference(item.message), media: TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.resource, previewRepresentations: image.representations, videoThumbnails: [], immediateThumbnailData: image.immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.dimensions, flags: [], preloadSize: nil, coverTime: nil, videoCodec: nil)], alternativeRepresentations: [])) let videoContent = NativeVideoContent(id: .profileVideo(id, "action"), userLocation: .peer(item.message.id.peerId), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, useLargeThumbnail: true, autoFetchFullSizeThumbnail: true, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear, storeAfterDownload: nil) if videoContent.id != strongSelf.videoContent?.id { let mediaManager = item.context.sharedContext.mediaManager diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/BUILD index 3869cfb7c9..1bd7f3cb75 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/AsyncDisplayKit", "//submodules/SSignalKit/SwiftSignalKit", "//submodules/Display", - "//submodules/Postbox", "//submodules/TelegramCore", "//submodules/TelegramUIPreferences", "//submodules/TelegramPresentationData", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift index 539164a44f..684c404552 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift @@ -2,7 +2,6 @@ import Foundation import UIKit import AsyncDisplayKit import Display -import Postbox import TelegramCore import TelegramUIPreferences import TelegramPresentationData @@ -144,14 +143,14 @@ public struct ChatMessageBubbleContentTapAction { case url(Url) case phone(String) case textMention(String) - case peerMention(peerId: PeerId, mention: String, openProfile: Bool) + case peerMention(peerId: EnginePeer.Id, mention: String, openProfile: Bool) case botCommand(String) case hashtag(String?, String) case instantPage case wallpaper case theme - case call(peerId: PeerId, isVideo: Bool) - case conferenceCall(message: Message) + case call(peerId: EnginePeer.Id, isVideo: Bool) + case conferenceCall(message: EngineRawMessage) case openMessage case timecode(Double, String) case tooltip(String, ASDisplayNode?, CGRect?) @@ -162,7 +161,7 @@ public struct ChatMessageBubbleContentTapAction { case date(Int32, String) case largeEmoji(String, String?, TelegramMediaFile) case customEmoji(TelegramMediaFile) - case externalInstantPage(url: Url, webpageId: MediaId, anchor: String?) + case externalInstantPage(url: Url, webpageId: EngineMedia.Id, anchor: String?) case custom(() -> Void) } @@ -182,8 +181,8 @@ public struct ChatMessageBubbleContentTapAction { public final class ChatMessageBubbleContentItem { public let context: AccountContext public let controllerInteraction: ChatControllerInteraction - public let message: Message - public let topMessage: Message + public let message: EngineRawMessage + public let topMessage: EngineRawMessage public let content: ChatMessageItemContent public let read: Bool public let chatLocation: ChatLocation @@ -193,7 +192,7 @@ public final class ChatMessageBubbleContentItem { public let isItemPinned: Bool public let isItemEdited: Bool - public init(context: AccountContext, controllerInteraction: ChatControllerInteraction, message: Message, topMessage: Message, content: ChatMessageItemContent, read: Bool, chatLocation: ChatLocation, presentationData: ChatPresentationData, associatedData: ChatMessageItemAssociatedData, attributes: ChatMessageEntryAttributes, isItemPinned: Bool, isItemEdited: Bool) { + public init(context: AccountContext, controllerInteraction: ChatControllerInteraction, message: EngineRawMessage, topMessage: EngineRawMessage, content: ChatMessageItemContent, read: Bool, chatLocation: ChatLocation, presentationData: ChatPresentationData, associatedData: ChatMessageItemAssociatedData, attributes: ChatMessageEntryAttributes, isItemPinned: Bool, isItemEdited: Bool) { self.context = context self.controllerInteraction = controllerInteraction self.message = message @@ -258,7 +257,7 @@ open class ChatMessageBubbleContentNode: ASDisplayNode { }) } - open func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + open func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { return nil } @@ -266,11 +265,11 @@ open class ChatMessageBubbleContentNode: ASDisplayNode { return nil } - open func updateHiddenMedia(_ media: [Media]?) -> Bool { + open func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { return false } - open func updateSearchTextHighlightState(text: String?, messages: [MessageIndex]?) { + open func updateSearchTextHighlightState(text: String?, messages: [EngineMessage.Index]?) { } open func updateAutomaticMediaDownloadSettings(_ settings: MediaAutoDownloadSettings) { @@ -317,7 +316,7 @@ open class ChatMessageBubbleContentNode: ASDisplayNode { return nil } - open func targetForStoryTransition(id: StoryId) -> UIView? { + open func targetForStoryTransition(id: EngineStoryId) -> UIView? { return nil } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageCommentFooterContentNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageCommentFooterContentNode/BUILD index 488db161a5..f50ac6e3b5 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageCommentFooterContentNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageCommentFooterContentNode/BUILD @@ -10,7 +10,6 @@ swift_library( "-warnings-as-errors", ], deps = [ - "//submodules/Postbox", "//submodules/Display", "//submodules/AsyncDisplayKit", "//submodules/SSignalKit/SwiftSignalKit", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousDescriptionContentNode/Sources/ChatMessageEventLogPreviousDescriptionContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousDescriptionContentNode/Sources/ChatMessageEventLogPreviousDescriptionContentNode.swift index d17580bb8f..ae9d2538c0 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousDescriptionContentNode/Sources/ChatMessageEventLogPreviousDescriptionContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousDescriptionContentNode/Sources/ChatMessageEventLogPreviousDescriptionContentNode.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import Display import AsyncDisplayKit import SwiftSignalKit @@ -50,7 +49,7 @@ public final class ChatMessageEventLogPreviousDescriptionContentNode: ChatMessag } else { text = item.message.text } - let mediaAndFlags: ([Media], ChatMessageAttachedContentNodeMediaFlags)? = nil + let mediaAndFlags: ([EngineRawMedia], ChatMessageAttachedContentNodeMediaFlags)? = nil let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, true, .peer(id: item.message.id.peerId), title, nil, nil, text, messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize, item.controllerInteraction.presentationContext.animationCache, item.controllerInteraction.presentationContext.animationRenderer) @@ -103,11 +102,11 @@ public final class ChatMessageEventLogPreviousDescriptionContentNode: ChatMessag return ChatMessageBubbleContentTapAction(content: .none) } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { return self.contentNode.updateHiddenMedia(media) } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id != messageId { return nil } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousLinkContentNode/Sources/ChatMessageEventLogPreviousLinkContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousLinkContentNode/Sources/ChatMessageEventLogPreviousLinkContentNode.swift index 0b420f0c7f..202bca13b2 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousLinkContentNode/Sources/ChatMessageEventLogPreviousLinkContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousLinkContentNode/Sources/ChatMessageEventLogPreviousLinkContentNode.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import Display import AsyncDisplayKit import SwiftSignalKit @@ -45,7 +44,7 @@ public final class ChatMessageEventLogPreviousLinkContentNode: ChatMessageBubble let title: String = item.message.text.contains("\n") ? item.presentationData.strings.Channel_AdminLog_MessagePreviousLinks : item.presentationData.strings.Channel_AdminLog_MessagePreviousLink let text: String = item.message.text - let mediaAndFlags: ([Media], ChatMessageAttachedContentNodeMediaFlags)? = nil + let mediaAndFlags: ([EngineRawMedia], ChatMessageAttachedContentNodeMediaFlags)? = nil let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, true, .peer(id: item.message.id.peerId), title, nil, nil, text, messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize, item.controllerInteraction.presentationContext.animationCache, item.controllerInteraction.presentationContext.animationRenderer) @@ -98,11 +97,11 @@ public final class ChatMessageEventLogPreviousLinkContentNode: ChatMessageBubble return ChatMessageBubbleContentTapAction(content: .none) } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { return self.contentNode.updateHiddenMedia(media) } - - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id != messageId { return nil } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousMessageContentNode/Sources/ChatMessageEventLogPreviousMessageContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousMessageContentNode/Sources/ChatMessageEventLogPreviousMessageContentNode.swift index d3ec9d1355..773b6c1849 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousMessageContentNode/Sources/ChatMessageEventLogPreviousMessageContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousMessageContentNode/Sources/ChatMessageEventLogPreviousMessageContentNode.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import Display import AsyncDisplayKit import SwiftSignalKit @@ -50,7 +49,7 @@ public final class ChatMessageEventLogPreviousMessageContentNode: ChatMessageBub } else { text = item.message.text } - let mediaAndFlags: ([Media], ChatMessageAttachedContentNodeMediaFlags)? = nil + let mediaAndFlags: ([EngineRawMedia], ChatMessageAttachedContentNodeMediaFlags)? = nil let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, true, .peer(id: item.message.id.peerId), title, nil, nil, text, messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize, item.controllerInteraction.presentationContext.animationCache, item.controllerInteraction.presentationContext.animationRenderer) @@ -105,11 +104,11 @@ public final class ChatMessageEventLogPreviousMessageContentNode: ChatMessageBub self.contentNode.updateTouchesAtPoint(point.flatMap { $0.offsetBy(dx: -contentNodeFrame.minX, dy: -contentNodeFrame.minY) }) } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { return self.contentNode.updateHiddenMedia(media) } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id != messageId { return nil } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageFileBubbleContentNode/Sources/ChatMessageFileBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageFileBubbleContentNode/Sources/ChatMessageFileBubbleContentNode.swift index 1aebf306db..877c143a8c 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageFileBubbleContentNode/Sources/ChatMessageFileBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageFileBubbleContentNode/Sources/ChatMessageFileBubbleContentNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import TelegramUIPreferences import ComponentFlow @@ -201,7 +200,7 @@ public class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode { } } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id == messageId { return self.interactiveFileNode.transitionNode(media: media) } else { @@ -209,7 +208,7 @@ public class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode { } } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { return self.interactiveFileNode.updateHiddenMedia(media) } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageGameBubbleContentNode/Sources/ChatMessageGameBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageGameBubbleContentNode/Sources/ChatMessageGameBubbleContentNode.swift index 647345b103..ca722d6fde 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageGameBubbleContentNode/Sources/ChatMessageGameBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageGameBubbleContentNode/Sources/ChatMessageGameBubbleContentNode.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import Display import AsyncDisplayKit import SwiftSignalKit @@ -67,7 +66,7 @@ public final class ChatMessageGameBubbleContentNode: ChatMessageBubbleContentNod var title: String? var text: String? - var mediaAndFlags: ([Media], ChatMessageAttachedContentNodeMediaFlags)? + var mediaAndFlags: ([EngineRawMedia], ChatMessageAttachedContentNodeMediaFlags)? if let game = game { title = game.title @@ -132,11 +131,11 @@ public final class ChatMessageGameBubbleContentNode: ChatMessageBubbleContentNod return ChatMessageBubbleContentTapAction(content: .none) } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { return self.contentNode.updateHiddenMedia(media) } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id != messageId { return nil } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoBubbleContentNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoBubbleContentNode/BUILD index becb2bbd06..5ec7467b05 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoBubbleContentNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoBubbleContentNode/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/AsyncDisplayKit", "//submodules/Display", "//submodules/SSignalKit/SwiftSignalKit", - "//submodules/Postbox", "//submodules/TelegramCore", "//submodules/TelegramUIPreferences", "//submodules/ComponentFlow", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoBubbleContentNode/Sources/ChatMessageInstantVideoBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoBubbleContentNode/Sources/ChatMessageInstantVideoBubbleContentNode.swift index 0b9936d978..1b6e4b11d6 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoBubbleContentNode/Sources/ChatMessageInstantVideoBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoBubbleContentNode/Sources/ChatMessageInstantVideoBubbleContentNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import TelegramUIPreferences import ComponentFlow @@ -393,11 +392,11 @@ public class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentN } } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { return nil } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { return false } @@ -465,7 +464,7 @@ public class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentN return nil } - override public func targetForStoryTransition(id: StoryId) -> UIView? { + override public func targetForStoryTransition(id: EngineStoryId) -> UIView? { return self.interactiveVideoNode.targetForStoryTransition(id: id) } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/BUILD index 5716eabe19..1dd6a7760c 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/AsyncDisplayKit", "//submodules/Display", "//submodules/SSignalKit/SwiftSignalKit", - "//submodules/Postbox", "//submodules/TelegramCore", "//submodules/TelegramPresentationData", "//submodules/TelegramUIPreferences", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift index 2e3e9876cf..f8c3faf696 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences @@ -48,7 +47,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, ASGestureReco public var appliedParams: ListViewItemLayoutParams? public var appliedItem: ChatMessageItem? - public var appliedForwardInfo: (Peer?, String?)? + public var appliedForwardInfo: (EngineRawPeer?, String?)? public var appliedHasAvatar = false public var appliedCurrentlyPlaying: Bool? public var appliedAutomaticDownload = false @@ -461,11 +460,11 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, ASGestureReco } } - var replyMessage: Message? + var replyMessage: EngineRawMessage? var replyForward: QuotedReplyMessageAttribute? var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)? var replyInnerSubject: EngineMessageReplyInnerSubject? - var replyStory: StoryId? + var replyStory: EngineStoryId? for attribute in item.message.attributes { if let attribute = attribute as? InlineBotMessageAttribute { var inlineBotNameString: String? @@ -551,7 +550,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, ASGestureReco let availableContentWidth = params.width - params.leftInset - params.rightInset - layoutConstants.bubble.edgeInset * 2.0 - avatarInset - layoutConstants.bubble.contentInsets.left - var forwardSource: Peer? + var forwardSource: EngineRawPeer? var forwardAuthorSignature: String? var forwardInfoSizeApply: (CGSize, (CGFloat) -> ChatMessageForwardInfoNode)? @@ -1513,7 +1512,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, ASGestureReco return nil } - override public func targetForStoryTransition(id: StoryId) -> UIView? { + override public func targetForStoryTransition(id: EngineStoryId) -> UIView? { guard let item = self.item else { return nil } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageInvoiceBubbleContentNode/Sources/ChatMessageInvoiceBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageInvoiceBubbleContentNode/Sources/ChatMessageInvoiceBubbleContentNode.swift index 02855854c9..e6034a6550 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageInvoiceBubbleContentNode/Sources/ChatMessageInvoiceBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageInvoiceBubbleContentNode/Sources/ChatMessageInvoiceBubbleContentNode.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import Display import AsyncDisplayKit import SwiftSignalKit @@ -52,7 +51,7 @@ public final class ChatMessageInvoiceBubbleContentNode: ChatMessageBubbleContent var title: String? var subtitle: NSAttributedString? = nil var text: String? - var mediaAndFlags: ([Media], ChatMessageAttachedContentNodeMediaFlags)? + var mediaAndFlags: ([EngineRawMedia], ChatMessageAttachedContentNodeMediaFlags)? var automaticDownloadSettings = item.controllerInteraction.automaticMediaDownloadSettings if let invoice = invoice { @@ -128,11 +127,11 @@ public final class ChatMessageInvoiceBubbleContentNode: ChatMessageBubbleContent return ChatMessageBubbleContentTapAction(content: .none) } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { return self.contentNode.updateHiddenMedia(media) } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id != messageId { return nil } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItem/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageItem/BUILD index 8c82069452..df02b6c4ad 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItem/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItem/BUILD @@ -10,7 +10,6 @@ swift_library( "-warnings-as-errors", ], deps = [ - "//submodules/Postbox", "//submodules/AsyncDisplayKit", "//submodules/Display", "//submodules/SSignalKit/SwiftSignalKit", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItem/Sources/ChatMessageItem.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItem/Sources/ChatMessageItem.swift index f736e8cbee..67ae7c2ef2 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItem/Sources/ChatMessageItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItem/Sources/ChatMessageItem.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import AsyncDisplayKit import Display import SwiftSignalKit @@ -12,10 +11,10 @@ import TelegramPresentationData import ChatMessageItemCommon public enum ChatMessageItemContent: Sequence { - case message(message: Message, read: Bool, selection: ChatHistoryMessageSelection, attributes: ChatMessageEntryAttributes, location: MessageHistoryEntryLocation?) - case group(messages: [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes, MessageHistoryEntryLocation?)]) - - public func effectivelyIncoming(_ accountPeerId: PeerId, associatedData: ChatMessageItemAssociatedData? = nil) -> Bool { + case message(message: EngineRawMessage, read: Bool, selection: ChatHistoryMessageSelection, attributes: ChatMessageEntryAttributes, location: EngineMessageHistoryEntryLocation?) + case group(messages: [(EngineRawMessage, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes, EngineMessageHistoryEntryLocation?)]) + + public func effectivelyIncoming(_ accountPeerId: EnginePeer.Id, associatedData: ChatMessageItemAssociatedData? = nil) -> Bool { if let subject = associatedData?.subject, case let .messageOptions(_, _, info) = subject { if case .forward = info { return false @@ -31,7 +30,7 @@ public enum ChatMessageItemContent: Sequence { } } - public var index: MessageIndex { + public var index: EngineMessage.Index { switch self { case let .message(message, _, _, _, _): return message.index @@ -40,7 +39,7 @@ public enum ChatMessageItemContent: Sequence { } } - public var firstMessage: Message { + public var firstMessage: EngineRawMessage { switch self { case let .message(message, _, _, _, _): return message @@ -58,9 +57,9 @@ public enum ChatMessageItemContent: Sequence { } } - public func makeIterator() -> AnyIterator<(Message, ChatMessageEntryAttributes)> { + public func makeIterator() -> AnyIterator<(EngineRawMessage, ChatMessageEntryAttributes)> { var index = 0 - return AnyIterator { () -> (Message, ChatMessageEntryAttributes)? in + return AnyIterator { () -> (EngineRawMessage, ChatMessageEntryAttributes)? in switch self { case let .message(message, _, _, attributes, _): if index == 0 { @@ -84,10 +83,10 @@ public enum ChatMessageItemContent: Sequence { } public enum ChatMessageItemAdditionalContent { - case eventLogPreviousMessage(Message) - case eventLogPreviousDescription(Message) - case eventLogPreviousLink(Message) - case eventLogGroupedMessages([Message], Bool) + case eventLogPreviousMessage(EngineRawMessage) + case eventLogPreviousDescription(EngineRawMessage) + case eventLogPreviousLink(EngineRawMessage) + case eventLogGroupedMessages([EngineRawMessage], Bool) } public enum ChatMessageMerge: Int32 { @@ -131,12 +130,12 @@ public protocol ChatMessageItem: ListViewItem { var controllerInteraction: ChatControllerInteraction { get } var content: ChatMessageItemContent { get } var disableDate: Bool { get } - var effectiveAuthorId: PeerId? { get } + var effectiveAuthorId: EnginePeer.Id? { get } var additionalContent: ChatMessageItemAdditionalContent? { get } var headers: [ListViewItemHeader] { get } - var message: Message { get } + var message: EngineRawMessage { get } var read: Bool { get } var unsent: Bool { get } var sending: Bool { get } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift index f8c40ccc3d..da8399997d 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import AsyncDisplayKit import Display import SwiftSignalKit @@ -18,7 +17,7 @@ import ChatMessageStickerItemNode import ChatMessageAnimatedStickerItemNode import ChatMessageBubbleItemNode -private func mediaMergeableStyle(_ media: Media) -> ChatMessageMerge { +private func mediaMergeableStyle(_ media: EngineRawMedia) -> ChatMessageMerge { if let story = media as? TelegramMediaStory, story.isMention { return .none } @@ -47,9 +46,9 @@ private func mediaMergeableStyle(_ media: Media) -> ChatMessageMerge { return .fullyMerged } -private func messagesShouldBeMerged(accountPeerId: PeerId, _ lhs: Message, _ rhs: Message) -> ChatMessageMerge { - var lhsEffectiveAuthor: Peer? = lhs.author - var rhsEffectiveAuthor: Peer? = rhs.author +private func messagesShouldBeMerged(accountPeerId: EnginePeer.Id, _ lhs: EngineRawMessage, _ rhs: EngineRawMessage) -> ChatMessageMerge { + var lhsEffectiveAuthor: EngineRawPeer? = lhs.author + var rhsEffectiveAuthor: EngineRawPeer? = rhs.author for attribute in lhs.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { lhsEffectiveAuthor = lhs.peers[attribute.messageId.peerId] @@ -223,7 +222,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible public let controllerInteraction: ChatControllerInteraction public let content: ChatMessageItemContent public let disableDate: Bool - public let effectiveAuthorId: PeerId? + public let effectiveAuthorId: EnginePeer.Id? public let additionalContent: ChatMessageItemAdditionalContent? let dateHeader: ChatMessageDateHeader @@ -232,7 +231,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible public let headers: [ListViewItemHeader] - public var message: Message { + public var message: EngineRawMessage { switch self.content { case let .message(message, _, _, _, _): return message @@ -299,10 +298,10 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible var avatarHeader: ChatMessageAvatarHeader? let incoming = content.effectivelyIncoming(self.context.account.peerId) - var effectiveAuthor: Peer? + var effectiveAuthor: EngineRawPeer? var displayAuthorInfo: Bool - let messagePeerId: PeerId = chatLocation.peerId ?? content.firstMessage.id.peerId + let messagePeerId: EnginePeer.Id = chatLocation.peerId ?? content.firstMessage.id.peerId var headerSeparableThreadId: Int64? var headerDisplayPeer: ChatMessageDateHeader.HeaderData? @@ -312,14 +311,14 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible if let forwardInfo = content.firstMessage.forwardInfo { effectiveAuthor = forwardInfo.author if effectiveAuthor == nil, let authorSignature = forwardInfo.authorSignature { - effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) + effectiveAuthor = TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.Empty, id: EnginePeer.Id.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) } } if let sourceAuthorInfo = content.firstMessage.sourceAuthorInfo { if let originalAuthor = sourceAuthorInfo.originalAuthor, let peer = content.firstMessage.peers[originalAuthor] { effectiveAuthor = peer } else if let authorSignature = sourceAuthorInfo.originalAuthorName { - effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) + effectiveAuthor = TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.Empty, id: EnginePeer.Id.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) } } if peerId.isVerificationCodes && effectiveAuthor == nil { @@ -360,7 +359,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible headerDisplayPeer = ChatMessageDateHeader.HeaderData(contents: .thread(id: threadId, info: threadInfo)) } else if content.firstMessage.threadId == EngineMessage.newTopicThreadId { headerSeparableThreadId = content.firstMessage.threadId - headerDisplayPeer = ChatMessageDateHeader.HeaderData(contents: .thread(id: threadId, info: Message.AssociatedThreadInfo( + headerDisplayPeer = ChatMessageDateHeader.HeaderData(contents: .thread(id: threadId, info: EngineRawMessage.AssociatedThreadInfo( title: presentationData.strings.Chat_MessageHeaderBotNewThread, icon: nil, iconColor: 0, @@ -434,7 +433,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible if hasAvatar { if let effectiveAuthor = effectiveAuthor { - var storyStats: PeerStoryStats? + var storyStats: EnginePeerStoryStats? if case .peer(id: context.account.peerId) = chatLocation { } else { switch content { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemView/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageItemView/BUILD index e935774197..eba7dfef21 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemView/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemView/BUILD @@ -12,7 +12,6 @@ swift_library( deps = [ "//submodules/AsyncDisplayKit", "//submodules/Display", - "//submodules/Postbox", "//submodules/TelegramCore", "//submodules/AccountContext", "//submodules/LocalizedPeerData", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift index 5ab0030bb4..828078334e 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift @@ -2,7 +2,6 @@ import Foundation import UIKit import AsyncDisplayKit import Display -import Postbox import TelegramCore import AccountContext import LocalizedPeerData @@ -105,7 +104,7 @@ public final class ChatMessageAccessibilityData { } } - let dataForMessage: (Message, Bool) -> (String, String) = { message, isReply -> (String, String) in + let dataForMessage: (EngineRawMessage, Bool) -> (String, String) = { message, isReply -> (String, String) in var label: String = "" var value: String = "" @@ -634,12 +633,12 @@ public enum InternalBubbleTapAction { } public struct OpenContextMenu { - public var tapMessage: Message + public var tapMessage: EngineRawMessage public var selectAll: Bool public var subFrame: CGRect public var disableDefaultPressAnimation: Bool - public init(tapMessage: Message, selectAll: Bool, subFrame: CGRect, disableDefaultPressAnimation: Bool = false) { + public init(tapMessage: EngineRawMessage, selectAll: Bool, subFrame: CGRect, disableDefaultPressAnimation: Bool = false) { self.tapMessage = tapMessage self.selectAll = selectAll self.subFrame = subFrame @@ -727,7 +726,7 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { } } - public func matchesMessage(id: MessageId) -> Bool { + public func matchesMessage(id: EngineMessage.Id) -> Bool { if let item = self.item { for (message, _) in item.content { if message.id == id { @@ -738,18 +737,18 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { return false } - public func messages() -> [Message] { + public func messages() -> [EngineRawMessage] { guard let item = self.item else { return [] } - var messages: [Message] = [] + var messages: [EngineRawMessage] = [] for (message, _) in item.content { messages.append(message) } return messages } - open func transitionNode(id: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + open func transitionNode(id: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { return nil } @@ -828,7 +827,7 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { case let .callback(requiresPassword, data): item.controllerInteraction.requestMessageActionCallback(item.message, data, false, requiresPassword, progress) case let .switchInline(samePeer, query, peerTypes): - var botPeer: Peer? + var botPeer: EngineRawPeer? var found = false for attribute in item.message.attributes { @@ -843,7 +842,7 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { botPeer = item.message.author } - var peerId: PeerId? + var peerId: EnginePeer.Id? if samePeer { peerId = item.message.id.peerId } @@ -895,7 +894,7 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { return nil } - open func targetForStoryTransition(id: StoryId) -> UIView? { + open func targetForStoryTransition(id: EngineStoryId) -> UIView? { return nil } @@ -995,7 +994,7 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { return nil } - private func playEffectAnimation(resource: MediaResource) { + private func playEffectAnimation(resource: EngineRawMediaResource) { guard let item = self.item else { return } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageJoinedChannelBubbleContentNode/Sources/ChatMessageJoinedChannelBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageJoinedChannelBubbleContentNode/Sources/ChatMessageJoinedChannelBubbleContentNode.swift index d769f7231b..86131766f1 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageJoinedChannelBubbleContentNode/Sources/ChatMessageJoinedChannelBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageJoinedChannelBubbleContentNode/Sources/ChatMessageJoinedChannelBubbleContentNode.swift @@ -337,7 +337,7 @@ public class ChatMessageJoinedChannelBubbleContentNode: ChatMessageBubbleContent jsonString += "}" if let data = jsonString.data(using: .utf8), let json = JSON(data: data) { - addAppLogEvent(postbox: item.context.account.postbox, type: "channels.open_recommended_channel", data: json) + item.context.engine.accountData.addAppLogEvent(type: "channels.open_recommended_channel", data: json) } item.controllerInteraction.openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) } else { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageMapBubbleContentNode/Sources/ChatMessageMapBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageMapBubbleContentNode/Sources/ChatMessageMapBubbleContentNode.swift index 53993ce16c..e66c17d057 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageMapBubbleContentNode/Sources/ChatMessageMapBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageMapBubbleContentNode/Sources/ChatMessageMapBubbleContentNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import LiveLocationTimerNode import PhotoResources @@ -505,7 +504,7 @@ public class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode { self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false) } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id == messageId, let currentMedia = self.media, currentMedia.isEqual(to: media) { let imageNode = self.imageNode return (self.imageNode, self.imageNode.bounds, { [weak imageNode] in @@ -515,7 +514,7 @@ public class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode { return nil } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { var mediaHidden = false if let currentMedia = self.media, let media = media { for item in media { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageMediaBubbleContentNode/Sources/ChatMessageMediaBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageMediaBubbleContentNode/Sources/ChatMessageMediaBubbleContentNode.swift index fa752abe2d..21feda7d24 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageMediaBubbleContentNode/Sources/ChatMessageMediaBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageMediaBubbleContentNode/Sources/ChatMessageMediaBubbleContentNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import TelegramUIPreferences import TelegramPresentationData @@ -27,7 +26,7 @@ public class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { private var selectionNode: GridMessageSelectionNode? private var highlightedState: Bool = false - private var media: Media? + private var media: EngineRawMedia? private var mediaIndex: Int? private var automaticPlayback: Bool? @@ -116,7 +115,7 @@ public class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { let interactiveImageLayout = self.interactiveImageNode.asyncLayout() return { item, layoutConstants, preparePosition, selection, constrainedSize, _ in - var selectedMedia: Media? + var selectedMedia: EngineRawMedia? var selectedMediaIndex: Int? var extendedMedia: TelegramExtendedMedia? var automaticDownload: InteractiveMediaNodeAutodownloadMode = .none @@ -512,7 +511,7 @@ public class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { } } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id == messageId, var currentMedia = self.media { if let invoice = currentMedia as? TelegramMediaInvoice, let extendedMedia = invoice.extendedMedia, case let .full(fullMedia) = extendedMedia { currentMedia = fullMedia @@ -527,7 +526,7 @@ public class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { return nil } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { var mediaHidden = false var currentMedia = self.media diff --git a/submodules/TelegramUI/Components/Chat/ChatMessagePollBubbleContentNode/Sources/ChatMessageQuizAnswerBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessagePollBubbleContentNode/Sources/ChatMessageQuizAnswerBubbleContentNode.swift index 72d3794fbb..1573119fe6 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessagePollBubbleContentNode/Sources/ChatMessageQuizAnswerBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessagePollBubbleContentNode/Sources/ChatMessageQuizAnswerBubbleContentNode.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import Display import AsyncDisplayKit import SwiftSignalKit @@ -48,7 +47,7 @@ public final class ChatMessageQuizAnswerBubbleContentNode: ChatMessageBubbleCont let title: String = item.presentationData.strings.MessagePoll_Explanation var text: String = "" var entities: [MessageTextEntity] = [] - var mediaAndFlags: ([Media], ChatMessageAttachedContentNodeMediaFlags)? = nil + var mediaAndFlags: ([EngineRawMedia], ChatMessageAttachedContentNodeMediaFlags)? = nil var solution: TelegramMediaPollResults.Solution? if let poll = item.message.media.first(where: { $0 is TelegramMediaPoll }) as? TelegramMediaPoll, let solutionValue = poll.results.solution { text = solutionValue.text @@ -124,11 +123,11 @@ public final class ChatMessageQuizAnswerBubbleContentNode: ChatMessageBubbleCont self.contentNode.updateTouchesAtPoint(point.flatMap { $0.offsetBy(dx: -contentNodeFrame.minX, dy: -contentNodeFrame.minY) }) } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { return self.contentNode.updateHiddenMedia(media) } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id != messageId { return nil } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageProfilePhotoSuggestionContentNode/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageProfilePhotoSuggestionContentNode/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift index 11008ec607..04a68ef4f5 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageProfilePhotoSuggestionContentNode/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageProfilePhotoSuggestionContentNode/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import AccountContext import TelegramPresentationData @@ -95,7 +94,7 @@ public class ChatMessageProfilePhotoSuggestionContentNode: ChatMessageBubbleCont self.fetchDisposable.dispose() } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id == messageId { return (self.imageNode, self.imageNode.bounds, { [weak self] in guard let strongSelf = self else { @@ -110,9 +109,9 @@ public class ChatMessageProfilePhotoSuggestionContentNode: ChatMessageBubbleCont } } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { var mediaHidden = false - var currentMedia: Media? + var currentMedia: EngineRawMedia? if let item = item { mediaLoop: for media in item.message.media { if let media = media as? TelegramMediaAction { @@ -218,7 +217,7 @@ public class ChatMessageProfilePhotoSuggestionContentNode: ChatMessageBubbleCont } if let photo = photo, let video = photo.videoRepresentations.last, let id = photo.id?.id { - let videoFileReference = FileMediaReference.message(message: MessageReference(item.message), media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.resource, previewRepresentations: photo.representations, videoThumbnails: [], immediateThumbnailData: photo.immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.dimensions, flags: [], preloadSize: nil, coverTime: nil, videoCodec: nil)], alternativeRepresentations: [])) + let videoFileReference = FileMediaReference.message(message: MessageReference(item.message), media: TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.resource, previewRepresentations: photo.representations, videoThumbnails: [], immediateThumbnailData: photo.immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.dimensions, flags: [], preloadSize: nil, coverTime: nil, videoCodec: nil)], alternativeRepresentations: [])) let videoContent = NativeVideoContent(id: .profileVideo(id, "action"), userLocation: .peer(item.message.id.peerId), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, useLargeThumbnail: true, autoFetchFullSizeThumbnail: true, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear, storeAfterDownload: nil) if videoContent.id != strongSelf.videoContent?.id { let mediaManager = item.context.sharedContext.mediaManager diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/BUILD index 9c5a9df3aa..7acafa371c 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/BUILD @@ -11,7 +11,6 @@ swift_library( ], deps = [ "//submodules/AsyncDisplayKit", - "//submodules/Postbox", "//submodules/Display", "//submodules/TelegramCore", "//submodules/SSignalKit/SwiftSignalKit", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift index 29a4cda102..4aef7b4f1e 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift @@ -1,7 +1,6 @@ import Foundation import UIKit import AsyncDisplayKit -import Postbox import Display import TelegramCore import SwiftSignalKit @@ -80,13 +79,13 @@ public class ChatMessageReplyInfoNode: ASDisplayNode { public let strings: PresentationStrings public let context: AccountContext public let type: ChatMessageReplyInfoType - public let message: Message? + public let message: EngineRawMessage? public let replyForward: QuotedReplyMessageAttribute? public let quote: (quote: EngineMessageReplyQuote, isQuote: Bool)? public let innerSubject: EngineMessageReplyInnerSubject? - public let story: StoryId? + public let story: EngineStoryId? public let isSummarized: Bool - public let parentMessage: Message + public let parentMessage: EngineRawMessage public let constrainedSize: CGSize public let animationCache: AnimationCache? public let animationRenderer: MultiAnimationRenderer? @@ -97,13 +96,13 @@ public class ChatMessageReplyInfoNode: ASDisplayNode { strings: PresentationStrings, context: AccountContext, type: ChatMessageReplyInfoType, - message: Message?, + message: EngineRawMessage?, replyForward: QuotedReplyMessageAttribute?, quote: (quote: EngineMessageReplyQuote, isQuote: Bool)?, innerSubject: EngineMessageReplyInnerSubject?, - story: StoryId?, + story: EngineStoryId?, isSummarized: Bool, - parentMessage: Message, + parentMessage: EngineRawMessage, constrainedSize: CGSize, animationCache: AnimationCache?, animationRenderer: MultiAnimationRenderer?, @@ -222,7 +221,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode { if let peer = forwardInfo.author { author = peer } else if let authorSignature = forwardInfo.authorSignature { - author = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) + author = TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.Empty, id: EnginePeer.Id.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil) } } @@ -903,7 +902,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode { pattern = MessageInlineBlockBackgroundView.Pattern( context: arguments.context, fileId: backgroundEmojiId, - file: arguments.parentMessage.associatedMedia[MediaId( + file: arguments.parentMessage.associatedMedia[EngineMedia.Id( namespace: Namespaces.Media.CloudFile, id: backgroundEmojiId )] as? TelegramMediaFile, diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/BUILD index 0615ab5b69..bbc0db7fde 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/AsyncDisplayKit", "//submodules/Display", "//submodules/TelegramCore", - "//submodules/Postbox", "//submodules/SSignalKit/SwiftSignalKit", "//submodules/AccountContext", "//submodules/InstantPageUI", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/Sources/ChatMessageRichDataBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/Sources/ChatMessageRichDataBubbleContentNode.swift index 599bf566ba..f1e0efe887 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/Sources/ChatMessageRichDataBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/Sources/ChatMessageRichDataBubbleContentNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import TelegramCore -import Postbox import SwiftSignalKit import AccountContext import ChatMessageBubbleContentNode @@ -697,7 +696,7 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode } } - override public func updateSearchTextHighlightState(text: String?, messages: [MessageIndex]?) { + override public func updateSearchTextHighlightState(text: String?, messages: [EngineMessage.Index]?) { } override public func willUpdateIsExtractedToContextPreview(_ value: Bool) { @@ -779,7 +778,7 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode self.textSelectionNode = textSelectionNode } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { guard let item = self.item, item.message.id == messageId else { return nil } @@ -797,7 +796,7 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode return nil } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { var hiddenMedia: InstantPageMedia? if let media, !media.isEmpty, let layout = self.currentPageLayout?.layout { for raw in media { @@ -813,7 +812,7 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode return hiddenMedia != nil } - private func findInstantPageMedia(in items: [InstantPageItem], mediaId: MediaId) -> InstantPageMedia? { + private func findInstantPageMedia(in items: [InstantPageItem], mediaId: EngineMedia.Id) -> InstantPageMedia? { for item in items { if let detailsItem = item as? InstantPageDetailsItem { if let found = self.findInstantPageMedia(in: detailsItem.items, mediaId: mediaId) { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/BUILD index 93400be766..1c4c39b41e 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/AsyncDisplayKit", "//submodules/Display", "//submodules/SSignalKit/SwiftSignalKit", - "//submodules/Postbox", "//submodules/TelegramCore", "//submodules/TelegramPresentationData", "//submodules/TextFormat", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift index b43b5d001e..bcd759a779 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import TelegramPresentationData import TextFormat @@ -75,7 +74,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { private var replyRecognizer: ChatSwipeToReplyRecognizer? private var currentSwipeAction: ChatControllerInteractionSwipeAction? - private var appliedForwardInfo: (Peer?, String?)? + private var appliedForwardInfo: (EngineRawPeer?, String?)? private var enableSynchronousImageApply: Bool = false @@ -703,11 +702,11 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { } } - var replyMessage: Message? + var replyMessage: EngineRawMessage? var replyForward: QuotedReplyMessageAttribute? var replyQuote: (quote: EngineMessageReplyQuote, isQuote: Bool)? var replyInnerSubject: EngineMessageReplyInnerSubject? - var replyStory: StoryId? + var replyStory: EngineStoryId? for attribute in item.message.attributes { if let attribute = attribute as? InlineBotMessageAttribute { var inlineBotNameString: String? @@ -811,7 +810,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { let contentHeight = max(imageSize.height, layoutConstants.image.minDimensions.height) - var forwardSource: Peer? + var forwardSource: EngineRawPeer? var forwardAuthorSignature: String? var forwardPsaType: String? @@ -867,13 +866,13 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { } var buttonDeclineValue: UInt8 = 0 - let buttonDecline = MemoryBuffer(data: Data(bytes: &buttonDeclineValue, count: 1)) + let buttonDecline = EngineMemoryBuffer(data: Data(bytes: &buttonDeclineValue, count: 1)) var buttonApproveValue: UInt8 = 1 - let buttonApprove = MemoryBuffer(data: Data(bytes: &buttonApproveValue, count: 1)) + let buttonApprove = EngineMemoryBuffer(data: Data(bytes: &buttonApproveValue, count: 1)) var buttonSuggestChangesValue: UInt8 = 2 - let buttonSuggestChanges = MemoryBuffer(data: Data(bytes: &buttonSuggestChangesValue, count: 1)) - - let customInfos: [MemoryBuffer: ChatMessageActionButtonsNode.CustomInfo] = [ + let buttonSuggestChanges = EngineMemoryBuffer(data: Data(bytes: &buttonSuggestChangesValue, count: 1)) + + let customInfos: [EngineMemoryBuffer: ChatMessageActionButtonsNode.CustomInfo] = [ buttonDecline: ChatMessageActionButtonsNode.CustomInfo( isEnabled: true, icon: .suggestedPostReject @@ -2219,7 +2218,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { item.controllerInteraction.openMessageContextMenu(item.message, false, self, self.imageNode.frame, nil, nil) } - override public func targetForStoryTransition(id: StoryId) -> UIView? { + override public func targetForStoryTransition(id: EngineStoryId) -> UIView? { guard let item = self.item else { return nil } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageStoryMentionContentNode/Sources/ChatMessageStoryMentionContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageStoryMentionContentNode/Sources/ChatMessageStoryMentionContentNode.swift index 3e805b7cb6..4962128938 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageStoryMentionContentNode/Sources/ChatMessageStoryMentionContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageStoryMentionContentNode/Sources/ChatMessageStoryMentionContentNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import AccountContext import TelegramPresentationData @@ -95,7 +94,7 @@ public class ChatMessageStoryMentionContentNode: ChatMessageBubbleContentNode { self.fetchDisposable.dispose() } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id == messageId { return (self.imageNode, self.imageNode.bounds, { [weak self] in guard let strongSelf = self else { @@ -110,9 +109,9 @@ public class ChatMessageStoryMentionContentNode: ChatMessageBubbleContentNode { } } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { var mediaHidden = false - var currentMedia: Media? + var currentMedia: EngineRawMedia? if let item = item { mediaLoop: for media in item.message.media { if let media = media as? TelegramMediaStory { @@ -159,7 +158,7 @@ public class ChatMessageStoryMentionContentNode: ChatMessageBubbleContentNode { var story: Stories.Item? let storyMedia: TelegramMediaStory? = item.message.media.first(where: { $0 is TelegramMediaStory }) as? TelegramMediaStory - var selectedMedia: Media? + var selectedMedia: EngineRawMedia? if let storyMedia, let storyItem = item.message.associatedStories[storyMedia.storyId], !storyItem.data.isEmpty, case let .item(storyValue) = storyItem.get(Stories.StoredItem.self) { selectedMedia = storyValue.media diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/BUILD index 0a6225a1f7..95017bfc93 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/AsyncDisplayKit", "//submodules/Display", "//submodules/TelegramCore", - "//submodules/Postbox", "//submodules/TextFormat", "//submodules/UrlEscaping", "//submodules/SSignalKit/SwiftSignalKit", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift index bdc4c7dc8d..566a097725 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import TelegramCore -import Postbox import TextFormat import UrlEscaping import SwiftSignalKit @@ -407,7 +406,7 @@ private final class ChatMessageTodoItemNode: ASDisplayNode { let separatorNode: ASDisplayNode var context: AccountContext? - var message: Message? + var message: EngineRawMessage? var option: TelegramMediaTodo.Item? var pressed: (() -> Void)? @@ -727,7 +726,7 @@ private final class ChatMessageTodoItemNode: ASDisplayNode { return ChatMessageBubbleContentTapAction(content: .none) } - static func asyncLayout(_ maybeNode: ChatMessageTodoItemNode?) -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ presentationContext: ChatPresentationContext, _ message: Message, _ todo: TelegramMediaTodo, _ option: TelegramMediaTodo.Item, _ completion: TelegramMediaTodo.Completion?, _ translation: TranslationMessageAttribute.Additional?, _ constrainedWidth: CGFloat) -> (minimumWidth: CGFloat, layout: ((CGFloat) -> (CGSize, (Bool, Bool, Bool) -> ChatMessageTodoItemNode))) { + static func asyncLayout(_ maybeNode: ChatMessageTodoItemNode?) -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ presentationContext: ChatPresentationContext, _ message: EngineRawMessage, _ todo: TelegramMediaTodo, _ option: TelegramMediaTodo.Item, _ completion: TelegramMediaTodo.Completion?, _ translation: TranslationMessageAttribute.Additional?, _ constrainedWidth: CGFloat) -> (minimumWidth: CGFloat, layout: ((CGFloat) -> (CGSize, (Bool, Bool, Bool) -> ChatMessageTodoItemNode))) { let makeTitleLayout = TextNodeWithEntities.asyncLayout(maybeNode?.titleNode) let makeNameLayout = TextNode.asyncLayout(maybeNode?.nameNode) @@ -1087,7 +1086,7 @@ public class ChatMessageTodoBubbleContentNode: ChatMessageBubbleContentNode { let makeViewResultsTextLayout = TextNode.asyncLayout(self.buttonViewResultsTextNode) let statusLayout = self.statusNode.asyncLayout() - var previousOptionNodeLayouts: [Int32: (_ contet: AccountContext, _ presentationData: ChatPresentationData, _ presentationContext: ChatPresentationContext, _ message: Message, _ poll: TelegramMediaTodo, _ option: TelegramMediaTodo.Item, _ completion: TelegramMediaTodo.Completion?, _ translation: TranslationMessageAttribute.Additional?, _ constrainedWidth: CGFloat) -> (minimumWidth: CGFloat, layout: ((CGFloat) -> (CGSize, (Bool, Bool, Bool) -> ChatMessageTodoItemNode)))] = [:] + var previousOptionNodeLayouts: [Int32: (_ contet: AccountContext, _ presentationData: ChatPresentationData, _ presentationContext: ChatPresentationContext, _ message: EngineRawMessage, _ poll: TelegramMediaTodo, _ option: TelegramMediaTodo.Item, _ completion: TelegramMediaTodo.Completion?, _ translation: TranslationMessageAttribute.Additional?, _ constrainedWidth: CGFloat) -> (minimumWidth: CGFloat, layout: ((CGFloat) -> (CGSize, (Bool, Bool, Bool) -> ChatMessageTodoItemNode)))] = [:] for optionNode in self.optionNodes { if let option = optionNode.option { previousOptionNodeLayouts[option.id] = ChatMessageTodoItemNode.asyncLayout(optionNode) @@ -1293,7 +1292,7 @@ public class ChatMessageTodoBubbleContentNode: ChatMessageBubbleContentNode { for i in 0 ..< todo.items.count { let todoItem = todo.items[i] - let makeLayout: (_ context: AccountContext, _ presentationData: ChatPresentationData, _ presentationContext: ChatPresentationContext, _ message: Message, _ todo: TelegramMediaTodo, _ item: TelegramMediaTodo.Item, _ completion: TelegramMediaTodo.Completion?, _ translation: TranslationMessageAttribute.Additional?, _ constrainedWidth: CGFloat) -> (minimumWidth: CGFloat, layout: ((CGFloat) -> (CGSize, (Bool, Bool, Bool) -> ChatMessageTodoItemNode))) + let makeLayout: (_ context: AccountContext, _ presentationData: ChatPresentationData, _ presentationContext: ChatPresentationContext, _ message: EngineRawMessage, _ todo: TelegramMediaTodo, _ item: TelegramMediaTodo.Item, _ completion: TelegramMediaTodo.Completion?, _ translation: TranslationMessageAttribute.Additional?, _ constrainedWidth: CGFloat) -> (minimumWidth: CGFloat, layout: ((CGFloat) -> (CGSize, (Bool, Bool, Bool) -> ChatMessageTodoItemNode))) if let previous = previousOptionNodeLayouts[todoItem.id] { makeLayout = previous } else { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode/Sources/ChatMessageWallpaperBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode/Sources/ChatMessageWallpaperBubbleContentNode.swift index ec9e6380ea..6aa35297cf 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode/Sources/ChatMessageWallpaperBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode/Sources/ChatMessageWallpaperBubbleContentNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import AccountContext import TelegramPresentationData @@ -135,7 +134,7 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode item.context.account.pendingPeerMediaUploadManager.cancel(peerId: item.message.id.peerId) } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id == messageId { return (self.imageNode, self.imageNode.bounds, { [weak self] in guard let strongSelf = self else { @@ -150,9 +149,9 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode } } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { var mediaHidden = false - var currentMedia: Media? + var currentMedia: EngineRawMedia? if let item = item { mediaLoop: for media in item.message.media { if let media = media as? TelegramMediaAction { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageWebpageBubbleContentNode/Sources/ChatMessageWebpageBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageWebpageBubbleContentNode/Sources/ChatMessageWebpageBubbleContentNode.swift index c0da699d9b..f4f93efff9 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageWebpageBubbleContentNode/Sources/ChatMessageWebpageBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageWebpageBubbleContentNode/Sources/ChatMessageWebpageBubbleContentNode.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import Display import AsyncDisplayKit import SwiftSignalKit @@ -225,7 +224,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent var text: String? var entities: [MessageTextEntity]? var titleBadge: String? - var mediaAndFlags: ([Media], ChatMessageAttachedContentNodeMediaFlags)? + var mediaAndFlags: ([EngineRawMedia], ChatMessageAttachedContentNodeMediaFlags)? var badge: String? var actionIcon: ChatMessageAttachedContentActionIcon? @@ -258,7 +257,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent entities = generateTextEntities(textValue, enabledTypes: entityTypes) } - var mainMedia: Media? + var mainMedia: EngineRawMedia? var automaticPlayback = false @@ -527,7 +526,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent for attribute in webpage.attributes { if case let .aiTextStyle(aiTextStyle) = attribute { - if let file = item.message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: aiTextStyle.emojiFileId)] { + if let file = item.message.associatedMedia[EngineMedia.Id(namespace: Namespaces.Media.CloudFile, id: aiTextStyle.emojiFileId)] { mediaAndFlags = ([file], [.preferMediaInline]) } } @@ -744,13 +743,13 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent return ChatMessageBubbleContentTapAction(content: .none) } - override public func updateHiddenMedia(_ media: [Media]?) -> Bool { + override public func updateHiddenMedia(_ media: [EngineRawMedia]?) -> Bool { if let media = media { var updatedMedia = media if let current = self.webPage, case let .Loaded(content) = current.content { for item in media { if let webpage = item as? TelegramMediaWebpage, webpage.id == current.id { - var mediaList: [Media] = [webpage] + var mediaList: [EngineRawMedia] = [webpage] if let image = content.image { mediaList.append(image) } @@ -762,7 +761,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent } updatedMedia = mediaList } else if let id = item.id, content.file?.id == id || content.image?.id == id { - var mediaList: [Media] = [current] + var mediaList: [EngineRawMedia] = [current] if let image = content.image { mediaList.append(image) } @@ -782,7 +781,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent } } - override public func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(messageId: EngineMessage.Id, media: EngineRawMedia, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { if self.item?.message.id != messageId { return nil } diff --git a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsFilterController.swift b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsFilterController.swift deleted file mode 100644 index cc001bf972..0000000000 --- a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsFilterController.swift +++ /dev/null @@ -1,504 +0,0 @@ -import Foundation -import UIKit -import Display -import SwiftSignalKit -import Postbox -import TelegramCore -import TelegramPresentationData -import TelegramUIPreferences -import ItemListUI -import PresentationDataUtils -import AccountContext -import ItemListPeerItem - -private final class ChatRecentActionsFilterControllerArguments { - let context: AccountContext - - let toggleAllActions: (Bool) -> Void - let toggleAction: ([AdminLogEventsFlags]) -> Void - let toggleAllAdmins: (Bool) -> Void - let toggleAdmin: (PeerId) -> Void - - init(context: AccountContext, toggleAllActions: @escaping (Bool) -> Void, toggleAction: @escaping ([AdminLogEventsFlags]) -> Void, toggleAllAdmins: @escaping (Bool) -> Void, toggleAdmin: @escaping (PeerId) -> Void) { - self.context = context - self.toggleAllActions = toggleAllActions - self.toggleAction = toggleAction - self.toggleAllAdmins = toggleAllAdmins - self.toggleAdmin = toggleAdmin - } -} - -private enum ChatRecentActionsFilterSection: Int32 { - case actions - case admins -} - -private enum ChatRecentActionsFilterEntryStableId: Hashable { - case index(Int32) - case peer(PeerId) -} - -private enum ChatRecentActionsFilterEntry: ItemListNodeEntry { - case actionsTitle(PresentationTheme, String) - case allActions(PresentationTheme, String, Bool) - case actionItem(PresentationTheme, Int32, [AdminLogEventsFlags], String, Bool) - - case adminsTitle(PresentationTheme, String) - case allAdmins(PresentationTheme, String, Bool) - case adminPeerItem(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, Int32, RenderedChannelParticipant, Bool, Bool) - - var section: ItemListSectionId { - switch self { - case .actionsTitle, .allActions, .actionItem: - return ChatRecentActionsFilterSection.actions.rawValue - case .adminsTitle, .allAdmins, .adminPeerItem: - return ChatRecentActionsFilterSection.admins.rawValue - } - } - - var stableId: ChatRecentActionsFilterEntryStableId { - switch self { - case .actionsTitle: - return .index(0) - case .allActions: - return .index(1) - case let .actionItem(_, index, _, _, _): - return .index(100 + index) - case .adminsTitle: - return .index(200) - case .allAdmins: - return .index(201) - case let .adminPeerItem(_, _, _, _, _, participant, _, _): - return .peer(participant.peer.id) - } - } - - static func ==(lhs: ChatRecentActionsFilterEntry, rhs: ChatRecentActionsFilterEntry) -> Bool { - switch lhs { - case let .actionsTitle(lhsTheme, lhsText): - if case let .actionsTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText { - return true - } else { - return false - } - case let .allActions(lhsTheme, lhsText, lhsValue): - if case let .allActions(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { - return true - } else { - return false - } - case let .actionItem(lhsTheme, lhsIndex, lhsFlags, lhsText, lhsValue): - if case let .actionItem(rhsTheme, rhsIndex, rhsFlags, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsIndex == rhsIndex, lhsFlags == rhsFlags, lhsText == rhsText, lhsValue == rhsValue { - return true - } else { - return false - } - case let .adminsTitle(lhsTheme, lhsText): - if case let .adminsTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText { - return true - } else { - return false - } - case let .allAdmins(lhsTheme, lhsText, lhsValue): - if case let .allAdmins(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { - return true - } else { - return false - } - case let .adminPeerItem(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsNameDisplayOrder, lhsIndex, lhsParticipant, lhsIsAntiSpam, lhsChecked): - if case let .adminPeerItem(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsNameDisplayOrder, rhsIndex, rhsParticipant, rhsIsAntiSpam, rhsChecked) = rhs { - if lhsTheme !== rhsTheme { - return false - } - if lhsStrings !== rhsStrings { - return false - } - if lhsDateTimeFormat != rhsDateTimeFormat { - return false - } - if lhsNameDisplayOrder != rhsNameDisplayOrder { - return false - } - if lhsIndex != rhsIndex { - return false - } - if lhsParticipant != rhsParticipant { - return false - } - if lhsIsAntiSpam != rhsIsAntiSpam { - return false - } - if lhsChecked != rhsChecked { - return false - } - return true - } else { - return false - } - } - } - - static func <(lhs: ChatRecentActionsFilterEntry, rhs: ChatRecentActionsFilterEntry) -> Bool { - switch lhs { - case .actionsTitle: - return true - case .allActions: - switch rhs { - case .actionsTitle: - return false - default: - return true - } - case let .actionItem(_, lhsIndex, _, _, _): - switch rhs { - case .actionsTitle, .allActions: - return false - case let .actionItem(_, rhsIndex, _, _, _): - return lhsIndex < rhsIndex - default: - return true - } - case .adminsTitle: - switch rhs { - case .adminPeerItem, .allAdmins: - return true - default: - return false - } - case .allAdmins: - switch rhs { - case .adminPeerItem: - return true - default: - return false - } - case let .adminPeerItem(_, _, _, _, lhsIndex, _, _, _): - switch rhs { - case let .adminPeerItem(_, _, _, _, rhsIndex, _, _, _): - return lhsIndex < rhsIndex - default: - return false - } - } - } - - func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { - let arguments = arguments as! ChatRecentActionsFilterControllerArguments - switch self { - case let .actionsTitle(_, text): - return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .allActions(_, text, value): - return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enabled: true, sectionId: self.section, style: .blocks, updated: { value in - arguments.toggleAllActions(value) - }) - case let .actionItem(_, _, events, text, value): - return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .right, checked: value, zeroSeparatorInsets: false, sectionId: self.section, action: { - arguments.toggleAction(events) - }) - case let .adminsTitle(_, text): - return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .allAdmins(_, text, value): - return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enabled: true, sectionId: self.section, style: .blocks, updated: { value in - arguments.toggleAllAdmins(value) - }) - case let .adminPeerItem(_, strings, dateTimeFormat, nameDisplayOrder, _, participant, isAntiSpam, checked): - var peerText: String = "" - if isAntiSpam { - peerText = strings.Group_Management_AntiSpamMagic - } else { - switch participant.participant { - case .creator: - peerText = strings.Channel_Management_LabelOwner.lowercased() - case .member: - peerText = strings.ChatAdmins_AdminLabel.lowercased() - } - } - return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: participant.peer, presence: nil, text: .text(peerText, .secondary), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), switchValue: ItemListPeerItemSwitch(value: checked, style: .check), enabled: true, selectable: true, sectionId: self.section, action: { - arguments.toggleAdmin(participant.peer.id) - }, setPeerIdWithRevealedOptions: { _, _ in - }, removePeer: { _ in }) - } - } -} - -private struct ChatRecentActionsFilterControllerState: Equatable { - let events: AdminLogEventsFlags - let adminPeerIds: [PeerId]? - - init(events: AdminLogEventsFlags, adminPeerIds: [PeerId]?) { - self.events = events - self.adminPeerIds = adminPeerIds - } - - static func ==(lhs: ChatRecentActionsFilterControllerState, rhs: ChatRecentActionsFilterControllerState) -> Bool { - if lhs.events != rhs.events { - return false - } - if let lhsAdminPeerIds = lhs.adminPeerIds, let rhsAdminPeerIds = rhs.adminPeerIds { - if lhsAdminPeerIds != rhsAdminPeerIds { - return false - } - } else if (lhs.adminPeerIds != nil) != (rhs.adminPeerIds != nil) { - return false - } - - return true - } - - func withUpdatedEvents(_ events: AdminLogEventsFlags) -> ChatRecentActionsFilterControllerState { - return ChatRecentActionsFilterControllerState(events: events, adminPeerIds: self.adminPeerIds) - } - - func withUpdatedAdminPeerIds(_ adminPeerIds: [PeerId]?) -> ChatRecentActionsFilterControllerState { - return ChatRecentActionsFilterControllerState(events: self.events, adminPeerIds: adminPeerIds) - } -} - -private func channelRecentActionsFilterControllerEntries(presentationData: PresentationData, accountPeerId: PeerId, peer: Peer, antiSpamBotId: PeerId?, state: ChatRecentActionsFilterControllerState, participants: [RenderedChannelParticipant]?) -> [ChatRecentActionsFilterEntry] { - var isGroup = true - if let peer = peer as? TelegramChannel, case .broadcast = peer.info { - isGroup = false - } - - var entries: [ChatRecentActionsFilterEntry] = [] - - let order: [([AdminLogEventsFlags], String)] - if isGroup { - order = [ - ([.ban, .unban, .kick, .unkick], presentationData.strings.Channel_AdminLogFilter_EventsRestrictions), - ([.promote, .demote], presentationData.strings.Channel_AdminLogFilter_EventsAdmins), - ([.invite, .join], presentationData.strings.Channel_AdminLogFilter_EventsNewMembers), - ([.info, .settings], isGroup ? presentationData.strings.Channel_AdminLogFilter_EventsInfo : presentationData.strings.Channel_AdminLogFilter_ChannelEventsInfo), - ([.invites], presentationData.strings.Channel_AdminLogFilter_EventsInviteLinks), - ([.deleteMessages], presentationData.strings.Channel_AdminLogFilter_EventsDeletedMessages), - ([.editMessages], presentationData.strings.Channel_AdminLogFilter_EventsEditedMessages), - ([.pinnedMessages], presentationData.strings.Channel_AdminLogFilter_EventsPinned), - ([.leave], presentationData.strings.Channel_AdminLogFilter_EventsLeaving), - ([.calls], presentationData.strings.Channel_AdminLogFilter_EventsCalls) - ] - } else { - order = [ - ([.promote, .demote], presentationData.strings.Channel_AdminLogFilter_EventsAdmins), - ([.invite, .join], presentationData.strings.Channel_AdminLogFilter_EventsNewMembers), - ([.info, .settings], isGroup ? presentationData.strings.Channel_AdminLogFilter_EventsInfo : presentationData.strings.Channel_AdminLogFilter_ChannelEventsInfo), - ([.invites], presentationData.strings.Channel_AdminLogFilter_EventsInviteLinks), - ([.deleteMessages], presentationData.strings.Channel_AdminLogFilter_EventsDeletedMessages), - ([.editMessages], presentationData.strings.Channel_AdminLogFilter_EventsEditedMessages), - ([.pinnedMessages], presentationData.strings.Channel_AdminLogFilter_EventsPinned), - ([.leave], presentationData.strings.Channel_AdminLogFilter_EventsLeaving), - ([.calls], presentationData.strings.Channel_AdminLogFilter_EventsLiveStreams) - ] - } - - var allTypesSelected = true - outer: for (events, _) in order { - for event in events { - if !state.events.contains(event) { - allTypesSelected = false - break outer - } - } - } - - entries.append(.actionsTitle(presentationData.theme, presentationData.strings.Channel_AdminLogFilter_EventsTitle)) - entries.append(.allActions(presentationData.theme, presentationData.strings.Channel_AdminLogFilter_EventsAll, allTypesSelected)) - - var index: Int32 = 0 - for (events, text) in order { - var eventsSelected = true - inner: for event in events { - if !state.events.contains(event) { - eventsSelected = false - break inner - } - } - entries.append(.actionItem(presentationData.theme, index, events, text, eventsSelected)) - index += 1 - } - - if let participants = participants { - var allAdminsSelected = true - if let adminPeerIds = state.adminPeerIds { - for participant in participants { - if !adminPeerIds.contains(participant.peer.id) { - allAdminsSelected = false - break - } - } - } else { - allAdminsSelected = true - } - - entries.append(.adminsTitle(presentationData.theme, presentationData.strings.Channel_AdminLogFilter_AdminsTitle)) - entries.append(.allAdmins(presentationData.theme, presentationData.strings.Channel_AdminLogFilter_AdminsAll, allAdminsSelected)) - - var index: Int32 = 0 - for participant in participants { - var adminSelected = true - if let adminPeerIds = state.adminPeerIds { - if !adminPeerIds.contains(participant.peer.id) { - adminSelected = false - } - } else { - adminSelected = true - } - entries.append(.adminPeerItem(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, index, participant, participant.peer.id == antiSpamBotId, adminSelected)) - index += 1 - } - } - - return entries -} - -public func channelRecentActionsFilterController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, peer: Peer, events: AdminLogEventsFlags, adminPeerIds: [PeerId]?, apply: @escaping (_ events: AdminLogEventsFlags, _ adminPeerIds: [PeerId]?) -> Void) -> ViewController { - let statePromise = ValuePromise(ChatRecentActionsFilterControllerState(events: events, adminPeerIds: adminPeerIds), ignoreRepeated: true) - let stateValue = Atomic(value: ChatRecentActionsFilterControllerState(events: events, adminPeerIds: adminPeerIds)) - let updateState: ((ChatRecentActionsFilterControllerState) -> ChatRecentActionsFilterControllerState) -> Void = { f in - statePromise.set(stateValue.modify { f($0) }) - } - - var dismissImpl: (() -> Void)? - - let adminsPromise = Promise<[RenderedChannelParticipant]?>(nil) - - let actionsDisposable = DisposableSet() - - let arguments = ChatRecentActionsFilterControllerArguments(context: context, toggleAllActions: { value in - updateState { current in - if value { - return current.withUpdatedEvents(.all) - } else { - return current.withUpdatedEvents([]) - } - } - }, toggleAction: { events in - if let first = events.first { - updateState { current in - var updatedEvents = current.events - if updatedEvents.contains(first) { - for event in events { - updatedEvents.remove(event) - } - } else { - for event in events { - updatedEvents.insert(event) - } - } - return current.withUpdatedEvents(updatedEvents) - } - } - }, toggleAllAdmins: { value in - let _ = (adminsPromise.get() - |> take(1) - |> deliverOnMainQueue).startStandalone(next: { admins in - if let _ = admins { - updateState { current in - if value { - return current.withUpdatedAdminPeerIds(nil) - } else { - return current.withUpdatedAdminPeerIds([]) - } - } - } - }) - }, toggleAdmin: { adminId in - let _ = (adminsPromise.get() - |> take(1) - |> deliverOnMainQueue).startStandalone(next: { admins in - if let admins = admins { - updateState { current in - if let adminPeerIds = current.adminPeerIds, let index = adminPeerIds.firstIndex(of: adminId) { - var updatedAdminPeerIds = adminPeerIds - updatedAdminPeerIds.remove(at: index) - return current.withUpdatedAdminPeerIds(updatedAdminPeerIds) - } else { - var updatedAdminPeerIds = current.adminPeerIds ?? admins.map { $0.peer.id } - if updatedAdminPeerIds.contains(adminId), let index = updatedAdminPeerIds.firstIndex(of: adminId) { - updatedAdminPeerIds.remove(at: index) - } else { - updatedAdminPeerIds.append(adminId) - } - return current.withUpdatedAdminPeerIds(updatedAdminPeerIds) - } - } - } - }) - }) - - adminsPromise.set(.single(nil)) - - let (membersDisposable, _) = context.peerChannelMemberCategoriesContextsManager.admins(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peer.id) { membersState in - if case .loading = membersState.loadingState, membersState.list.isEmpty { - adminsPromise.set(.single(nil)) - } else { - adminsPromise.set(.single(membersState.list)) - } - } - actionsDisposable.add(membersDisposable) - - let antiSpamBotConfiguration = AntiSpamBotConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) - let antiSpamBotPeerPromise = Promise(nil) - if let antiSpamBotId = antiSpamBotConfiguration.antiSpamBotId { - antiSpamBotPeerPromise.set(context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: antiSpamBotId)) - |> map { peer in - if let peer = peer, case let .user(user) = peer { - return RenderedChannelParticipant(participant: .member(id: user.id, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil, subscriptionUntilDate: nil), peer: peer) - } else { - return nil - } - }) - } - - var previousPeers: [RenderedChannelParticipant]? - - let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData - let signal = combineLatest(presentationData, statePromise.get(), adminsPromise.get(), antiSpamBotPeerPromise.get()) - |> deliverOnMainQueue - |> map { presentationData, state, admins, antiSpamBot -> (ItemListControllerState, (ItemListNodeState, Any)) in - let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: { - dismissImpl?() - }) - - let doneEnabled = !state.events.isEmpty - - let rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: doneEnabled, action: { - var resultState: ChatRecentActionsFilterControllerState? - updateState { current in - resultState = current - return current - } - if let resultState = resultState { - apply(resultState.events, resultState.adminPeerIds) - } - dismissImpl?() - }) - - var sortedAdmins: [RenderedChannelParticipant]? - if let admins = admins { - sortedAdmins = admins.filter { $0.peer.id == context.account.peerId } + admins.filter({ $0.peer.id != context.account.peerId }) - if let antiSpamBot = antiSpamBot { - sortedAdmins?.insert(antiSpamBot, at: 0) - } - } else { - sortedAdmins = nil - } - - let previous = previousPeers - previousPeers = sortedAdmins - - let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.ChatAdmins_Title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) - let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelRecentActionsFilterControllerEntries(presentationData: presentationData, accountPeerId: context.account.peerId, peer: peer, antiSpamBotId: antiSpamBotConfiguration.antiSpamBotId, state: state, participants: sortedAdmins), style: .blocks, animateChanges: previous != nil && admins != nil && previous!.count >= sortedAdmins!.count) - - return (controllerState, (listState, arguments)) - } - |> afterDisposed { - actionsDisposable.dispose() - } - - let controller = ItemListController(context: context, state: signal) - dismissImpl = { [weak controller] in - controller?.dismiss() - } - return controller -} - diff --git a/submodules/TelegramUI/Components/ChatControllerInteraction/BUILD b/submodules/TelegramUI/Components/ChatControllerInteraction/BUILD index 684e3ca458..43bbbfc9aa 100644 --- a/submodules/TelegramUI/Components/ChatControllerInteraction/BUILD +++ b/submodules/TelegramUI/Components/ChatControllerInteraction/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/Display:Display", - "//submodules/Postbox:Postbox", "//submodules/TelegramCore:TelegramCore", "//submodules/ChatPresentationInterfaceState:ChatPresentationInterfaceState", "//submodules/TelegramUIPreferences:TelegramUIPreferences", diff --git a/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift b/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift index 43ba16297c..1387502783 100644 --- a/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift +++ b/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift @@ -16,7 +16,6 @@ import TextFormat import WallpaperBackgroundNode import AnimationCache import MultiAnimationRenderer -import Postbox public struct ChatInterfaceHighlightedState: Equatable { public struct Quote: Equatable { @@ -41,9 +40,9 @@ public struct ChatInterfaceHighlightedState: Equatable { } public struct ChatInterfacePollActionState: Equatable { - public var pollMessageIdsInProgress: [MessageId: [Data]] = [:] + public var pollMessageIdsInProgress: [EngineMessage.Id: [Data]] = [:] - public init(pollMessageIdsInProgress: [MessageId: [Data]] = [:]) { + public init(pollMessageIdsInProgress: [EngineMessage.Id: [Data]] = [:]) { self.pollMessageIdsInProgress = pollMessageIdsInProgress } } @@ -59,10 +58,10 @@ public enum ChatControllerInteractionReaction { } public struct UnreadMessageRangeKey: Hashable { - public var peerId: PeerId - public var namespace: MessageId.Namespace + public var peerId: EnginePeer.Id + public var namespace: Int32 - public init(peerId: PeerId, namespace: MessageId.Namespace) { + public init(peerId: EnginePeer.Id, namespace: Int32) { self.peerId = peerId self.namespace = namespace } @@ -137,18 +136,18 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol public enum OpenPeerSource { case `default` case reaction - case groupParticipant(storyStats: PeerStoryStats?, avatarHeaderNode: ASDisplayNode?) + case groupParticipant(storyStats: EnginePeerStoryStats?, avatarHeaderNode: ASDisplayNode?) } public struct OpenUrl { public var url: String public var concealed: Bool public var external: Bool? - public var message: Message? + public var message: EngineRawMessage? public var allowInlineWebpageResolution: Bool public var progress: Promise? - public init(url: String, concealed: Bool, external: Bool? = nil, message: Message? = nil, allowInlineWebpageResolution: Bool = false, progress: Promise? = nil) { + public init(url: String, concealed: Bool, external: Bool? = nil, message: EngineRawMessage? = nil, allowInlineWebpageResolution: Bool = false, progress: Promise? = nil) { self.url = url self.concealed = concealed self.external = external @@ -159,13 +158,13 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol } public struct OpenInstantPage { - public var webpageId: MediaId + public var webpageId: EngineMedia.Id public var url: String public var anchor: String? public var concealed: Bool public var progress: Promise? - public init(webpageId: MediaId, url: String, anchor: String?, concealed: Bool, progress: Promise? = nil) { + public init(webpageId: EngineMedia.Id, url: String, anchor: String?, concealed: Bool, progress: Promise? = nil) { self.webpageId = webpageId self.url = url self.anchor = anchor @@ -175,13 +174,13 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol } public struct LongTapParams { - public var message: Message? + public var message: EngineRawMessage? public var contentNode: ContextExtractedContentContainingNode? public var messageNode: ASDisplayNode? public var progress: Promise? public var gesture: TapLongTapOrDoubleTapGestureRecognizer? - public init(message: Message? = nil, contentNode: ContextExtractedContentContainingNode? = nil, messageNode: ASDisplayNode? = nil, progress: Promise? = nil, gesture: TapLongTapOrDoubleTapGestureRecognizer? = nil) { + public init(message: EngineRawMessage? = nil, contentNode: ContextExtractedContentContainingNode? = nil, messageNode: ASDisplayNode? = nil, progress: Promise? = nil, gesture: TapLongTapOrDoubleTapGestureRecognizer? = nil) { self.message = message self.contentNode = contentNode self.messageNode = messageNode @@ -195,100 +194,100 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol case solution(TelegramMediaPollResults.Solution) } - public let openMessage: (Message, OpenMessageParams) -> Bool + public let openMessage: (EngineRawMessage, OpenMessageParams) -> Bool public let openPeer: (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, OpenPeerSource) -> Void public let openPeerMention: (String, Promise?) -> Void - public let openMessageContextMenu: (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void - public let updateMessageReaction: (Message, ChatControllerInteractionReaction, Bool, ContextExtractedContentContainingView?) -> Void - public let openMessageReactionContextMenu: (Message, ContextExtractedContentContainingView, ContextGesture?, MessageReaction.Reaction) -> Void + public let openMessageContextMenu: (EngineRawMessage, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void + public let updateMessageReaction: (EngineRawMessage, ChatControllerInteractionReaction, Bool, ContextExtractedContentContainingView?) -> Void + public let openMessageReactionContextMenu: (EngineRawMessage, ContextExtractedContentContainingView, ContextGesture?, MessageReaction.Reaction) -> Void public let activateMessagePinch: (PinchSourceContainerNode) -> Void - public let openMessageContextActions: (Message, ASDisplayNode, CGRect, ContextGesture?) -> Void - public let navigateToMessage: (MessageId, MessageId, NavigateToMessageParams) -> Void - public let navigateToMessageStandalone: (MessageId) -> Void - public let navigateToThreadMessage: (PeerId, Int64, MessageId?) -> Void - public let tapMessage: ((Message) -> Void)? + public let openMessageContextActions: (EngineRawMessage, ASDisplayNode, CGRect, ContextGesture?) -> Void + public let navigateToMessage: (EngineMessage.Id, EngineMessage.Id, NavigateToMessageParams) -> Void + public let navigateToMessageStandalone: (EngineMessage.Id) -> Void + public let navigateToThreadMessage: (EnginePeer.Id, Int64, EngineMessage.Id?) -> Void + public let tapMessage: ((EngineRawMessage) -> Void)? public let clickThroughMessage: (UIView?, CGPoint?) -> Void - public let toggleMessagesSelection: ([MessageId], Bool) -> Void + public let toggleMessagesSelection: ([EngineMessage.Id], Bool) -> Void public let sendCurrentMessage: (Bool, ChatSendMessageEffect?) -> Void public let sendMessage: (String) -> Void - public let sendSticker: (FileMediaReference, Bool, Bool, String?, Bool, UIView?, CGRect?, CALayer?, [ItemCollectionId]) -> Bool + public let sendSticker: (FileMediaReference, Bool, Bool, String?, Bool, UIView?, CGRect?, CALayer?, [EngineItemCollectionId]) -> Bool public let sendEmoji: (String, ChatTextInputTextCustomEmojiAttribute, Bool) -> Void public let sendGif: (FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool public let sendBotContextResultAsGif: (ChatContextResultCollection, ChatContextResult, UIView, CGRect, Bool, Bool) -> Bool public let editGif: (FileMediaReference, Bool) -> Void - public let requestMessageActionCallback: (Message, MemoryBuffer?, Bool, Bool, Promise?) -> Void + public let requestMessageActionCallback: (EngineRawMessage, EngineMemoryBuffer?, Bool, Bool, Promise?) -> Void public let requestMessageActionUrlAuth: (String, MessageActionUrlSubject) -> Void - public let activateSwitchInline: (PeerId?, String, ReplyMarkupButtonAction.PeerTypes?) -> Void + public let activateSwitchInline: (EnginePeer.Id?, String, ReplyMarkupButtonAction.PeerTypes?) -> Void public let openUrl: (OpenUrl) -> Void public let openExternalInstantPage: (OpenInstantPage) -> Void public let shareCurrentLocation: () -> Void public let shareAccountContact: () -> Void - public let sendBotCommand: (MessageId?, String) -> Void - public let openInstantPage: (Message, ChatMessageItemAssociatedData?) -> Void - public let openWallpaper: (Message) -> Void - public let openTheme: (Message) -> Void + public let sendBotCommand: (EngineMessage.Id?, String) -> Void + public let openInstantPage: (EngineRawMessage, ChatMessageItemAssociatedData?) -> Void + public let openWallpaper: (EngineRawMessage) -> Void + public let openTheme: (EngineRawMessage) -> Void public let openHashtag: (String?, String) -> Void public let updateInputState: ((ChatTextInputState) -> ChatTextInputState) -> Void public let updateInputMode: ((ChatInputMode) -> ChatInputMode) -> Void public let updatePresentationState: ((ChatPresentationInterfaceState) -> ChatPresentationInterfaceState) -> Void - public let openMessageShareMenu: (MessageId) -> Void + public let openMessageShareMenu: (EngineMessage.Id) -> Void public let presentController: (ViewController, Any?) -> Void public let presentControllerInCurrent: (ViewController, Any?) -> Void public let navigationController: () -> NavigationController? public let chatControllerNode: () -> ASDisplayNode? public let presentGlobalOverlayController: (ViewController, Any?) -> Void - public let callPeer: (PeerId, Bool) -> Void - public let openConferenceCall: (Message) -> Void + public let callPeer: (EnginePeer.Id, Bool) -> Void + public let openConferenceCall: (EngineRawMessage) -> Void public let longTap: (ChatControllerInteractionLongTapAction, LongTapParams?) -> Void public let todoItemLongTap: (Int32, LongTapParams?) -> Void public let pollOptionLongTap: (Data, LongTapParams?) -> Void - public let openCheckoutOrReceipt: (MessageId, OpenMessageParams?) -> Void + public let openCheckoutOrReceipt: (EngineMessage.Id, OpenMessageParams?) -> Void public let openSearch: () -> Void - public let setupReply: (MessageId) -> Void - public let canSetupReply: (Message) -> ChatControllerInteractionSwipeAction + public let setupReply: (EngineMessage.Id) -> Void + public let canSetupReply: (EngineRawMessage) -> ChatControllerInteractionSwipeAction public let canSendMessages: () -> Bool public let navigateToFirstDateMessage: (Int32, Bool) -> Void - public let requestRedeliveryOfFailedMessages: (MessageId) -> Void + public let requestRedeliveryOfFailedMessages: (EngineMessage.Id) -> Void public let addContact: (String) -> Void - public let rateCall: (Message, CallId, Bool) -> Void - public let requestSelectMessagePollOptions: (MessageId, [Data]) -> Void - public let requestAddMessagePollOption: (MessageId, String, [MessageTextEntity], Data, AnyMediaReference?) -> Void - public let requestOpenMessagePollResults: (MessageId, MediaId) -> Void + public let rateCall: (EngineRawMessage, CallId, Bool) -> Void + public let requestSelectMessagePollOptions: (EngineMessage.Id, [Data]) -> Void + public let requestAddMessagePollOption: (EngineMessage.Id, String, [MessageTextEntity], Data, AnyMediaReference?) -> Void + public let requestOpenMessagePollResults: (EngineMessage.Id, EngineMedia.Id) -> Void public let openAppStorePage: () -> Void - public let displayMessageTooltip: (MessageId, String, Bool, ASDisplayNode?, CGRect?) -> Void - public let seekToTimecode: (Message, Double, Bool) -> Void + public let displayMessageTooltip: (EngineMessage.Id, String, Bool, ASDisplayNode?, CGRect?) -> Void + public let seekToTimecode: (EngineRawMessage, Double, Bool) -> Void public let scheduleCurrentMessage: (ChatSendMessageActionSheetController.SendParameters?) -> Void - public let sendScheduledMessagesNow: ([MessageId]) -> Void - public let editScheduledMessagesTime: ([MessageId]) -> Void - public let performTextSelectionAction: (Message?, Bool, NSAttributedString, [MessageTextEntity]?, TextSelectionAction) -> Void + public let sendScheduledMessagesNow: ([EngineMessage.Id]) -> Void + public let editScheduledMessagesTime: ([EngineMessage.Id]) -> Void + public let performTextSelectionAction: (EngineRawMessage?, Bool, NSAttributedString, [MessageTextEntity]?, TextSelectionAction) -> Void public let displayImportedMessageTooltip: (ASDisplayNode) -> Void public let displaySwipeToReplyHint: () -> Void - public let dismissReplyMarkupMessage: (Message) -> Void - public let openMessagePollResults: (MessageId, Data) -> Void + public let dismissReplyMarkupMessage: (EngineRawMessage) -> Void + public let openMessagePollResults: (EngineMessage.Id, Data) -> Void public let openPollCreation: (Bool?) -> Void - public let openPollMedia: (Message, PollMediaSubject) -> Void + public let openPollMedia: (EngineRawMessage, PollMediaSubject) -> Void public let displayPollSolution: (TelegramMediaPollResults.Solution?, ASDisplayNode?) -> Void public let displayPsa: (String, ASDisplayNode) -> Void public let displayDiceTooltip: (TelegramMediaDice) -> Void public let animateDiceSuccess: (Bool, Bool) -> Void - public let displayPremiumStickerTooltip: (TelegramMediaFile, Message) -> Void - public let displayEmojiPackTooltip: (TelegramMediaFile, Message) -> Void - public let openPeerContextMenu: (Peer, MessageId?, ASDisplayNode, CGRect, ContextGesture?) -> Void - public let openMessageReplies: (MessageId, Bool, Bool) -> Void - public let openReplyThreadOriginalMessage: (Message) -> Void - public let openMessageStats: (MessageId) -> Void - public let editMessageMedia: (MessageId, Bool) -> Void + public let displayPremiumStickerTooltip: (TelegramMediaFile, EngineRawMessage) -> Void + public let displayEmojiPackTooltip: (TelegramMediaFile, EngineRawMessage) -> Void + public let openPeerContextMenu: (EngineRawPeer, EngineMessage.Id?, ASDisplayNode, CGRect, ContextGesture?) -> Void + public let openMessageReplies: (EngineMessage.Id, Bool, Bool) -> Void + public let openReplyThreadOriginalMessage: (EngineRawMessage) -> Void + public let openMessageStats: (EngineMessage.Id) -> Void + public let editMessageMedia: (EngineMessage.Id, Bool) -> Void public let copyText: (String) -> Void public let displayUndo: (UndoOverlayContent) -> Void public let isAnimatingMessage: (UInt32) -> Bool public let getMessageTransitionNode: () -> ChatMessageTransitionProtocol? public let updateChoosingSticker: (Bool) -> Void - public let commitEmojiInteraction: (MessageId, String, EmojiInteraction, TelegramMediaFile) -> Void + public let commitEmojiInteraction: (EngineMessage.Id, String, EmojiInteraction, TelegramMediaFile) -> Void public let openLargeEmojiInfo: (String, String?, TelegramMediaFile) -> Void public let openJoinLink: (String) -> Void public let openWebView: (String, String, Bool, ChatOpenWebViewSource) -> Void public let activateAdAction: (EngineMessage.Id, Promise?, Bool, Bool) -> Void - public let adContextAction: (Message, ASDisplayNode, ContextGesture?) -> Void + public let adContextAction: (EngineRawMessage, ASDisplayNode, ContextGesture?) -> Void public let removeAd: (Data) -> Void public let openRequestedPeerSelection: (EngineMessage.Id, ReplyMarkupButtonRequestPeerType, Int32, Int32) -> Void public let saveMediaToFiles: (EngineMessage.Id) -> Void @@ -299,45 +298,45 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol public let openRecommendedChannelContextMenu: (EnginePeer, UIView, ContextGesture?) -> Void public let openGroupBoostInfo: (EnginePeer.Id?, Int) -> Void public let openStickerEditor: () -> Void - public let openAgeRestrictedMessageMedia: (Message, @escaping () -> Void) -> Void - public let playMessageEffect: (Message) -> Void - public let editMessageFactCheck: (MessageId) -> Void + public let openAgeRestrictedMessageMedia: (EngineRawMessage, @escaping () -> Void) -> Void + public let playMessageEffect: (EngineRawMessage) -> Void + public let editMessageFactCheck: (EngineMessage.Id) -> Void public let sendGift: (EnginePeer.Id) -> Void public let openUniqueGift: (String) -> Void public let openMessageFeeException: () -> Void - public let requestMessageUpdate: (MessageId, Bool, ControlledTransition?) -> Void + public let requestMessageUpdate: (EngineMessage.Id, Bool, ControlledTransition?) -> Void public let cancelInteractiveKeyboardGestures: () -> Void public let dismissTextInput: () -> Void - public let scrollToMessageId: (MessageIndex, CGFloat) -> Void - public let scrollToMessageIdWithAnchor: (MessageIndex, String) -> Void - public let navigateToStory: (Message, StoryId) -> Void - public let attemptedNavigationToPrivateQuote: (Peer?) -> Void + public let scrollToMessageId: (EngineMessage.Index, CGFloat) -> Void + public let scrollToMessageIdWithAnchor: (EngineMessage.Index, String) -> Void + public let navigateToStory: (EngineRawMessage, EngineStoryId) -> Void + public let attemptedNavigationToPrivateQuote: (EngineRawPeer?) -> Void public let forceUpdateWarpContents: () -> Void public let playShakeAnimation: () -> Void - public let displayQuickShare: (MessageId, ASDisplayNode, ContextGesture) -> Void + public let displayQuickShare: (EngineMessage.Id, ASDisplayNode, ContextGesture) -> Void public let updateChatLocationThread: (Int64?, ChatControllerAnimateInnerChatSwitchDirection?) -> Void - public let requestToggleTodoMessageItem: (MessageId, Int32, Bool) -> Void - public let displayTodoToggleUnavailable: (MessageId) -> Void + public let requestToggleTodoMessageItem: (EngineMessage.Id, Int32, Bool) -> Void + public let displayTodoToggleUnavailable: (EngineMessage.Id) -> Void public let openStarsPurchase: (Int64?) -> Void public let openRankInfo: (EnginePeer, ChatRankInfoScreenRole, String) -> Void public let openSetPeerAvatar: () -> Void public let displayPollRestrictedToast: (EngineMessage.Id) -> Void public var canPlayMedia: Bool = false - public var hiddenMedia: [MessageId: [Media]] = [:] + public var hiddenMedia: [EngineMessage.Id: [EngineRawMedia]] = [:] public var expandedTranslationMessageStableIds: Set = Set() public var selectionState: ChatInterfaceSelectionState? public var highlightedState: ChatInterfaceHighlightedState? public var contextHighlightedState: ChatInterfaceHighlightedState? public var automaticMediaDownloadSettings: MediaAutoDownloadSettings public var pollActionState: ChatInterfacePollActionState - public var currentPollMessageWithTooltip: MessageId? - public var currentPsaMessageWithTooltip: MessageId? + public var currentPollMessageWithTooltip: EngineMessage.Id? + public var currentPsaMessageWithTooltip: EngineMessage.Id? public var stickerSettings: ChatInterfaceStickerSettings - public var searchTextHighightState: (String, [MessageIndex])? - public var unreadMessageRange: [UnreadMessageRangeKey: Range] = [:] - public var seenOneTimeAnimatedMedia = Set() - public var currentMessageWithLoadingReplyThread: MessageId? + public var searchTextHighightState: (String, [EngineMessage.Index])? + public var unreadMessageRange: [UnreadMessageRangeKey: Range] = [:] + public var seenOneTimeAnimatedMedia = Set() + public var currentMessageWithLoadingReplyThread: EngineMessage.Id? public var updatedPresentationData: (initial: PresentationData, signal: Signal)? public let presentationContext: ChatPresentationContext public var playNextOutgoingGift: Bool = false @@ -345,9 +344,9 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol public var enableFullTranslucency: Bool = true public var chatIsRotated: Bool = true public var canReadHistory: Bool = false - public var summarizedMessageIds: Set = Set() + public var summarizedMessageIds: Set = Set() public var focusedTextInputIsMedia: Bool = false - public var focusedPollAddOptionMessageId: MessageId? + public var focusedPollAddOptionMessageId: EngineMessage.Id? private var isOpeningMediaValue: Bool = false public var isOpeningMedia: Bool { @@ -375,100 +374,100 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol public var isSidePanelOpen: Bool = false public init( - openMessage: @escaping (Message, OpenMessageParams) -> Bool, + openMessage: @escaping (EngineRawMessage, OpenMessageParams) -> Bool, openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, OpenPeerSource) -> Void, openPeerMention: @escaping (String, Promise?) -> Void, - openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void, - openMessageReactionContextMenu: @escaping (Message, ContextExtractedContentContainingView, ContextGesture?, MessageReaction.Reaction) -> Void, - updateMessageReaction: @escaping (Message, ChatControllerInteractionReaction, Bool, ContextExtractedContentContainingView?) -> Void, + openMessageContextMenu: @escaping (EngineRawMessage, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void, + openMessageReactionContextMenu: @escaping (EngineRawMessage, ContextExtractedContentContainingView, ContextGesture?, MessageReaction.Reaction) -> Void, + updateMessageReaction: @escaping (EngineRawMessage, ChatControllerInteractionReaction, Bool, ContextExtractedContentContainingView?) -> Void, activateMessagePinch: @escaping (PinchSourceContainerNode) -> Void, - openMessageContextActions: @escaping (Message, ASDisplayNode, CGRect, ContextGesture?) -> Void, - navigateToMessage: @escaping (MessageId, MessageId, NavigateToMessageParams) -> Void, - navigateToMessageStandalone: @escaping (MessageId) -> Void, - navigateToThreadMessage: @escaping (PeerId, Int64, MessageId?) -> Void, - tapMessage: ((Message) -> Void)?, + openMessageContextActions: @escaping (EngineRawMessage, ASDisplayNode, CGRect, ContextGesture?) -> Void, + navigateToMessage: @escaping (EngineMessage.Id, EngineMessage.Id, NavigateToMessageParams) -> Void, + navigateToMessageStandalone: @escaping (EngineMessage.Id) -> Void, + navigateToThreadMessage: @escaping (EnginePeer.Id, Int64, EngineMessage.Id?) -> Void, + tapMessage: ((EngineRawMessage) -> Void)?, clickThroughMessage: @escaping (UIView?, CGPoint?) -> Void, - toggleMessagesSelection: @escaping ([MessageId], Bool) -> Void, + toggleMessagesSelection: @escaping ([EngineMessage.Id], Bool) -> Void, sendCurrentMessage: @escaping (Bool, ChatSendMessageEffect?) -> Void, sendMessage: @escaping (String) -> Void, - sendSticker: @escaping (FileMediaReference, Bool, Bool, String?, Bool, UIView?, CGRect?, CALayer?, [ItemCollectionId]) -> Bool, + sendSticker: @escaping (FileMediaReference, Bool, Bool, String?, Bool, UIView?, CGRect?, CALayer?, [EngineItemCollectionId]) -> Bool, sendEmoji: @escaping (String, ChatTextInputTextCustomEmojiAttribute, Bool) -> Void, sendGif: @escaping (FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool, sendBotContextResultAsGif: @escaping (ChatContextResultCollection, ChatContextResult, UIView, CGRect, Bool, Bool) -> Bool, editGif: @escaping (FileMediaReference, Bool) -> Void, - requestMessageActionCallback: @escaping (Message, MemoryBuffer?, Bool, Bool, Promise?) -> Void, + requestMessageActionCallback: @escaping (EngineRawMessage, EngineMemoryBuffer?, Bool, Bool, Promise?) -> Void, requestMessageActionUrlAuth: @escaping (String, MessageActionUrlSubject) -> Void, - activateSwitchInline: @escaping (PeerId?, String, ReplyMarkupButtonAction.PeerTypes?) -> Void, + activateSwitchInline: @escaping (EnginePeer.Id?, String, ReplyMarkupButtonAction.PeerTypes?) -> Void, openUrl: @escaping (OpenUrl) -> Void, openExternalInstantPage: @escaping (OpenInstantPage) -> Void, shareCurrentLocation: @escaping () -> Void, shareAccountContact: @escaping () -> Void, - sendBotCommand: @escaping (MessageId?, String) -> Void, - openInstantPage: @escaping (Message, ChatMessageItemAssociatedData?) -> Void, - openWallpaper: @escaping (Message) -> Void, - openTheme: @escaping (Message) -> Void, + sendBotCommand: @escaping (EngineMessage.Id?, String) -> Void, + openInstantPage: @escaping (EngineRawMessage, ChatMessageItemAssociatedData?) -> Void, + openWallpaper: @escaping (EngineRawMessage) -> Void, + openTheme: @escaping (EngineRawMessage) -> Void, openHashtag: @escaping (String?, String) -> Void, updateInputState: @escaping ((ChatTextInputState) -> ChatTextInputState) -> Void, updateInputMode: @escaping ((ChatInputMode) -> ChatInputMode) -> Void, updatePresentationState: @escaping ((ChatPresentationInterfaceState) -> ChatPresentationInterfaceState) -> Void, - openMessageShareMenu: @escaping (MessageId) -> Void, + openMessageShareMenu: @escaping (EngineMessage.Id) -> Void, presentController: @escaping (ViewController, Any?) -> Void, presentControllerInCurrent: @escaping (ViewController, Any?) -> Void, navigationController: @escaping () -> NavigationController?, chatControllerNode: @escaping () -> ASDisplayNode?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, - callPeer: @escaping (PeerId, Bool) -> Void, - openConferenceCall: @escaping (Message) -> Void, + callPeer: @escaping (EnginePeer.Id, Bool) -> Void, + openConferenceCall: @escaping (EngineRawMessage) -> Void, longTap: @escaping (ChatControllerInteractionLongTapAction, LongTapParams?) -> Void, todoItemLongTap: @escaping (Int32, LongTapParams?) -> Void, pollOptionLongTap: @escaping (Data, LongTapParams?) -> Void, - openCheckoutOrReceipt: @escaping (MessageId, OpenMessageParams?) -> Void, + openCheckoutOrReceipt: @escaping (EngineMessage.Id, OpenMessageParams?) -> Void, openSearch: @escaping () -> Void, - setupReply: @escaping (MessageId) -> Void, - canSetupReply: @escaping (Message) -> ChatControllerInteractionSwipeAction, + setupReply: @escaping (EngineMessage.Id) -> Void, + canSetupReply: @escaping (EngineRawMessage) -> ChatControllerInteractionSwipeAction, canSendMessages: @escaping () -> Bool, navigateToFirstDateMessage: @escaping(Int32, Bool) ->Void, - requestRedeliveryOfFailedMessages: @escaping (MessageId) -> Void, + requestRedeliveryOfFailedMessages: @escaping (EngineMessage.Id) -> Void, addContact: @escaping (String) -> Void, - rateCall: @escaping (Message, CallId, Bool) -> Void, - requestSelectMessagePollOptions: @escaping (MessageId, [Data]) -> Void, - requestAddMessagePollOption: @escaping (MessageId, String, [MessageTextEntity], Data, AnyMediaReference?) -> Void, - requestOpenMessagePollResults: @escaping (MessageId, MediaId) -> Void, + rateCall: @escaping (EngineRawMessage, CallId, Bool) -> Void, + requestSelectMessagePollOptions: @escaping (EngineMessage.Id, [Data]) -> Void, + requestAddMessagePollOption: @escaping (EngineMessage.Id, String, [MessageTextEntity], Data, AnyMediaReference?) -> Void, + requestOpenMessagePollResults: @escaping (EngineMessage.Id, EngineMedia.Id) -> Void, openAppStorePage: @escaping () -> Void, - displayMessageTooltip: @escaping (MessageId, String, Bool, ASDisplayNode?, CGRect?) -> Void, - seekToTimecode: @escaping (Message, Double, Bool) -> Void, + displayMessageTooltip: @escaping (EngineMessage.Id, String, Bool, ASDisplayNode?, CGRect?) -> Void, + seekToTimecode: @escaping (EngineRawMessage, Double, Bool) -> Void, scheduleCurrentMessage: @escaping (ChatSendMessageActionSheetController.SendParameters?) -> Void, - sendScheduledMessagesNow: @escaping ([MessageId]) -> Void, - editScheduledMessagesTime: @escaping ([MessageId]) -> Void, - performTextSelectionAction: @escaping (Message?, Bool, NSAttributedString, [MessageTextEntity]?, TextSelectionAction) -> Void, + sendScheduledMessagesNow: @escaping ([EngineMessage.Id]) -> Void, + editScheduledMessagesTime: @escaping ([EngineMessage.Id]) -> Void, + performTextSelectionAction: @escaping (EngineRawMessage?, Bool, NSAttributedString, [MessageTextEntity]?, TextSelectionAction) -> Void, displayImportedMessageTooltip: @escaping (ASDisplayNode) -> Void, displaySwipeToReplyHint: @escaping () -> Void, - dismissReplyMarkupMessage: @escaping (Message) -> Void, - openMessagePollResults: @escaping (MessageId, Data) -> Void, + dismissReplyMarkupMessage: @escaping (EngineRawMessage) -> Void, + openMessagePollResults: @escaping (EngineMessage.Id, Data) -> Void, openPollCreation: @escaping (Bool?) -> Void, - openPollMedia: @escaping (Message, PollMediaSubject) -> Void, + openPollMedia: @escaping (EngineRawMessage, PollMediaSubject) -> Void, displayPollSolution: @escaping (TelegramMediaPollResults.Solution?, ASDisplayNode?) -> Void, displayPsa: @escaping (String, ASDisplayNode) -> Void, displayDiceTooltip: @escaping (TelegramMediaDice) -> Void, animateDiceSuccess: @escaping (Bool, Bool) -> Void, - displayPremiumStickerTooltip: @escaping (TelegramMediaFile, Message) -> Void, - displayEmojiPackTooltip: @escaping (TelegramMediaFile, Message) -> Void, - openPeerContextMenu: @escaping (Peer, MessageId?, ASDisplayNode, CGRect, ContextGesture?) -> Void, - openMessageReplies: @escaping (MessageId, Bool, Bool) -> Void, - openReplyThreadOriginalMessage: @escaping (Message) -> Void, - openMessageStats: @escaping (MessageId) -> Void, - editMessageMedia: @escaping (MessageId, Bool) -> Void, + displayPremiumStickerTooltip: @escaping (TelegramMediaFile, EngineRawMessage) -> Void, + displayEmojiPackTooltip: @escaping (TelegramMediaFile, EngineRawMessage) -> Void, + openPeerContextMenu: @escaping (EngineRawPeer, EngineMessage.Id?, ASDisplayNode, CGRect, ContextGesture?) -> Void, + openMessageReplies: @escaping (EngineMessage.Id, Bool, Bool) -> Void, + openReplyThreadOriginalMessage: @escaping (EngineRawMessage) -> Void, + openMessageStats: @escaping (EngineMessage.Id) -> Void, + editMessageMedia: @escaping (EngineMessage.Id, Bool) -> Void, copyText: @escaping (String) -> Void, displayUndo: @escaping (UndoOverlayContent) -> Void, isAnimatingMessage: @escaping (UInt32) -> Bool, getMessageTransitionNode: @escaping () -> ChatMessageTransitionProtocol?, updateChoosingSticker: @escaping (Bool) -> Void, - commitEmojiInteraction: @escaping (MessageId, String, EmojiInteraction, TelegramMediaFile) -> Void, + commitEmojiInteraction: @escaping (EngineMessage.Id, String, EmojiInteraction, TelegramMediaFile) -> Void, openLargeEmojiInfo: @escaping (String, String?, TelegramMediaFile) -> Void, openJoinLink: @escaping (String) -> Void, openWebView: @escaping (String, String, Bool, ChatOpenWebViewSource) -> Void, activateAdAction: @escaping (EngineMessage.Id, Promise?, Bool, Bool) -> Void, - adContextAction: @escaping (Message, ASDisplayNode, ContextGesture?) -> Void, + adContextAction: @escaping (EngineRawMessage, ASDisplayNode, ContextGesture?) -> Void, removeAd: @escaping (Data) -> Void, openRequestedPeerSelection: @escaping (EngineMessage.Id, ReplyMarkupButtonRequestPeerType, Int32, Int32) -> Void, saveMediaToFiles: @escaping (EngineMessage.Id) -> Void, @@ -479,25 +478,25 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol openRecommendedChannelContextMenu: @escaping (EnginePeer, UIView, ContextGesture?) -> Void, openGroupBoostInfo: @escaping (EnginePeer.Id?, Int) -> Void, openStickerEditor: @escaping () -> Void, - openAgeRestrictedMessageMedia: @escaping (Message, @escaping () -> Void) -> Void, - playMessageEffect: @escaping (Message) -> Void, - editMessageFactCheck: @escaping (MessageId) -> Void, + openAgeRestrictedMessageMedia: @escaping (EngineRawMessage, @escaping () -> Void) -> Void, + playMessageEffect: @escaping (EngineRawMessage) -> Void, + editMessageFactCheck: @escaping (EngineMessage.Id) -> Void, sendGift: @escaping (EnginePeer.Id) -> Void, openUniqueGift: @escaping (String) -> Void, openMessageFeeException: @escaping () -> Void, - requestMessageUpdate: @escaping (MessageId, Bool, ControlledTransition?) -> Void, + requestMessageUpdate: @escaping (EngineMessage.Id, Bool, ControlledTransition?) -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void, dismissTextInput: @escaping () -> Void, - scrollToMessageId: @escaping (MessageIndex, CGFloat) -> Void, - scrollToMessageIdWithAnchor: @escaping (MessageIndex, String) -> Void, - navigateToStory: @escaping (Message, StoryId) -> Void, - attemptedNavigationToPrivateQuote: @escaping (Peer?) -> Void, + scrollToMessageId: @escaping (EngineMessage.Index, CGFloat) -> Void, + scrollToMessageIdWithAnchor: @escaping (EngineMessage.Index, String) -> Void, + navigateToStory: @escaping (EngineRawMessage, EngineStoryId) -> Void, + attemptedNavigationToPrivateQuote: @escaping (EngineRawPeer?) -> Void, forceUpdateWarpContents: @escaping () -> Void, playShakeAnimation: @escaping () -> Void, - displayQuickShare: @escaping (MessageId, ASDisplayNode, ContextGesture) -> Void, + displayQuickShare: @escaping (EngineMessage.Id, ASDisplayNode, ContextGesture) -> Void, updateChatLocationThread: @escaping (Int64?, ChatControllerAnimateInnerChatSwitchDirection?) -> Void, - requestToggleTodoMessageItem: @escaping (MessageId, Int32, Bool) -> Void, - displayTodoToggleUnavailable: @escaping (MessageId) -> Void, + requestToggleTodoMessageItem: @escaping (EngineMessage.Id, Int32, Bool) -> Void, + displayTodoToggleUnavailable: @escaping (EngineMessage.Id) -> Void, openStarsPurchase: @escaping (Int64?) -> Void, openRankInfo: @escaping (EnginePeer, ChatRankInfoScreenRole, String) -> Void, openSetPeerAvatar: @escaping () -> Void, diff --git a/submodules/TelegramUI/Components/EntityKeyboardGifContent/BUILD b/submodules/TelegramUI/Components/EntityKeyboardGifContent/BUILD index cc15d62131..1888991dca 100644 --- a/submodules/TelegramUI/Components/EntityKeyboardGifContent/BUILD +++ b/submodules/TelegramUI/Components/EntityKeyboardGifContent/BUILD @@ -19,7 +19,6 @@ swift_library( "//submodules/Components/BundleIconComponent:BundleIconComponent", "//submodules/TelegramPresentationData:TelegramPresentationData", "//submodules/TelegramCore:TelegramCore", - "//submodules/Postbox:Postbox", "//submodules/AnimatedStickerNode:AnimatedStickerNode", "//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode", "//submodules/YuvConversion:YuvConversion", diff --git a/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift index ec517ecc7e..0db09aed45 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift @@ -376,7 +376,7 @@ private final class GiftSetupScreenComponent: Component { let (currency, amount) = storeProduct.priceCurrencyAndAmount - addAppLogEvent(postbox: component.context.account.postbox, type: "premium_gift.promo_screen_accept") + component.context.engine.accountData.addAppLogEvent(type: "premium_gift.promo_screen_accept") var textInputText = NSAttributedString() if let inputPanelView = self.inputPanel.view as? MessageInputPanelComponent.View, case let .text(text) = inputPanelView.getSendMessageInput() { @@ -450,7 +450,7 @@ private final class GiftSetupScreenComponent: Component { } if let errorText { - addAppLogEvent(postbox: component.context.account.postbox, type: "premium_gift.promo_screen_fail") + component.context.engine.accountData.addAppLogEvent(type: "premium_gift.promo_screen_fail") let alertController = textAlertController(context: component.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]) controller.present(alertController, in: .window(.root)) diff --git a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/BUILD b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/BUILD index 3f8e64ed20..3dad3ead7d 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/BUILD +++ b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/BUILD @@ -12,7 +12,6 @@ swift_library( deps = [ "//submodules/AsyncDisplayKit", "//submodules/Display", - "//submodules/Postbox", "//submodules/TelegramCore", "//submodules/SSignalKit/SwiftSignalKit", "//submodules/TelegramPresentationData", diff --git a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackCurrentItem.swift b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackCurrentItem.swift index 622412a738..edc3f81720 100644 --- a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackCurrentItem.swift +++ b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerPackCurrentItem.swift @@ -3,7 +3,6 @@ import UIKit import Display import AsyncDisplayKit import SwiftSignalKit -import Postbox import TelegramCore import TelegramPresentationData import ItemListUI @@ -323,7 +322,7 @@ class GroupStickerPackCurrentItemNode: ItemListRevealOptionsItemNode { } var updatedImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>? - var updatedFetchSignal: Signal? + var updatedFetchSignal: Signal? if fileUpdated { if let file = file { updatedImageSignal = chatMessageSticker(account: item.account, userLocation: .other, file: file, small: false) diff --git a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchContainerNode.swift b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchContainerNode.swift index e8224ba5ca..381166f2d7 100644 --- a/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchContainerNode.swift +++ b/submodules/TelegramUI/Components/GroupStickerPackSetupController/Sources/GroupStickerSearchContainerNode.swift @@ -3,7 +3,6 @@ import UIKit import AsyncDisplayKit import Display import SwiftSignalKit -import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences @@ -24,15 +23,15 @@ private final class GroupStickerSearchContainerInteraction { private final class GroupStickerSearchEntry: Comparable, Identifiable { let index: Int let pack: StickerPackCollectionInfo - let topItem: ItemCollectionItem? + let topItem: EngineRawItemCollectionItem? - init(index: Int, pack: StickerPackCollectionInfo, topItem: ItemCollectionItem?) { + init(index: Int, pack: StickerPackCollectionInfo, topItem: EngineRawItemCollectionItem?) { self.index = index self.pack = pack self.topItem = topItem } - var stableId: ItemCollectionId { + var stableId: EngineItemCollectionId { return self.pack.id } diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatListPaneNode/BUILD b/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatListPaneNode/BUILD index 586c694ff3..2cbff8a410 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatListPaneNode/BUILD +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatListPaneNode/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/SSignalKit/SwiftSignalKit", "//submodules/AsyncDisplayKit", "//submodules/TelegramCore", - "//submodules/Postbox", "//submodules/TelegramPresentationData", "//submodules/AccountContext", "//submodules/TelegramStringFormatting", diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatPaneNode/BUILD b/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatPaneNode/BUILD index 067d915018..fe815d3255 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatPaneNode/BUILD +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoChatPaneNode/BUILD @@ -13,7 +13,6 @@ swift_library( "//submodules/SSignalKit/SwiftSignalKit", "//submodules/AsyncDisplayKit", "//submodules/TelegramCore", - "//submodules/Postbox", "//submodules/TelegramPresentationData", "//submodules/AccountContext", "//submodules/TelegramStringFormatting", diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoPaneNode/BUILD b/submodules/TelegramUI/Components/PeerInfo/PeerInfoPaneNode/BUILD index 1e8570712a..3bd9654bb7 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoPaneNode/BUILD +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoPaneNode/BUILD @@ -11,7 +11,6 @@ swift_library( ], deps = [ "//submodules/SSignalKit/SwiftSignalKit", - "//submodules/Postbox", "//submodules/TelegramCore", "//submodules/AsyncDisplayKit", "//submodules/Display", diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/Panes/PeerInfoListPaneNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/Panes/PeerInfoListPaneNode.swift index 774651c5c4..84d5d770e4 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/Panes/PeerInfoListPaneNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/Panes/PeerInfoListPaneNode.swift @@ -3,7 +3,6 @@ import AsyncDisplayKit import Display import TelegramCore import SwiftSignalKit -import Postbox import TelegramPresentationData import PresentationDataUtils import AccountContext @@ -23,7 +22,7 @@ import PeerInfoPaneNode final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { private let context: AccountContext - private let peerId: PeerId + private let peerId: EnginePeer.Id private let chatLocation: ChatLocation private let chatLocationContextHolder: Atomic private let chatControllerInteraction: ChatControllerInteraction @@ -40,8 +39,8 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { return self.ready.get() } - private let selectedMessagesPromise = Promise?>(nil) - private var selectedMessages: Set? { + private let selectedMessagesPromise = Promise?>(nil) + private var selectedMessages: Set? { didSet { if self.selectedMessages != oldValue { self.selectedMessagesPromise.set(.single(self.selectedMessages)) @@ -69,7 +68,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { return 0.0 } - init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, chatControllerInteraction: ChatControllerInteraction, peerId: PeerId, chatLocation: ChatLocation, chatLocationContextHolder: Atomic, tagMask: MessageTags) { + init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, chatControllerInteraction: ChatControllerInteraction, peerId: EnginePeer.Id, chatLocation: ChatLocation, chatLocationContextHolder: Atomic, tagMask: EngineMessage.Tags) { self.context = context self.peerId = peerId self.chatLocation = chatLocation @@ -166,15 +165,15 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { let presentationData = context.sharedContext.currentPresentationData.with { $0 } switch tagMask { - case MessageTags.file: + case EngineMessage.Tags.file: return PeerInfoStatusData(text: presentationData.strings.SharedMedia_FileCount(Int32(count)), isActivity: false, key: .files) - case MessageTags.music: + case EngineMessage.Tags.music: return PeerInfoStatusData(text: presentationData.strings.SharedMedia_MusicCount(Int32(count)), isActivity: false, key: .music) - case MessageTags.voiceOrInstantVideo: + case EngineMessage.Tags.voiceOrInstantVideo: return PeerInfoStatusData(text: presentationData.strings.SharedMedia_VoiceMessageCount(Int32(count)), isActivity: false, key: .voice) - case MessageTags.webPage: + case EngineMessage.Tags.webPage: return PeerInfoStatusData(text: presentationData.strings.SharedMedia_LinkCount(Int32(count)), isActivity: false, key: .links) - case MessageTags.polls: + case EngineMessage.Tags.polls: return PeerInfoStatusData(text: presentationData.strings.SharedMedia_PollCount(Int32(count)), isActivity: false, key: .links) default: return nil @@ -276,7 +275,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { let settings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.musicPlaybackSettings)?.get(MusicPlaybackSettings.self) ?? MusicPlaybackSettings.defaultSettings transaction.updateSharedData(ApplicationSpecificSharedDataKeys.musicPlaybackSettings, { _ in - return PreferencesEntry(settings.withUpdatedVoicePlaybackRate(rate)) + return EnginePreferencesEntry(settings.withUpdatedVoicePlaybackRate(rate)) }) return rate } @@ -371,7 +370,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { } if let id = state.id as? PeerMessagesMediaPlaylistItemId, let playlistLocation = strongSelf.playlistLocation as? PeerMessagesPlaylistLocation, case let .messages(chatLocation, _, _) = playlistLocation { if type == .music { - let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(id.messageId)), count: 60, highlight: true, setupReply: false), id: 0), context: strongSelf.context, chatLocation: .peer(id: id.messageId.peerId), subject: nil, chatLocationContextHolder: Atomic(value: nil), tag: .tag(MessageTags.music)) + let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: .id(id.messageId)), count: 60, highlight: true, setupReply: false), id: 0), context: strongSelf.context, chatLocation: .peer(id: id.messageId.peerId), subject: nil, chatLocationContextHolder: Atomic(value: nil), tag: .tag(EngineMessage.Tags.music)) var cancelImpl: (() -> Void)? let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/Components/Resources/FetchAudioMediaResource/BUILD b/submodules/TelegramUI/Components/Resources/FetchAudioMediaResource/BUILD index 24183c1036..54d18e0f46 100644 --- a/submodules/TelegramUI/Components/Resources/FetchAudioMediaResource/BUILD +++ b/submodules/TelegramUI/Components/Resources/FetchAudioMediaResource/BUILD @@ -10,7 +10,6 @@ swift_library( "-warnings-as-errors", ], deps = [ - "//submodules/Postbox", "//submodules/SSignalKit/SwiftSignalKit", "//submodules/TelegramCore", "//submodules/LegacyComponents", diff --git a/submodules/TelegramUI/Components/Resources/FetchAudioMediaResource/Sources/FetchAudioMediaResource.swift b/submodules/TelegramUI/Components/Resources/FetchAudioMediaResource/Sources/FetchAudioMediaResource.swift index 97acda1ddb..c451ecab49 100644 --- a/submodules/TelegramUI/Components/Resources/FetchAudioMediaResource/Sources/FetchAudioMediaResource.swift +++ b/submodules/TelegramUI/Components/Resources/FetchAudioMediaResource/Sources/FetchAudioMediaResource.swift @@ -1,14 +1,13 @@ import Foundation import UIKit -import Postbox import SwiftSignalKit import TelegramCore import FFMpegBinding import LocalMediaResources -public func fetchLocalFileAudioMediaResource(postbox: Postbox, resource: LocalFileAudioMediaResource) -> Signal { +public func fetchLocalFileAudioMediaResource(resource: LocalFileAudioMediaResource) -> Signal { let tempFile = EngineTempBox.shared.tempFile(fileName: "audio.ogg") FFMpegOpusTrimmer.trim(resource.path, to: tempFile.path, start: resource.trimRange?.lowerBound ?? 0.0, end: resource.trimRange?.upperBound ?? 1.0) - + return .single(.moveTempFile(file: tempFile)) } diff --git a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/ChannelAppearanceScreen.swift b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/ChannelAppearanceScreen.swift index c00225f8a7..46c32e6195 100644 --- a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/ChannelAppearanceScreen.swift +++ b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/ChannelAppearanceScreen.swift @@ -4,7 +4,6 @@ import Photos import Display import AsyncDisplayKit import SwiftSignalKit -import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences @@ -98,7 +97,7 @@ final class ChannelAppearanceScreenComponent: Component { TelegramEngine.EngineData.Item.Peer.StickerPack(id: peerId), TelegramEngine.EngineData.Item.Peer.Wallpaper(id: peerId) ), - telegramThemes(postbox: context.account.postbox, network: context.account.network, accountManager: context.sharedContext.accountManager) + context.engine.themes.themes(accountManager: context.sharedContext.accountManager) ) |> map { peerData, cloudThemes -> ContentsData in let (peer, subscriberCount, emojiPack, canSetStickerPack, stickerPack, wallpaper) = peerData @@ -695,9 +694,9 @@ final class ChannelAppearanceScreenComponent: Component { self.previousEmojiSetupTimestamp = currentTimestamp self.emojiStatusSelectionController?.dismiss() - var selectedItems = Set() + var selectedItems = Set() if let currentFileId { - selectedItems.insert(MediaId(namespace: Namespaces.Media.CloudFile, id: currentFileId)) + selectedItems.insert(EngineMedia.Id(namespace: Namespaces.Media.CloudFile, id: currentFileId)) } let mappedSubject: EmojiPagerContentComponent.Subject @@ -1303,7 +1302,7 @@ final class ChannelAppearanceScreenComponent: Component { var emojiPackFile: TelegramMediaFile? if let thumbnail = emojiPack?.thumbnail { - emojiPackFile = TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: thumbnail.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: thumbnail.immediateThumbnailData, mimeType: "", size: nil, attributes: [], alternativeRepresentations: []) + emojiPackFile = TelegramMediaFile(fileId: EngineMedia.Id(namespace: 0, id: 0), partialReference: nil, resource: thumbnail.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: thumbnail.immediateThumbnailData, mimeType: "", size: nil, attributes: [], alternativeRepresentations: []) } let emojiPackSectionSize = self.emojiPackSection.update( @@ -1435,7 +1434,7 @@ final class ChannelAppearanceScreenComponent: Component { var stickerPackFile: TelegramMediaFile? if let peerStickerPack = contentsData.peerStickerPack, let thumbnail = peerStickerPack.thumbnail { - stickerPackFile = TelegramMediaFile(fileId: MediaId(namespace: 0, id: peerStickerPack.id.id), partialReference: nil, resource: thumbnail.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: thumbnail.immediateThumbnailData, mimeType: "", size: nil, attributes: [], alternativeRepresentations: []) + stickerPackFile = TelegramMediaFile(fileId: EngineMedia.Id(namespace: 0, id: peerStickerPack.id.id), partialReference: nil, resource: thumbnail.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: thumbnail.immediateThumbnailData, mimeType: "", size: nil, attributes: [], alternativeRepresentations: []) } let stickerPackSectionSize = self.stickerPackSection.update( @@ -1505,7 +1504,7 @@ final class ChannelAppearanceScreenComponent: Component { if !isGroup { let messageItem = PeerNameColorChatPreviewItem.MessageItem( outgoing: false, - peerId: EnginePeer.Id(namespace: peer.id.namespace, id: PeerId.Id._internalFromInt64Value(0)), + peerId: EnginePeer.Id(namespace: peer.id.namespace, id: EnginePeer.Id.Id._internalFromInt64Value(0)), author: peer.compactDisplayTitle, photo: peer.profileImageRepresentations, nameColor: .preset(resolvedState.nameColor), @@ -1644,7 +1643,7 @@ final class ChannelAppearanceScreenComponent: Component { if isGroup { let incomingMessageItem = PeerNameColorChatPreviewItem.MessageItem( outgoing: false, - peerId: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0)), + peerId: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(0)), author: environment.strings.Group_Appearance_PreviewAuthor, photo: [], nameColor: .preset(.red), @@ -1656,7 +1655,7 @@ final class ChannelAppearanceScreenComponent: Component { let outgoingMessageItem = PeerNameColorChatPreviewItem.MessageItem( outgoing: true, - peerId: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), + peerId: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(1)), author: peer.compactDisplayTitle, photo: peer.profileImageRepresentations, nameColor: .preset(.blue), diff --git a/submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode/Sources/SettingsThemeWallpaperNode.swift b/submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode/Sources/SettingsThemeWallpaperNode.swift index 5756cf369e..86a9ecb6ff 100644 --- a/submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode/Sources/SettingsThemeWallpaperNode.swift +++ b/submodules/TelegramUI/Components/Settings/SettingsThemeWallpaperNode/Sources/SettingsThemeWallpaperNode.swift @@ -232,7 +232,7 @@ public final class SettingsThemeWallpaperNode: ASDisplayNode { switch wallpaper { case .builtin: self.imageNode.alpha = 1.0 - self.imageNode.setSignal(settingsBuiltinWallpaperImage(account: context.account, thumbnail: true)) + self.imageNode.setSignal(settingsBuiltinWallpaperImage(thumbnail: true)) let apply = self.imageNode.asyncLayout()(TransformImageArguments(corners: corners, imageSize: CGSize(), boundingSize: size, intrinsicInsets: UIEdgeInsets())) apply() self.isLoadedDisposable.set(nil) diff --git a/submodules/TelegramUI/Components/Settings/ThemeAccentColorScreen/Sources/ThemeAccentColorController.swift b/submodules/TelegramUI/Components/Settings/ThemeAccentColorScreen/Sources/ThemeAccentColorController.swift index 3acf431bae..3b656ee5be 100644 --- a/submodules/TelegramUI/Components/Settings/ThemeAccentColorScreen/Sources/ThemeAccentColorController.swift +++ b/submodules/TelegramUI/Components/Settings/ThemeAccentColorScreen/Sources/ThemeAccentColorController.swift @@ -385,7 +385,7 @@ public final class ThemeAccentColorController: ViewController { let _ = (combineLatest( self.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings]) |> take(1), - telegramWallpapers(postbox: context.account.postbox, network: context.account.network) |> take(1) + context.engine.themes.wallpapers() |> take(1) ) |> deliverOnMainQueue).start(next: { [weak self] sharedData, wallpapers in guard let strongSelf = self else { diff --git a/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryItem.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryItem.swift index 247e0f75eb..b7888119d0 100644 --- a/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryItem.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperGalleryItem.swift @@ -719,7 +719,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { case .builtin, .emoticon: displaySize = CGSize(width: 1308.0, height: 2688.0).fitted(CGSize(width: 1280.0, height: 1280.0)).dividedByScreenScale().integralFloor contentSize = displaySize - signal = settingsBuiltinWallpaperImage(account: self.context.account) + signal = settingsBuiltinWallpaperImage() fetchSignal = .complete() statusSignal = .single(.Local) subtitleSignal = .single(nil) @@ -875,7 +875,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { let dimensions = CGSize(width: asset.pixelWidth, height: asset.pixelHeight) contentSize = dimensions displaySize = dimensions.aspectFittedOrSmaller(CGSize(width: 2048.0, height: 2048.0)) - signal = photoWallpaper(postbox: context.account.postbox, photoLibraryResource: PhotoLibraryMediaResource(localIdentifier: asset.localIdentifier, uniqueId: Int64.random(in: Int64.min ... Int64.max))) + signal = photoWallpaper(photoLibraryResource: PhotoLibraryMediaResource(localIdentifier: asset.localIdentifier, uniqueId: Int64.random(in: Int64.min ... Int64.max))) fetchSignal = .complete() statusSignal = .single(.Local) subtitleSignal = .single(nil) diff --git a/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift index 22810d275e..bed529da7e 100644 --- a/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGalleryScreen/Sources/WallpaperPatternPanelNode.swift @@ -255,7 +255,7 @@ public final class WallpaperPatternPanelNode: ASDisplayNode { self.addSubnode(self.titleNode) self.addSubnode(self.labelNode) - self.disposable = ((telegramWallpapers(postbox: context.account.postbox, network: context.account.network) + self.disposable = ((context.engine.themes.wallpapers() |> map { wallpapers -> [TelegramWallpaper] in var existingIds = Set() diff --git a/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridController.swift b/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridController.swift index b7d86b3f0f..2c4d0213fa 100644 --- a/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridController.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridController.swift @@ -359,7 +359,7 @@ public final class ThemeGridController: ViewController { }) }).start() - let _ = (telegramWallpapers(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network) + let _ = (strongSelf.context.engine.themes.wallpapers() |> deliverOnMainQueue).start(completed: { [weak self, weak controller] in controller?.dismiss() if let strongSelf = self { diff --git a/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridControllerNode.swift b/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridControllerNode.swift index c316cecebb..7c2b63a292 100644 --- a/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridControllerNode.swift +++ b/submodules/TelegramUI/Components/Settings/WallpaperGridScreen/Sources/ThemeGridControllerNode.swift @@ -633,7 +633,7 @@ final class ThemeGridControllerNode: ASDisplayNode { switch self.mode { case .generic: self.wallpapersPromise.set(combineLatest(queue: .mainQueue(), - telegramWallpapers(postbox: self.context.account.postbox, network: self.context.account.network), + self.context.engine.themes.wallpapers(), self.context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.wallapersState]) ) |> map { remoteWallpapers, sharedData -> [Wallpaper] in diff --git a/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift b/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift index 446e8d1910..29f49ec090 100644 --- a/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift @@ -203,7 +203,7 @@ public final class StorySetIndicatorComponent: Component { var fetchSignal: Signal? if displayAvatars { - imageSignal = peerAvatarCompleteImage(postbox: context.account.postbox, network: context.account.network, peer: item.peer, forceProvidedRepresentation: false, representation: nil, size: CGSize(width: 26.0, height: 26.0), round: true, font: avatarPlaceholderFont(size: 13.0), drawLetters: true, fullSize: false, blurred: false) + imageSignal = peerAvatarCompleteImage(postbox: context.account.postbox, peer: item.peer, forceProvidedRepresentation: false, representation: nil, size: CGSize(width: 26.0, height: 26.0), round: true, font: avatarPlaceholderFont(size: 13.0), drawLetters: true, fullSize: false, blurred: false) } else { switch messageMedia { case let .image(image): diff --git a/submodules/TelegramUI/Components/TelegramAccountAuxiliaryMethods/Sources/TelegramAccountAuxiliaryMethods.swift b/submodules/TelegramUI/Components/TelegramAccountAuxiliaryMethods/Sources/TelegramAccountAuxiliaryMethods.swift index 3f6203887f..976b942ba6 100644 --- a/submodules/TelegramUI/Components/TelegramAccountAuxiliaryMethods/Sources/TelegramAccountAuxiliaryMethods.swift +++ b/submodules/TelegramUI/Components/TelegramAccountAuxiliaryMethods/Sources/TelegramAccountAuxiliaryMethods.swift @@ -46,7 +46,7 @@ public func makeTelegramAccountAuxiliaryMethods(uploadInBackground: ((Postbox, M return fetchLocalFileVideoMediaResource(postbox: postbox, resource: resource, alwaysUseModernPipeline: useModernPipeline) } } else if let resource = resource as? LocalFileAudioMediaResource { - return fetchLocalFileAudioMediaResource(postbox: postbox, resource: resource) + return fetchLocalFileAudioMediaResource(resource: resource) } else if let resource = resource as? LocalFileGifMediaResource { return fetchLocalFileGifMediaResource(resource: resource) } else if let photoLibraryResource = resource as? PhotoLibraryMediaResource { diff --git a/submodules/TelegramUI/Components/TelegramUIDeclareEncodables/BUILD b/submodules/TelegramUI/Components/TelegramUIDeclareEncodables/BUILD index 5faf3562fe..72a004e510 100644 --- a/submodules/TelegramUI/Components/TelegramUIDeclareEncodables/BUILD +++ b/submodules/TelegramUI/Components/TelegramUIDeclareEncodables/BUILD @@ -10,7 +10,7 @@ swift_library( "-warnings-as-errors", ], deps = [ - "//submodules/Postbox", + "//submodules/TelegramCore", "//submodules/TemporaryCachedPeerDataManager", "//submodules/TelegramUIPreferences", "//submodules/TelegramNotices", diff --git a/submodules/TelegramUI/Components/TelegramUIDeclareEncodables/Sources/TelegramUIDeclareEncodables.swift b/submodules/TelegramUI/Components/TelegramUIDeclareEncodables/Sources/TelegramUIDeclareEncodables.swift index 461dc1999b..203fcd6656 100644 --- a/submodules/TelegramUI/Components/TelegramUIDeclareEncodables/Sources/TelegramUIDeclareEncodables.swift +++ b/submodules/TelegramUI/Components/TelegramUIDeclareEncodables/Sources/TelegramUIDeclareEncodables.swift @@ -1,4 +1,4 @@ -import Postbox +import TelegramCore import TemporaryCachedPeerDataManager import TelegramUIPreferences import TelegramNotices @@ -15,12 +15,12 @@ import ChatInterfaceState import ICloudResources private var telegramUIDeclaredEncodables: Void = { - declareEncodable(VideoLibraryMediaResource.self, f: { VideoLibraryMediaResource(decoder: $0) }) - declareEncodable(LocalFileVideoMediaResource.self, f: { LocalFileVideoMediaResource(decoder: $0) }) - declareEncodable(LocalFileAudioMediaResource.self, f: { LocalFileAudioMediaResource(decoder: $0) }) - declareEncodable(LocalFileGifMediaResource.self, f: { LocalFileGifMediaResource(decoder: $0) }) - declareEncodable(PhotoLibraryMediaResource.self, f: { PhotoLibraryMediaResource(decoder: $0) }) - declareEncodable(ICloudFileResource.self, f: { ICloudFileResource(decoder: $0) }) + engineDeclareEncodable(VideoLibraryMediaResource.self, f: { VideoLibraryMediaResource(decoder: $0) }) + engineDeclareEncodable(LocalFileVideoMediaResource.self, f: { LocalFileVideoMediaResource(decoder: $0) }) + engineDeclareEncodable(LocalFileAudioMediaResource.self, f: { LocalFileAudioMediaResource(decoder: $0) }) + engineDeclareEncodable(LocalFileGifMediaResource.self, f: { LocalFileGifMediaResource(decoder: $0) }) + engineDeclareEncodable(PhotoLibraryMediaResource.self, f: { PhotoLibraryMediaResource(decoder: $0) }) + engineDeclareEncodable(ICloudFileResource.self, f: { ICloudFileResource(decoder: $0) }) return }() diff --git a/submodules/TelegramUI/Components/WallpaperPreviewMedia/Sources/WallpaperPreviewMedia.swift b/submodules/TelegramUI/Components/WallpaperPreviewMedia/Sources/WallpaperPreviewMedia.swift index f2863df6c2..bbd149be09 100644 --- a/submodules/TelegramUI/Components/WallpaperPreviewMedia/Sources/WallpaperPreviewMedia.swift +++ b/submodules/TelegramUI/Components/WallpaperPreviewMedia/Sources/WallpaperPreviewMedia.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import TelegramCore public enum WallpaperPreviewMediaContent: Equatable { @@ -12,11 +11,11 @@ public enum WallpaperPreviewMediaContent: Equatable { case emoticon(String) } -public final class WallpaperPreviewMedia: Media { - public var id: MediaId? { +public final class WallpaperPreviewMedia: EngineRawMedia { + public var id: EngineMedia.Id? { return nil } - public let peerIds: [PeerId] = [] + public let peerIds: [EnginePeer.Id] = [] public let content: WallpaperPreviewMediaContent @@ -24,14 +23,14 @@ public final class WallpaperPreviewMedia: Media { self.content = content } - public init(decoder: PostboxDecoder) { + public init(decoder: EnginePostboxDecoder) { self.content = .color(.clear) } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { } - public func isEqual(to other: Media) -> Bool { + public func isEqual(to other: EngineRawMedia) -> Bool { guard let other = other as? WallpaperPreviewMedia else { return false } @@ -43,7 +42,7 @@ public final class WallpaperPreviewMedia: Media { return true } - public func isSemanticallyEqual(to other: Media) -> Bool { + public func isSemanticallyEqual(to other: EngineRawMedia) -> Bool { return self.isEqual(to: other) } } @@ -73,11 +72,11 @@ public extension WallpaperPreviewMedia { } } -public final class UniqueGiftPreviewMedia: Media { - public var id: MediaId? { +public final class UniqueGiftPreviewMedia: EngineRawMedia { + public var id: EngineMedia.Id? { return nil } - public let peerIds: [PeerId] = [] + public let peerIds: [EnginePeer.Id] = [] public let content: StarGift.UniqueGift? @@ -85,14 +84,14 @@ public final class UniqueGiftPreviewMedia: Media { self.content = content } - public init(decoder: PostboxDecoder) { + public init(decoder: EnginePostboxDecoder) { self.content = nil } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { } - public func isEqual(to other: Media) -> Bool { + public func isEqual(to other: EngineRawMedia) -> Bool { guard let other = other as? UniqueGiftPreviewMedia else { return false } @@ -104,17 +103,17 @@ public final class UniqueGiftPreviewMedia: Media { return true } - public func isSemanticallyEqual(to other: Media) -> Bool { + public func isSemanticallyEqual(to other: EngineRawMedia) -> Bool { return self.isEqual(to: other) } } -public final class GiftAuctionPreviewMedia: Media { - public var id: MediaId? { +public final class GiftAuctionPreviewMedia: EngineRawMedia { + public var id: EngineMedia.Id? { return nil } - public let peerIds: [PeerId] = [] + public let peerIds: [EnginePeer.Id] = [] public let content: StarGift.Gift? public let endTime: Int32 @@ -124,15 +123,15 @@ public final class GiftAuctionPreviewMedia: Media { self.endTime = endTime } - public init(decoder: PostboxDecoder) { + public init(decoder: EnginePostboxDecoder) { self.content = nil self.endTime = 0 } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { } - public func isEqual(to other: Media) -> Bool { + public func isEqual(to other: EngineRawMedia) -> Bool { guard let other = other as? GiftAuctionPreviewMedia else { return false } @@ -144,7 +143,7 @@ public final class GiftAuctionPreviewMedia: Media { return true } - public func isSemanticallyEqual(to other: Media) -> Bool { + public func isSemanticallyEqual(to other: EngineRawMedia) -> Bool { return self.isEqual(to: other) } } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 953692fad1..f15c0d78a2 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -212,7 +212,7 @@ func isTopmostChatController(_ controller: ChatControllerImpl) -> Bool { return true } -func calculateSlowmodeActiveUntilTimestamp(account: Account, untilTimestamp: Int32?) -> Int32? { +func calculateSlowmodeActiveUntilTimestamp(untilTimestamp: Int32?) -> Int32? { guard let untilTimestamp = untilTimestamp else { return nil } diff --git a/submodules/TelegramUI/Sources/ChatControllerContentData.swift b/submodules/TelegramUI/Sources/ChatControllerContentData.swift index fcc7e6e66f..77366bb6f7 100644 --- a/submodules/TelegramUI/Sources/ChatControllerContentData.swift +++ b/submodules/TelegramUI/Sources/ChatControllerContentData.swift @@ -1907,7 +1907,7 @@ extension ChatControllerImpl { canBypassRestrictions = true } if !canBypassRestrictions, let channel = combinedInitialData.initialData?.peer as? TelegramChannel, channel.isRestrictedBySlowmode, let timeout = cachedData.slowModeTimeout { - if let slowmodeUntilTimestamp = calculateSlowmodeActiveUntilTimestamp(account: context.account, untilTimestamp: cachedData.slowModeValidUntilTimestamp) { + if let slowmodeUntilTimestamp = calculateSlowmodeActiveUntilTimestamp(untilTimestamp: cachedData.slowModeValidUntilTimestamp) { slowmodeState = ChatSlowmodeState(timeout: timeout, variant: .timestamp(slowmodeUntilTimestamp)) } } @@ -2313,7 +2313,7 @@ extension ChatControllerImpl { if let channel = strongSelf.state.renderedPeer?.peer as? TelegramChannel, channel.isRestrictedBySlowmode, let timeout = cachedData.slowModeTimeout { if hasPendingMessages { slowmodeState = ChatSlowmodeState(timeout: timeout, variant: .pendingMessages) - } else if let slowmodeUntilTimestamp = calculateSlowmodeActiveUntilTimestamp(account: context.account, untilTimestamp: cachedData.slowModeValidUntilTimestamp) { + } else if let slowmodeUntilTimestamp = calculateSlowmodeActiveUntilTimestamp(untilTimestamp: cachedData.slowModeValidUntilTimestamp) { slowmodeState = ChatSlowmodeState(timeout: timeout, variant: .timestamp(slowmodeUntilTimestamp)) } } diff --git a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift index 324fd0e7e6..61744d861e 100644 --- a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift @@ -2,7 +2,6 @@ import Foundation import UIKit import Display import AsyncDisplayKit -import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData @@ -570,7 +569,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { } } - private func enqueueTransition(width: CGFloat, panelHeight: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition, animation: PinnedMessageAnimation?, pinnedMessage: ChatPinnedMessage, theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, accountPeerId: PeerId, firstTime: Bool, isReplyThread: Bool, translateToLanguage: String?) { + private func enqueueTransition(width: CGFloat, panelHeight: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition, animation: PinnedMessageAnimation?, pinnedMessage: ChatPinnedMessage, theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, accountPeerId: EnginePeer.Id, firstTime: Bool, isReplyThread: Bool, translateToLanguage: String?) { let message = pinnedMessage.message var animationTransition: ContainedViewLayoutTransition = .immediate @@ -661,7 +660,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { } else if let paidContent = media as? TelegramMediaPaidContent, let firstMedia = paidContent.extendedMedia.first { switch firstMedia { case let .preview(dimensions, immediateThumbnailData, _): - let thumbnailMedia = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [], immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: []) + let thumbnailMedia = TelegramMediaImage(imageId: EngineMedia.Id(namespace: 0, id: 0), representations: [], immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: []) if let dimensions { imageDimensions = dimensions.cgSize } @@ -722,7 +721,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { let hasSpoiler = message.attributes.contains(where: { $0 is MediaSpoilerMessageAttribute }) var updateImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>? - var updatedFetchMediaSignal: Signal? + var updatedFetchMediaSignal: Signal? if mediaUpdated { if let updatedMediaReference = updatedMediaReference, imageDimensions != nil { if let imageReference = updatedMediaReference.concrete(TelegramMediaImage.self) { @@ -976,22 +975,22 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { }) return case let .switchInline(samePeer, query, peerTypes): - var botPeer: Peer? - + var botPeer: EnginePeer? + var found = false for attribute in message.attributes { if let attribute = attribute as? InlineBotMessageAttribute { if let peerId = attribute.peerId { - botPeer = message.peers[peerId] + botPeer = message.peers[peerId].flatMap(EnginePeer.init) found = true } } } if !found { - botPeer = message.author + botPeer = message.author.flatMap(EnginePeer.init) } - - var peerId: PeerId? + + var peerId: EnginePeer.Id? if samePeer { peerId = message.id.peerId } diff --git a/submodules/TelegramUI/Sources/FetchCachedRepresentations.swift b/submodules/TelegramUI/Sources/FetchCachedRepresentations.swift index 0e6be30087..1aa4751861 100644 --- a/submodules/TelegramUI/Sources/FetchCachedRepresentations.swift +++ b/submodules/TelegramUI/Sources/FetchCachedRepresentations.swift @@ -29,7 +29,7 @@ public func fetchCachedResourceRepresentation(account: Account, resource: MediaR if !data.complete { return .complete() } - return fetchCachedStickerAJpegRepresentation(account: account, resource: resource, resourceData: data, representation: representation) + return fetchCachedStickerAJpegRepresentation(resource: resource, resourceData: data, representation: representation) } } else if let representation = representation as? CachedScaledImageRepresentation { return account.postbox.mediaBox.resourceData(resource, option: .complete(waitUntilFetchStatus: false)) @@ -130,7 +130,7 @@ public func fetchCachedResourceRepresentation(account: Account, resource: MediaR return account.postbox.mediaBox.resourceData(resource, option: .complete(waitUntilFetchStatus: false)) |> mapToSignal { data -> Signal in if data.complete, let fileData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) { - return fetchCachedAlbumArtworkRepresentation(account: account, resource: resource, data: fileData, representation: representation) + return fetchCachedAlbumArtworkRepresentation(resource: resource, data: fileData, representation: representation) |> `catch` { _ -> Signal in return .complete() } @@ -138,7 +138,7 @@ public func fetchCachedResourceRepresentation(account: Account, resource: MediaR return account.postbox.mediaBox.resourceData(resource, size: size, in: 0 ..< min(size, 256 * 1024)) |> mapToSignal { result -> Signal in let (data, _) = result - return fetchCachedAlbumArtworkRepresentation(account: account, resource: resource, data: data, representation: representation) + return fetchCachedAlbumArtworkRepresentation(resource: resource, data: data, representation: representation) |> `catch` { error -> Signal in switch error { case let .moreDataNeeded(targetSize): @@ -146,7 +146,7 @@ public func fetchCachedResourceRepresentation(account: Account, resource: MediaR |> mapToSignal { result -> Signal in let (data, _) = result - return fetchCachedAlbumArtworkRepresentation(account: account, resource: resource, data: data, representation: representation) + return fetchCachedAlbumArtworkRepresentation(resource: resource, data: data, representation: representation) |> `catch` { error -> Signal in return .complete() } @@ -164,7 +164,7 @@ public func fetchCachedResourceRepresentation(account: Account, resource: MediaR if !data.complete { return .complete() } - return fetchAnimatedStickerRepresentation(account: account, resource: resource, resourceData: data, representation: representation) + return fetchAnimatedStickerRepresentation(resource: resource, resourceData: data, representation: representation) } } else if let representation = representation as? CachedVideoStickerRepresentation { return account.postbox.mediaBox.resourceData(resource, option: .complete(waitUntilFetchStatus: false)) @@ -172,7 +172,7 @@ public func fetchCachedResourceRepresentation(account: Account, resource: MediaR if !data.complete { return .complete() } - return fetchVideoStickerRepresentation(account: account, resource: resource, resourceData: data, representation: representation) + return fetchVideoStickerRepresentation(resource: resource, resourceData: data, representation: representation) } } else if let representation = representation as? CachedAnimatedStickerFirstFrameRepresentation { return account.postbox.mediaBox.resourceData(resource, option: .complete(waitUntilFetchStatus: false)) @@ -180,7 +180,7 @@ public func fetchCachedResourceRepresentation(account: Account, resource: MediaR if !data.complete { return .complete() } - return fetchAnimatedStickerFirstFrameRepresentation(account: account, resource: resource, resourceData: data, representation: representation) + return fetchAnimatedStickerFirstFrameRepresentation(resource: resource, resourceData: data, representation: representation) } } else if let resource = resource as? YoutubeEmbedStoryboardMediaResource, let _ = representation as? YoutubeEmbedStoryboardMediaResourceRepresentation { return fetchYoutubeEmbedStoryboardResource(resource: resource) @@ -210,7 +210,7 @@ private func videoFirstFrameData(account: Account, resource: MediaResource, chun |> mapToSignal { _ -> Signal in return account.postbox.mediaBox.resourceData(resource, option: .incremental(waitUntilFetchStatus: false), attemptSynchronously: false) |> mapToSignal { data -> Signal in - return fetchCachedVideoFirstFrameRepresentation(account: account, resource: resource, resourceData: data) + return fetchCachedVideoFirstFrameRepresentation(resource: resource, resourceData: data) |> `catch` { _ -> Signal in if chunkSize > size { return .complete() @@ -225,7 +225,7 @@ private func videoFirstFrameData(account: Account, resource: MediaResource, chun } } -private func fetchCachedStickerAJpegRepresentation(account: Account, resource: MediaResource, resourceData: MediaResourceData, representation: CachedStickerAJpegRepresentation) -> Signal { +private func fetchCachedStickerAJpegRepresentation(resource: MediaResource, resourceData: MediaResourceData, representation: CachedStickerAJpegRepresentation) -> Signal { return Signal({ subscriber in if let data = try? Data(contentsOf: URL(fileURLWithPath: resourceData.path), options: [.mappedIfSafe]) { var image: UIImage? @@ -371,7 +371,7 @@ public enum FetchVideoFirstFrameError { case generic } -private func fetchCachedVideoFirstFrameRepresentation(account: Account, resource: MediaResource, resourceData: MediaResourceData) -> Signal { +private func fetchCachedVideoFirstFrameRepresentation(resource: MediaResource, resourceData: MediaResourceData) -> Signal { return Signal { subscriber in let tempFilePath = NSTemporaryDirectory() + "\(arc4random()).mov" do { @@ -499,38 +499,11 @@ public func fetchCachedSharedResourceRepresentation(accountManager: AccountManag } } -private func fetchCachedBlurredWallpaperRepresentation(account: Account, resource: MediaResource, resourceData: MediaResourceData, representation: CachedBlurredWallpaperRepresentation) -> Signal { - return Signal({ subscriber in - if let data = try? Data(contentsOf: URL(fileURLWithPath: resourceData.path), options: [.mappedIfSafe]) { - if let image = UIImage(data: data) { - let path = NSTemporaryDirectory() + "\(Int64.random(in: Int64.min ... Int64.max))" - let url = URL(fileURLWithPath: path) - - if let colorImage = blurredImage(image, radius: 30.0), let colorDestination = CGImageDestinationCreateWithURL(url as CFURL, kUTTypeJPEG, 1, nil) { - CGImageDestinationSetProperties(colorDestination, NSDictionary() as CFDictionary) - - let colorQuality: Float = 0.5 - - let options = NSMutableDictionary() - options.setObject(colorQuality as NSNumber, forKey: kCGImageDestinationLossyCompressionQuality as NSString) - - CGImageDestinationAddImage(colorDestination, colorImage.cgImage!, options as CFDictionary) - if CGImageDestinationFinalize(colorDestination) { - subscriber.putNext(.temporaryPath(path)) - subscriber.putCompletion() - } - } - } - } - return EmptyDisposable - }) |> runOn(Queue.concurrentDefaultQueue()) -} - public enum FetchAlbumArtworkError { case moreDataNeeded(Int) } -private func fetchCachedAlbumArtworkRepresentation(account: Account, resource: MediaResource, data: Data, representation: CachedAlbumArtworkRepresentation) -> Signal { +private func fetchCachedAlbumArtworkRepresentation(resource: MediaResource, data: Data, representation: CachedAlbumArtworkRepresentation) -> Signal { return Signal({ subscriber in let result = readAlbumArtworkData(data) switch result { @@ -573,7 +546,7 @@ private func fetchCachedAlbumArtworkRepresentation(account: Account, resource: M }) |> runOn(Queue.concurrentDefaultQueue()) } -private func fetchAnimatedStickerFirstFrameRepresentation(account: Account, resource: MediaResource, resourceData: MediaResourceData, representation: CachedAnimatedStickerFirstFrameRepresentation) -> Signal { +private func fetchAnimatedStickerFirstFrameRepresentation(resource: MediaResource, resourceData: MediaResourceData, representation: CachedAnimatedStickerFirstFrameRepresentation) -> Signal { return Signal({ subscriber in if let data = try? Data(contentsOf: URL(fileURLWithPath: resourceData.path), options: [.mappedIfSafe]) { return fetchCompressedLottieFirstFrameAJpeg(data: data, size: CGSize(width: CGFloat(representation.width), height: CGFloat(representation.height)), fitzModifier: representation.fitzModifier, cacheKey: "\(resource.id.stringRepresentation)-\(representation.uniqueId)").start(next: { file in @@ -587,7 +560,7 @@ private func fetchAnimatedStickerFirstFrameRepresentation(account: Account, reso |> runOn(Queue.concurrentDefaultQueue()) } -private func fetchAnimatedStickerRepresentation(account: Account, resource: MediaResource, resourceData: MediaResourceData, representation: CachedAnimatedStickerRepresentation) -> Signal { +private func fetchAnimatedStickerRepresentation(resource: MediaResource, resourceData: MediaResourceData, representation: CachedAnimatedStickerRepresentation) -> Signal { return Signal({ subscriber in if let data = try? Data(contentsOf: URL(fileURLWithPath: resourceData.path), options: [.mappedIfSafe]) { return cacheAnimatedStickerFrames(data: data, size: CGSize(width: CGFloat(representation.width), height: CGFloat(representation.height)), fitzModifier: representation.fitzModifier, cacheKey: "\(resource.id.stringRepresentation)-\(representation.uniqueId)").start(next: { value in @@ -602,7 +575,7 @@ private func fetchAnimatedStickerRepresentation(account: Account, resource: Medi |> runOn(Queue.concurrentDefaultQueue()) } -private func fetchVideoStickerRepresentation(account: Account, resource: MediaResource, resourceData: MediaResourceData, representation: CachedVideoStickerRepresentation) -> Signal { +private func fetchVideoStickerRepresentation(resource: MediaResource, resourceData: MediaResourceData, representation: CachedVideoStickerRepresentation) -> Signal { return Signal({ subscriber in return cacheVideoStickerFrames(path: resourceData.path, size: CGSize(width: CGFloat(representation.width), height: CGFloat(representation.height)), cacheKey: "\(resource.id.stringRepresentation)-\(representation.uniqueId)").start(next: { value in subscriber.putNext(value) diff --git a/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift b/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift index 9faa2ba98a..bc2da20523 100755 --- a/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift +++ b/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift @@ -4,7 +4,6 @@ import Display import TelegramCore import SwiftSignalKit import AsyncDisplayKit -import Postbox import StickerResources import AccountContext import AnimatedStickerNode @@ -81,7 +80,7 @@ final class HorizontalStickerGridItemNode: GridItemNode { var stickerItem: StickerPackItem? { if let (_, item, _) = self.currentState { - return StickerPackItem(index: ItemCollectionItemIndex(index: 0, id: 0), file: item.file, indexKeys: []) + return StickerPackItem(index: EngineItemCollectionItemIndex(index: 0, id: 0), file: item.file, indexKeys: []) } else { return nil } diff --git a/submodules/TelegramUI/Sources/NotificationContentContext.swift b/submodules/TelegramUI/Sources/NotificationContentContext.swift index 5fa8c6edf8..022b47055b 100644 --- a/submodules/TelegramUI/Sources/NotificationContentContext.swift +++ b/submodules/TelegramUI/Sources/NotificationContentContext.swift @@ -4,7 +4,6 @@ import UserNotificationsUI import Display import TelegramCore import SwiftSignalKit -import Postbox import TelegramPresentationData import TelegramUIPreferences import AccountContext @@ -87,7 +86,7 @@ public final class NotificationViewControllerImpl { let rootPath = rootPathForBasePath(self.initializationData.appGroupPath) performAppGroupUpgrades(appGroupPath: self.initializationData.appGroupPath, rootPath: rootPath) - TempBox.initializeShared(basePath: rootPath, processType: "notification-content", launchSpecificId: Int64.random(in: Int64.min ... Int64.max)) + EngineTempBox.initializeShared(basePath: rootPath, processType: "notification-content", launchSpecificId: Int64.random(in: Int64.min ... Int64.max)) let logsPath = rootPath + "/logs/notificationcontent-logs" let _ = try? FileManager.default.createDirectory(atPath: logsPath, withIntermediateDirectories: true, attributes: nil) @@ -140,7 +139,7 @@ public final class NotificationViewControllerImpl { return nil }) - sharedAccountContext = SharedAccountContextImpl(mainWindow: nil, sharedContainerPath: self.initializationData.appGroupPath, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, appLockContext: appLockContext, notificationController: nil, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, apiHash: self.initializationData.apiHash, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(self.initializationData.bundleData), externalRequestVerificationStream: .never(), externalRecaptchaRequestVerification: { _, _ in return .never() }, autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider(), deviceModelName: nil, useBetaFeatures: self.initializationData.useBetaFeatures, isICloudEnabled: false), hasInAppPurchases: false, rootPath: rootPath, legacyBasePath: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), firebaseSecretStream: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _, _ in }, appDelegate: nil) + sharedAccountContext = SharedAccountContextImpl(mainWindow: nil, sharedContainerPath: self.initializationData.appGroupPath, basePath: rootPath, encryptionParameters: EngineValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: EngineValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: EngineValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, appLockContext: appLockContext, notificationController: nil, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, apiHash: self.initializationData.apiHash, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(self.initializationData.bundleData), externalRequestVerificationStream: .never(), externalRecaptchaRequestVerification: { _, _ in return .never() }, autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider(), deviceModelName: nil, useBetaFeatures: self.initializationData.useBetaFeatures, isICloudEnabled: false), hasInAppPurchases: false, rootPath: rootPath, legacyBasePath: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), firebaseSecretStream: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _, _ in }, appDelegate: nil) presentationDataPromise.set(sharedAccountContext!.presentationData) } @@ -179,7 +178,7 @@ public final class NotificationViewControllerImpl { return } - let messageId = MessageId(peerId: PeerId(peerIdValue), namespace: messageIdNamespace, id: messageIdId) + let messageId = EngineMessage.Id(peerId: EnginePeer.Id(peerIdValue), namespace: messageIdNamespace, id: messageIdId) if let image = media as? TelegramMediaImage, let thumbnailRepresentation = imageRepresentationLargerThan(image.representations, size: PixelDimensions(width: 120, height: 120)), let largestRepresentation = largestImageRepresentation(image.representations) { let dimensions = largestRepresentation.dimensions diff --git a/submodules/TelegramUI/Sources/OverlayAudioPlayerController.swift b/submodules/TelegramUI/Sources/OverlayAudioPlayerController.swift index ed034ebced..c7fef41747 100644 --- a/submodules/TelegramUI/Sources/OverlayAudioPlayerController.swift +++ b/submodules/TelegramUI/Sources/OverlayAudioPlayerController.swift @@ -1,7 +1,6 @@ import Foundation import UIKit import TelegramCore -import Postbox import Display import SwiftSignalKit import TelegramUIPreferences @@ -15,7 +14,7 @@ final class OverlayAudioPlayerControllerImpl: ViewController, OverlayAudioPlayer private let context: AccountContext let chatLocation: ChatLocation let type: MediaManagerPlayerType - let initialMessageId: MessageId + let initialMessageId: EngineMessage.Id let initialOrder: MusicPlaybackSettingsOrder let playlistLocation: SharedMediaPlaylistLocation? @@ -33,7 +32,7 @@ final class OverlayAudioPlayerControllerImpl: ViewController, OverlayAudioPlayer context: AccountContext, chatLocation: ChatLocation, type: MediaManagerPlayerType, - initialMessageId: MessageId, + initialMessageId: EngineMessage.Id, initialOrder: MusicPlaybackSettingsOrder, playlistLocation: SharedMediaPlaylistLocation? = nil, parentNavigationController: NavigationController? @@ -189,7 +188,7 @@ final class OverlayAudioPlayerControllerImpl: ViewController, OverlayAudioPlayer attributes.append(.Audio(isVoice: false, duration: audioMetadata.duration, title: audioMetadata.title, performer: audioMetadata.performer, waveform: nil)) } - let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: fileId), partialReference: nil, resource: ICloudFileResource(urlData: item.urlData, thumbnail: false), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(item.fileSize), attributes: attributes, alternativeRepresentations: []) + let file = TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: fileId), partialReference: nil, resource: ICloudFileResource(urlData: item.urlData, thumbnail: false), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(item.fileSize), attributes: attributes, alternativeRepresentations: []) let _ = (standaloneUploadedFile( postbox: self.context.account.postbox, diff --git a/submodules/TelegramUI/Sources/ThemeUpdateManager.swift b/submodules/TelegramUI/Sources/ThemeUpdateManager.swift index f6f3f81488..e7baecc1e7 100644 --- a/submodules/TelegramUI/Sources/ThemeUpdateManager.swift +++ b/submodules/TelegramUI/Sources/ThemeUpdateManager.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData @@ -138,7 +137,7 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager { theme = updatedTheme } - return PreferencesEntry(PresentationThemeSettings(theme: theme, themePreferredBaseTheme: current.themePreferredBaseTheme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)) + return EnginePreferencesEntry(PresentationThemeSettings(theme: theme, themePreferredBaseTheme: current.themePreferredBaseTheme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, listsFontSize: current.listsFontSize, chatBubbleSettings: current.chatBubbleSettings, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, reduceMotion: current.reduceMotion)) }) }).start() } diff --git a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift index 3e7f2c5484..5f2f06d4d7 100644 --- a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift +++ b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import TelegramCore import SwiftSignalKit @@ -58,7 +57,7 @@ public struct WallpaperPresentationOptions: OptionSet { public static let blur = WallpaperPresentationOptions(rawValue: 1 << 1) } -public struct PresentationLocalTheme: PostboxCoding, Equatable { +public struct PresentationLocalTheme: EnginePostboxCoding, Equatable { public let title: String public let resource: LocalFileMediaResource public let resolvedWallpaper: TelegramWallpaper? @@ -69,13 +68,13 @@ public struct PresentationLocalTheme: PostboxCoding, Equatable { self.resolvedWallpaper = resolvedWallpaper } - public init(decoder: PostboxDecoder) { + public init(decoder: EnginePostboxDecoder) { self.title = decoder.decodeStringForKey("title", orElse: "") self.resource = decoder.decodeObjectForKey("resource", decoder: { LocalFileMediaResource(decoder: $0) }) as! LocalFileMediaResource self.resolvedWallpaper = decoder.decode(TelegramWallpaperNativeCodable.self, forKey: "wallpaper")?.value } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeString(self.title, forKey: "title") encoder.encodeObject(self.resource, forKey: "resource") if let resolvedWallpaper = self.resolvedWallpaper { @@ -137,12 +136,12 @@ public struct PresentationCloudTheme: Codable, Equatable { } } -public enum PresentationThemeReference: PostboxCoding, Equatable { +public enum PresentationThemeReference: EnginePostboxCoding, Equatable { case builtin(PresentationBuiltinThemeReference) case local(PresentationLocalTheme) case cloud(PresentationCloudTheme) - public init(decoder: PostboxDecoder) { + public init(decoder: EnginePostboxDecoder) { switch decoder.decodeInt32ForKey("v", orElse: 0) { case 0: self = .builtin(PresentationBuiltinThemeReference(rawValue: decoder.decodeInt32ForKey("t", orElse: 0))!) @@ -166,7 +165,7 @@ public enum PresentationThemeReference: PostboxCoding, Equatable { } } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { switch self { case let .builtin(reference): encoder.encodeInt32(0, forKey: "v") @@ -369,8 +368,8 @@ public struct AutomaticThemeSwitchSetting: Codable, Equatable { self.force = try container.decodeIfPresent(Bool.self, forKey: "force") ?? false self.trigger = try container.decode(AutomaticThemeSwitchTrigger.self, forKey: "trigger") - if let themeData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "theme_v2") { - self.theme = PresentationThemeReference(decoder: PostboxDecoder(buffer: MemoryBuffer(data: themeData.data))) + if let themeData = try container.decodeIfPresent(EngineAdaptedPostboxDecoder.RawObjectData.self, forKey: "theme_v2") { + self.theme = PresentationThemeReference(decoder: EnginePostboxDecoder(buffer: EngineMemoryBuffer(data: themeData.data))) } else { self.theme = .builtin(.night) } @@ -382,7 +381,7 @@ public struct AutomaticThemeSwitchSetting: Codable, Equatable { try container.encode(self.force, forKey: "force") try container.encode(self.trigger, forKey: "trigger") - let themeData = PostboxEncoder().encodeObjectToRawData(self.theme) + let themeData = EnginePostboxEncoder().encodeObjectToRawData(self.theme) try container.encode(themeData, forKey: "theme_v2") } } @@ -435,7 +434,7 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable { } } -public struct PresentationThemeAccentColor: PostboxCoding, Equatable { +public struct PresentationThemeAccentColor: EnginePostboxCoding, Equatable { public static func == (lhs: PresentationThemeAccentColor, rhs: PresentationThemeAccentColor) -> Bool { return lhs.index == rhs.index && lhs.baseColor == rhs.baseColor && lhs.accentColor == rhs.accentColor && lhs.bubbleColors == rhs.bubbleColors } @@ -476,7 +475,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { self.themeIndex = themeIndex } - public init(decoder: PostboxDecoder) { + public init(decoder: EnginePostboxDecoder) { self.index = decoder.decodeInt32ForKey("i", orElse: -1) self.baseColor = PresentationThemeBaseColor(rawValue: decoder.decodeInt32ForKey("b", orElse: 0)) ?? .blue self.accentColor = decoder.decodeOptionalInt32ForKey("c").flatMap { UInt32(bitPattern: $0) } @@ -500,7 +499,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { self.themeIndex = decoder.decodeOptionalInt64ForKey("t") } - public func encode(_ encoder: PostboxEncoder) { + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeInt32(self.index, forKey: "i") encoder.encodeInt32(self.baseColor.rawValue, forKey: "b") if let value = self.accentColor { @@ -617,12 +616,12 @@ public struct PresentationThemeSettings: Codable { public var largeEmoji: Bool public var reduceMotion: Bool - private func wallpaperResources(_ wallpaper: TelegramWallpaper) -> [MediaResourceId] { + private func wallpaperResources(_ wallpaper: TelegramWallpaper) -> [EngineRawMediaResourceId] { switch wallpaper { case let .image(representations, _): return representations.map { $0.resource.id } case let .file(file): - var resources: [MediaResourceId] = [] + var resources: [EngineRawMediaResourceId] = [] resources.append(file.file.resource.id) resources.append(contentsOf: file.file.previewRepresentations.map { $0.resource.id }) return resources @@ -631,8 +630,8 @@ public struct PresentationThemeSettings: Codable { } } - public var relatedResources: [MediaResourceId] { - var resources: [MediaResourceId] = [] + public var relatedResources: [EngineRawMediaResourceId] { + var resources: [EngineRawMediaResourceId] = [] for (_, chatWallpaper) in self.themeSpecificChatWallpapers { resources.append(contentsOf: wallpaperResources(chatWallpaper)) } @@ -673,8 +672,8 @@ public struct PresentationThemeSettings: Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: StringCodingKey.self) - if let themeData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "t") { - self.theme = PresentationThemeReference(decoder: PostboxDecoder(buffer: MemoryBuffer(data: themeData.data))) + if let themeData = try container.decodeIfPresent(EngineAdaptedPostboxDecoder.RawObjectData.self, forKey: "t") { + self.theme = PresentationThemeReference(decoder: EnginePostboxDecoder(buffer: EngineMemoryBuffer(data: themeData.data))) } else { self.theme = .builtin(.dayClassic) } @@ -695,10 +694,10 @@ public struct PresentationThemeSettings: Codable { } self.themeSpecificChatWallpapers = mappedThemeSpecificChatWallpapers - let themeSpecificAccentColorsDict = try container.decode([DictionaryKey: AdaptedPostboxDecoder.RawObjectData].self, forKey: "themeSpecificAccentColors") + let themeSpecificAccentColorsDict = try container.decode([DictionaryKey: EngineAdaptedPostboxDecoder.RawObjectData].self, forKey: "themeSpecificAccentColors") var mappedThemeSpecificAccentColors: [Int64: PresentationThemeAccentColor] = [:] for (key, value) in themeSpecificAccentColorsDict { - let innerDecoder = PostboxDecoder(buffer: MemoryBuffer(data: value.data)) + let innerDecoder = EnginePostboxDecoder(buffer: EngineMemoryBuffer(data: value.data)) mappedThemeSpecificAccentColors[key.key] = PresentationThemeAccentColor(decoder: innerDecoder) } self.themeSpecificAccentColors = mappedThemeSpecificAccentColors @@ -719,7 +718,7 @@ public struct PresentationThemeSettings: Codable { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: StringCodingKey.self) - try container.encode(PostboxEncoder().encodeObjectToRawData(self.theme), forKey: "t") + try container.encode(EnginePostboxEncoder().encodeObjectToRawData(self.theme), forKey: "t") var mappedThemePreferredBaseTheme: [Int64: Int64] = [:] for (key, value) in self.themePreferredBaseTheme { @@ -727,9 +726,9 @@ public struct PresentationThemeSettings: Codable { } try container.encode(mappedThemePreferredBaseTheme, forKey: "themePreferredBaseTheme") - var mappedThemeSpecificAccentColors: [DictionaryKey: AdaptedPostboxEncoder.RawObjectData] = [:] + var mappedThemeSpecificAccentColors: [DictionaryKey: EngineAdaptedPostboxEncoder.RawObjectData] = [:] for (key, value) in self.themeSpecificAccentColors { - mappedThemeSpecificAccentColors[DictionaryKey(key)] = PostboxEncoder().encodeObjectToRawData(value) + mappedThemeSpecificAccentColors[DictionaryKey(key)] = EnginePostboxEncoder().encodeObjectToRawData(value) } try container.encode(mappedThemeSpecificAccentColors, forKey: "themeSpecificAccentColors") @@ -802,7 +801,7 @@ public func updatePresentationThemeSettingsInteractively(accountManager: Account } else { currentSettings = PresentationThemeSettings.defaultSettings } - return PreferencesEntry(f(currentSettings)) + return EnginePreferencesEntry(f(currentSettings)) }) } } diff --git a/submodules/TelegramUniversalVideoContent/Sources/YoutubeEmbedImplementation.swift b/submodules/TelegramUniversalVideoContent/Sources/YoutubeEmbedImplementation.swift index 753ea23172..452764e542 100644 --- a/submodules/TelegramUniversalVideoContent/Sources/YoutubeEmbedImplementation.swift +++ b/submodules/TelegramUniversalVideoContent/Sources/YoutubeEmbedImplementation.swift @@ -1,6 +1,5 @@ import Foundation import Display -import Postbox import TelegramCore import AccountContext import WebKit @@ -417,23 +416,23 @@ public class YoutubeEmbedStoryboardMediaResource: TelegramMediaResource { self.url = url } - public required init(decoder: PostboxDecoder) { + public required init(decoder: EnginePostboxDecoder) { self.videoId = decoder.decodeStringForKey("v", orElse: "") self.storyboardId = decoder.decodeInt32ForKey("i", orElse: 0) self.url = decoder.decodeStringForKey("u", orElse: "") } - - public func encode(_ encoder: PostboxEncoder) { + + public func encode(_ encoder: EnginePostboxEncoder) { encoder.encodeString(self.videoId, forKey: "v") encoder.encodeInt32(self.storyboardId, forKey: "i") encoder.encodeString(self.url, forKey: "u") } - - public var id: MediaResourceId { - return MediaResourceId(YoutubeEmbedStoryboardMediaResourceId(videoId: self.videoId, storyboardId: self.storyboardId).uniqueId) + + public var id: EngineRawMediaResourceId { + return EngineRawMediaResourceId(YoutubeEmbedStoryboardMediaResourceId(videoId: self.videoId, storyboardId: self.storyboardId).uniqueId) } - - public func isEqual(to: MediaResource) -> Bool { + + public func isEqual(to: EngineRawMediaResource) -> Bool { if let to = to as? YoutubeEmbedStoryboardMediaResource { return self.videoId == to.videoId && self.storyboardId == to.storyboardId && self.url == to.url } else { @@ -442,17 +441,17 @@ public class YoutubeEmbedStoryboardMediaResource: TelegramMediaResource { } } -public final class YoutubeEmbedStoryboardMediaResourceRepresentation: CachedMediaResourceRepresentation { - public let keepDuration: CachedMediaRepresentationKeepDuration = .shortLived - +public final class YoutubeEmbedStoryboardMediaResourceRepresentation: EngineRawCachedMediaResourceRepresentation { + public let keepDuration: EngineCachedMediaRepresentationKeepDuration = .shortLived + public var uniqueId: String { return "cached" } - + public init() { } - - public func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + + public func isEqual(to: EngineRawCachedMediaResourceRepresentation) -> Bool { if to is YoutubeEmbedStoryboardMediaResourceRepresentation { return true } else { @@ -461,14 +460,14 @@ public final class YoutubeEmbedStoryboardMediaResourceRepresentation: CachedMedi } } -public func fetchYoutubeEmbedStoryboardResource(resource: YoutubeEmbedStoryboardMediaResource) -> Signal { +public func fetchYoutubeEmbedStoryboardResource(resource: YoutubeEmbedStoryboardMediaResource) -> Signal { return Signal { subscriber in subscriber.putNext(.reset) let disposable = MetaDisposable() disposable.set(fetchHttpResource(url: resource.url).start(next: { next in if case let .dataPart(_, data, _, complete) = next, complete { - let tempFile = TempBox.shared.tempFile(fileName: "image.jpg") + let tempFile = EngineTempBox.shared.tempFile(fileName: "image.jpg") if let _ = try? data.write(to: URL(fileURLWithPath: tempFile.path), options: .atomic) { subscriber.putNext(.tempFile(tempFile)) subscriber.putCompletion() diff --git a/submodules/TextFormat/Sources/StringWithAppliedEntities.swift b/submodules/TextFormat/Sources/StringWithAppliedEntities.swift index 29234377d7..c84cd84767 100644 --- a/submodules/TextFormat/Sources/StringWithAppliedEntities.swift +++ b/submodules/TextFormat/Sources/StringWithAppliedEntities.swift @@ -1,6 +1,5 @@ import Foundation import UIKit -import Postbox import TelegramCore import Display import libprisma @@ -127,7 +126,7 @@ private func generateMessageSyntaxHighlight(spec: CachedMessageSyntaxHighlight.S return MessageSyntaxHighlight(entities: entities) } -public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], strings: PresentationStrings? = nil, dateTimeFormat: PresentationDateTimeFormat? = nil, baseColor: UIColor, linkColor: UIColor, baseQuoteTintColor: UIColor? = nil, baseQuoteSecondaryTintColor: UIColor? = nil, baseQuoteTertiaryTintColor: UIColor? = nil, codeBlockTitleColor: UIColor? = nil, codeBlockAccentColor: UIColor? = nil, codeBlockBackgroundColor: UIColor? = nil, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false, message: Message?, entityFiles: [MediaId: TelegramMediaFile] = [:], adjustQuoteFontSize: Bool = false, cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil, paragraphAlignment: NSTextAlignment? = nil) -> NSAttributedString { +public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], strings: PresentationStrings? = nil, dateTimeFormat: PresentationDateTimeFormat? = nil, baseColor: UIColor, linkColor: UIColor, baseQuoteTintColor: UIColor? = nil, baseQuoteSecondaryTintColor: UIColor? = nil, baseQuoteTertiaryTintColor: UIColor? = nil, codeBlockTitleColor: UIColor? = nil, codeBlockAccentColor: UIColor? = nil, codeBlockBackgroundColor: UIColor? = nil, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false, message: EngineRawMessage?, entityFiles: [EngineMedia.Id: TelegramMediaFile] = [:], adjustQuoteFontSize: Bool = false, cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil, paragraphAlignment: NSTextAlignment? = nil) -> NSAttributedString { let baseQuoteTintColor = baseQuoteTintColor ?? baseColor var nsString: NSString? @@ -380,7 +379,7 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti addFontAttributes(range, .smaller) } case let .CustomEmoji(_, fileId): - let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId) + let mediaId = EngineMedia.Id(namespace: Namespaces.Media.CloudFile, id: fileId) var emojiFile: TelegramMediaFile? if let file = message?.associatedMedia[mediaId] as? TelegramMediaFile { emojiFile = file @@ -662,7 +661,7 @@ public func asyncUpdateMessageSyntaxHighlight(engine: TelegramEngine, messageId: } } - if let entry = CodableEntry(CachedMessageSyntaxHighlight(values: updated)) { + if let entry = EngineCodableEntry(CachedMessageSyntaxHighlight(values: updated)) { return engine.messages.storeLocallyDerivedData(messageId: messageId, data: ["code": entry]).start(completed: { subscriber.putCompletion() }) diff --git a/submodules/TonBinding/BUILD b/submodules/TonBinding/BUILD deleted file mode 100644 index e32788b00b..0000000000 --- a/submodules/TonBinding/BUILD +++ /dev/null @@ -1,26 +0,0 @@ -objc_library( - name = "TonBinding", - module_name = "TonBinding", - enable_modules = True, - srcs = glob([ - "Sources/**/*.m", - "Sources/**/*.mm", - ]), - hdrs = glob([ - "Sources/**/*.h", - ]), - copts = [ - "-std=c++14", - ], - includes = [ - "Sources", - ], - deps = [ - "//submodules/SSignalKit/SSignalKit:SSignalKit", - "//third-party/boringssl:crypto", - "//submodules/ton:ton", - ], - visibility = [ - "//visibility:public", - ], -) diff --git a/submodules/TonBinding/Sources/TON.h b/submodules/TonBinding/Sources/TON.h deleted file mode 100644 index 31c0dc812f..0000000000 --- a/submodules/TonBinding/Sources/TON.h +++ /dev/null @@ -1,190 +0,0 @@ -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface TONError : NSObject - -@property (nonatomic, strong, readonly) NSString *text; - -@end - -@interface TONKey : NSObject - -@property (nonatomic, strong, readonly) NSString *publicKey; -@property (nonatomic, strong, readonly) NSData *secret; - -- (instancetype)initWithPublicKey:(NSString *)publicKey secret:(NSData *)secret; - -@end - -@interface TONTransactionId : NSObject - -@property (nonatomic, readonly) int64_t lt; -@property (nonatomic, strong, readonly) NSData * _Nonnull transactionHash; - -- (instancetype)initWithLt:(int64_t)lt transactionHash:(NSData * _Nonnull)transactionHash; - -@end - -@interface TONAccountState : NSObject - -@property (nonatomic, readonly) bool isInitialized; -@property (nonatomic, readonly) bool isRWallet; -@property (nonatomic, readonly) int64_t balance; -@property (nonatomic, readonly) int64_t unlockedBalance; - -@property (nonatomic, readonly) int32_t seqno; -@property (nonatomic, strong, readonly) TONTransactionId * _Nullable lastTransactionId; -@property (nonatomic, readonly) int64_t syncUtime; - -- (instancetype)initWithIsInitialized:(bool)isInitialized isRWallet:(bool)isRWallet balance:(int64_t)balance unlockedBalance:(int64_t)unlockedBalance seqno:(int32_t)seqno lastTransactionId:(TONTransactionId * _Nullable)lastTransactionId syncUtime:(int64_t)syncUtime; - -@end - -@protocol TONTransactionMessageContents - -@end - -@interface TONTransactionMessageContentsRawData : NSObject - -@property (nonatomic, strong, readonly) NSData * _Nonnull data; - -- (instancetype)initWithData:(NSData * _Nonnull)data; - -@end - -@interface TONTransactionMessageContentsPlainText : NSObject - -@property (nonatomic, strong, readonly) NSString * _Nonnull text; - -- (instancetype)initWithText:(NSString * _Nonnull)text; - -@end - -@interface TONEncryptedData : NSObject - -@property (nonatomic, strong, readonly) NSString * _Nonnull sourceAddress; -@property (nonatomic, strong, readonly) NSData * _Nonnull data; - -- (instancetype)initWithSourceAddress:(NSString * _Nonnull)sourceAddress data:(NSData * _Nonnull)data; - -@end - -@interface TONTransactionMessageContentsEncryptedText : NSObject - -@property (nonatomic, strong, readonly) TONEncryptedData * _Nonnull encryptedData; - -- (instancetype)initWithEncryptedData:(TONEncryptedData * _Nonnull)encryptedData; - -@end - -@interface TONTransactionMessage : NSObject - -@property (nonatomic, readonly) int64_t value; -@property (nonatomic, strong, readonly) NSString * _Nonnull source; -@property (nonatomic, strong, readonly) NSString * _Nonnull destination; -@property (nonatomic, strong, readonly) id _Nonnull contents; -@property (nonatomic, strong, readonly) NSData * _Nonnull bodyHash; - -- (instancetype)initWithValue:(int64_t)value source:(NSString * _Nonnull)source destination:(NSString * _Nonnull)destination contents:(id _Nonnull)contents bodyHash:(NSData * _Nonnull)bodyHash; - -@end - -@interface TONTransaction : NSObject - -@property (nonatomic, strong, readonly) NSData * _Nonnull data; -@property (nonatomic, strong, readonly) TONTransactionId * _Nonnull transactionId; -@property (nonatomic, readonly) int64_t timestamp; -@property (nonatomic, readonly) int64_t storageFee; -@property (nonatomic, readonly) int64_t otherFee; -@property (nonatomic, strong, readonly) TONTransactionMessage * _Nullable inMessage; -@property (nonatomic, strong, readonly) NSArray * _Nonnull outMessages; - -- (instancetype)initWithData:(NSData * _Nonnull)data transactionId:(TONTransactionId * _Nonnull)transactionId timestamp:(int64_t)timestamp storageFee:(int64_t)storageFee otherFee:(int64_t)otherFee inMessage:(TONTransactionMessage * _Nullable)inMessage outMessages:(NSArray * _Nonnull)outMessages; - -@end - -@interface TONExternalRequest : NSObject - -@property (nonatomic, strong, readonly) NSData * _Nonnull data; -@property (nonatomic, copy, readonly) void (^onResult)(NSData * _Nullable, NSString * _Nullable); - -- (instancetype)initWithData:(NSData * _Nonnull)data onResult:(void (^)(NSData * _Nullable, NSString * _Nullable))onResult; - -@end - -@interface TONFees : NSObject - -@property (nonatomic, readonly) int64_t inFwdFee; -@property (nonatomic, readonly) int64_t storageFee; -@property (nonatomic, readonly) int64_t gasFee; -@property (nonatomic, readonly) int64_t fwdFee; - -- (instancetype)initWithInFwdFee:(int64_t)inFwdFee storageFee:(int64_t)storageFee gasFee:(int64_t)gasFee fwdFee:(int64_t)fwdFee; - -@end - -@interface TONSendGramsQueryFees : NSObject - -@property (nonatomic, strong, readonly) TONFees * _Nonnull sourceFees; -@property (nonatomic, strong, readonly) NSArray * _Nonnull destinationFees; - -- (instancetype)initWithSourceFees:(TONFees * _Nonnull)sourceFees destinationFees:(NSArray * _Nonnull)destinationFees; - -@end - -@interface TONPreparedSendGramsQuery : NSObject - -@property (nonatomic, readonly) int64_t queryId; -@property (nonatomic, readonly) int64_t validUntil; -@property (nonatomic, strong, readonly) NSData * _Nonnull bodyHash; - -- (instancetype)initWithQueryId:(int64_t)queryId validUntil:(int64_t)validUntil bodyHash:(NSData *)bodyHash; - -@end - -@interface TONSendGramsResult : NSObject - -@property (nonatomic, readonly) int64_t sentUntil; -@property (nonatomic, strong, readonly) NSData * _Nonnull bodyHash; - -- (instancetype)initWithSentUntil:(int64_t)sentUntil bodyHash:(NSData *)bodyHash; - -@end - -@interface TONValidatedConfig : NSObject - -@property (nonatomic, readonly) int64_t defaultWalletId; - -- (instancetype)initWithDefaultWalletId:(int64_t)defaultWalletId; - -@end - -@interface TON : NSObject - -- (instancetype)initWithKeystoreDirectory:(NSString *)keystoreDirectory config:(NSString *)config blockchainName:(NSString *)blockchainName performExternalRequest:(void (^)(TONExternalRequest * _Nonnull))performExternalRequest enableExternalRequests:(bool)enableExternalRequests syncStateUpdated:(void (^)(float))syncStateUpdated; - -- (SSignal *)updateConfig:(NSString *)config blockchainName:(NSString *)blockchainName; -- (SSignal *)validateConfig:(NSString *)config blockchainName:(NSString *)blockchainName; - -- (SSignal *)createKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword; -- (SSignal *)getWalletAccountAddressWithPublicKey:(NSString *)publicKey initialWalletId:(int64_t)initialWalletId rwalletInitialPublicKey:(NSString * _Nullable)rwalletInitialPublicKey; -- (SSignal *)getAccountStateWithAddress:(NSString *)accountAddress; -- (SSignal *)generateSendGramsQueryFromKey:(TONKey *)key localPassword:(NSData *)localPassword fromAddress:(NSString *)fromAddress toAddress:(NSString *)address amount:(int64_t)amount comment:(NSData *)comment encryptComment:(bool)encryptComment forceIfDestinationNotInitialized:(bool)forceIfDestinationNotInitialized timeout:(int32_t)timeout randomId:(int64_t)randomId; -- (SSignal *)generateFakeSendGramsQueryFromAddress:(NSString *)fromAddress toAddress:(NSString *)address amount:(int64_t)amount comment:(NSData *)comment encryptComment:(bool)encryptComment forceIfDestinationNotInitialized:(bool)forceIfDestinationNotInitialized timeout:(int32_t)timeout; -- (SSignal *)estimateSendGramsQueryFees:(TONPreparedSendGramsQuery *)preparedQuery; -- (SSignal *)commitPreparedSendGramsQuery:(TONPreparedSendGramsQuery *)preparedQuery; -- (SSignal *)exportKey:(TONKey *)key localPassword:(NSData *)localPassword; -- (SSignal *)importKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword wordList:(NSArray *)wordList; -- (SSignal *)deleteKey:(TONKey *)key; -- (SSignal *)deleteAllKeys; -- (SSignal *)getTransactionListWithAddress:(NSString * _Nonnull)address lt:(int64_t)lt hash:(NSData * _Nonnull)hash; -- (SSignal *)decryptMessagesWithKey:(TONKey * _Nonnull)key localPassword:(NSData * _Nonnull)localPassword messages:(NSArray * _Nonnull)messages; - -- (NSData *)encrypt:(NSData *)decryptedData secret:(NSData *)data; -- (NSData * __nullable)decrypt:(NSData *)encryptedData secret:(NSData *)data; - -@end - -NS_ASSUME_NONNULL_END diff --git a/submodules/TonBinding/Sources/TON.mm b/submodules/TonBinding/Sources/TON.mm deleted file mode 100644 index 1ff7dc656d..0000000000 --- a/submodules/TonBinding/Sources/TON.mm +++ /dev/null @@ -1,1227 +0,0 @@ -#import "TON.h" - -#import "tonlib/Client.h" - -static td::SecureString makeSecureString(NSData * _Nonnull data) { - if (data == nil || data.length == 0) { - return td::SecureString(); - } else { - return td::SecureString((const char *)data.bytes, (size_t)data.length); - } -} - -static std::string makeString(NSData * _Nonnull data) { - if (data == nil || data.length == 0) { - return std::string(); - } else { - return std::string((const char *)data.bytes, ((const char *)data.bytes) + data.length); - } -} - -static NSData * _Nonnull makeData(std::string &string) { - if (string.size() == 0) { - return [NSData data]; - } else { - return [[NSData alloc] initWithBytes:string.data() length:string.size()]; - } -} - -static NSString * _Nullable readString(std::string &string) { - if (string.size() == 0) { - return @""; - } else { - return [[NSString alloc] initWithBytes:string.data() length:string.size() encoding:NSUTF8StringEncoding]; - } -} - -static NSData * _Nullable readSecureString(td::SecureString &string) { - if (string.size() == 0) { - return [NSData data]; - } else { - return [[NSData alloc] initWithBytes:string.data() length:string.size()]; - } -} - -static TONTransactionMessage * _Nullable parseTransactionMessage(tonlib_api::object_ptr &message) { - if (message == nullptr) { - return nil; - } - NSString *source = readString(message->source_->account_address_); - NSString *destination = readString(message->destination_->account_address_); - - id contents = nil; - if (message->msg_data_->get_id() == tonlib_api::msg_dataRaw::ID) { - auto msgData = tonlib_api::move_object_as(message->msg_data_); - contents = [[TONTransactionMessageContentsRawData alloc] initWithData:makeData(msgData->body_)]; - } else if (message->msg_data_->get_id() == tonlib_api::msg_dataText::ID) { - auto msgData = tonlib_api::move_object_as(message->msg_data_); - NSString *text = readString(msgData->text_); - if (text == nil) { - contents = [[TONTransactionMessageContentsPlainText alloc] initWithText:@""]; - } else { - contents = [[TONTransactionMessageContentsPlainText alloc] initWithText:text]; - } - } else if (message->msg_data_->get_id() == tonlib_api::msg_dataDecryptedText::ID) { - auto msgData = tonlib_api::move_object_as(message->msg_data_); - NSString *text = readString(msgData->text_); - if (text == nil) { - contents = [[TONTransactionMessageContentsPlainText alloc] initWithText:@""]; - } else { - contents = [[TONTransactionMessageContentsPlainText alloc] initWithText:text]; - } - } else if (message->msg_data_->get_id() == tonlib_api::msg_dataEncryptedText::ID) { - auto msgData = tonlib_api::move_object_as(message->msg_data_); - TONEncryptedData *encryptedData = [[TONEncryptedData alloc] initWithSourceAddress:source data:makeData(msgData->text_)]; - contents = [[TONTransactionMessageContentsEncryptedText alloc] initWithEncryptedData:encryptedData]; - } else { - contents = [[TONTransactionMessageContentsRawData alloc] initWithData:[NSData data]]; - } - - if (source == nil || destination == nil) { - return nil; - } - return [[TONTransactionMessage alloc] initWithValue:message->value_ source:source destination:destination contents:contents bodyHash:makeData(message->body_hash_)]; -} - -@implementation TONKey - -- (instancetype)initWithPublicKey:(NSString *)publicKey secret:(NSData *)secret { - self = [super init]; - if (self != nil) { - _publicKey = publicKey; - _secret = secret; - } - return self; -} - -@end - -@implementation TONAccountState - -- (instancetype)initWithIsInitialized:(bool)isInitialized isRWallet:(bool)isRWallet balance:(int64_t)balance unlockedBalance:(int64_t)unlockedBalance seqno:(int32_t)seqno lastTransactionId:(TONTransactionId * _Nullable)lastTransactionId syncUtime:(int64_t)syncUtime { - self = [super init]; - if (self != nil) { - _isInitialized = isInitialized; - _isRWallet = isRWallet; - _balance = balance; - _unlockedBalance = unlockedBalance; - _seqno = seqno; - _lastTransactionId = lastTransactionId; - _syncUtime = syncUtime; - } - return self; -} - -@end - -@implementation TONTransactionId - -- (instancetype)initWithLt:(int64_t)lt transactionHash:(NSData *)transactionHash { - self = [super init]; - if (self != nil) { - _lt = lt; - _transactionHash = transactionHash; - } - return self; -} - -@end - -@implementation TONTransactionMessageContentsRawData - -- (instancetype)initWithData:(NSData * _Nonnull)data { - self = [super init]; - if (self != nil) { - _data = data; - } - return self; -} - -@end - -@implementation TONTransactionMessageContentsPlainText - -- (instancetype)initWithText:(NSString * _Nonnull)text { - self = [super init]; - if (self != nil) { - _text = text; - } - return self; -} - -@end - -@implementation TONTransactionMessageContentsEncryptedText - -- (instancetype)initWithEncryptedData:(TONEncryptedData * _Nonnull)encryptedData { - self = [super init]; - if (self != nil) { - _encryptedData = encryptedData; - } - return self; -} - -@end - -@implementation TONTransactionMessage - -- (instancetype)initWithValue:(int64_t)value source:(NSString * _Nonnull)source destination:(NSString * _Nonnull)destination contents:(id _Nonnull)contents bodyHash:(NSData * _Nonnull)bodyHash { - self = [super init]; - if (self != nil) { - _value = value; - _source = source; - _destination = destination; - _contents = contents; - _bodyHash = bodyHash; - } - return self; -} - -@end - -@implementation TONTransaction - -- (instancetype)initWithData:(NSData * _Nonnull)data transactionId:(TONTransactionId * _Nonnull)transactionId timestamp:(int64_t)timestamp storageFee:(int64_t)storageFee otherFee:(int64_t)otherFee inMessage:(TONTransactionMessage * _Nullable)inMessage outMessages:(NSArray * _Nonnull)outMessages { - self = [super init]; - if (self != nil) { - _data = data; - _transactionId = transactionId; - _timestamp = timestamp; - _storageFee = storageFee; - _otherFee = otherFee; - _inMessage = inMessage; - _outMessages = outMessages; - } - return self; -} - -@end - -@implementation TONExternalRequest - -- (instancetype)initWithData:(NSData * _Nonnull)data onResult:(void (^)(NSData * _Nullable, NSString * _Nullable))onResult { - self = [super init]; - if (self != nil) { - _data = data; - _onResult = [onResult copy]; - } - return self; -} - -@end - -@implementation TONFees - -- (instancetype)initWithInFwdFee:(int64_t)inFwdFee storageFee:(int64_t)storageFee gasFee:(int64_t)gasFee fwdFee:(int64_t)fwdFee { - self = [super init]; - if (self != nil) { - _inFwdFee = inFwdFee; - _storageFee = storageFee; - _gasFee = gasFee; - _fwdFee = fwdFee; - } - return self; -} - -@end - -@implementation TONSendGramsQueryFees - -- (instancetype)initWithSourceFees:(TONFees * _Nonnull)sourceFees destinationFees:(NSArray * _Nonnull)destinationFees { - self = [super init]; - if (self != nil) { - _sourceFees = sourceFees; - _destinationFees = destinationFees; - } - return self; -} - -@end - -@implementation TONPreparedSendGramsQuery - -- (instancetype)initWithQueryId:(int64_t)queryId validUntil:(int64_t)validUntil bodyHash:(NSData *)bodyHash { - self = [super init]; - if (self != nil) { - _queryId = queryId; - _validUntil = validUntil; - _bodyHash = bodyHash; - } - return self; -} - -@end - -@implementation TONSendGramsResult - -- (instancetype)initWithSentUntil:(int64_t)sentUntil bodyHash:(NSData *)bodyHash { - self = [super init]; - if (self != nil) { - _sentUntil = sentUntil; - _bodyHash = bodyHash; - } - return self; -} - -@end - -@implementation TONValidatedConfig - -- (instancetype)initWithDefaultWalletId:(int64_t)defaultWalletId { - self = [super init]; - if (self != nil) { - _defaultWalletId = defaultWalletId; - } - return self; -} - -@end - -@implementation TONEncryptedData - -- (instancetype)initWithSourceAddress:(NSString * _Nonnull)sourceAddress data:(NSData * _Nonnull)data { - self = [super init]; - if (self != nil) { - _sourceAddress = sourceAddress; - _data = data; - } - return self; -} - -@end - -using tonlib_api::make_object; - -@interface TONReceiveThreadParams : NSObject - -@property (nonatomic, readonly) std::shared_ptr client; -@property (nonatomic, copy, readonly) void (^received)(tonlib::Client::Response &); - -@end - -@implementation TONReceiveThreadParams - -- (instancetype)initWithClient:(std::shared_ptr)client received:(void (^)(tonlib::Client::Response &))received { - self = [super init]; - if (self != nil) { - _client = client; - _received = [received copy]; - } - return self; -} - -@end - -@interface TONRequestHandler : NSObject - -@property (nonatomic, copy, readonly) void (^completion)(tonlib_api::object_ptr &); - -@end - -@implementation TONRequestHandler - -- (instancetype)initWithCompletion:(void (^)(tonlib_api::object_ptr &))completion { - self = [super init]; - if (self != nil) { - _completion = [completion copy]; - } - return self; -} - -@end - -@implementation TONError - -- (instancetype)initWithText:(NSString *)text { - self = [super init]; - if (self != nil) { - _text = text; - } - return self; -} - -@end - -typedef enum { - TONInitializationStatusInitializing, - TONInitializationStatusReady, - TONInitializationStatusError -} TONInitializationStatus; - -@interface TON () { - std::shared_ptr _client; - uint64_t _nextRequestId; - NSLock *_requestHandlersLock; - NSMutableDictionary *_requestHandlers; - SPipe *_initializedStatus; - NSMutableSet *_sendGramRandomIds; - SQueue *_queue; - bool _enableExternalRequests; -} - -@end - -@implementation TON - -+ (void)receiveThread:(TONReceiveThreadParams *)params { - while (true) { - auto response = params.client->receive(1000); - if (response.object) { - params.received(response); - } - } -} - -- (instancetype)initWithKeystoreDirectory:(NSString *)keystoreDirectory config:(NSString *)config blockchainName:(NSString *)blockchainName performExternalRequest:(void (^)(TONExternalRequest * _Nonnull))performExternalRequest enableExternalRequests:(bool)enableExternalRequests syncStateUpdated:(void (^)(float))syncStateUpdated { - self = [super init]; - if (self != nil) { - _queue = [SQueue mainQueue]; - _requestHandlersLock = [[NSLock alloc] init]; - _requestHandlers = [[NSMutableDictionary alloc] init]; - _initializedStatus = [[SPipe alloc] initWithReplay:true]; - _initializedStatus.sink(@(TONInitializationStatusInitializing)); - _nextRequestId = 1; - _sendGramRandomIds = [[NSMutableSet alloc] init]; - _enableExternalRequests = enableExternalRequests; - - _client = std::make_shared(); - - [self setupLogging]; - - std::weak_ptr weakClient = _client; - - NSLock *requestHandlersLock = _requestHandlersLock; - NSMutableDictionary *requestHandlers = _requestHandlers; - NSThread *thread = [[NSThread alloc] initWithTarget:[self class] selector:@selector(receiveThread:) object:[[TONReceiveThreadParams alloc] initWithClient:_client received:^(tonlib::Client::Response &response) { - if (response.object->get_id() == tonlib_api::updateSendLiteServerQuery::ID) { - auto result = tonlib_api::move_object_as(response.object); - int64_t requestId = result->id_; - NSData *data = makeData(result->data_); - if (performExternalRequest) { - performExternalRequest([[TONExternalRequest alloc] initWithData:data onResult:^(NSData * _Nullable result, NSString * _Nullable error) { - auto strongClient = weakClient.lock(); - if (strongClient != nullptr) { - if (result != nil) { - auto query = make_object( - requestId, - makeString(result) - ); - strongClient->send({ 1, std::move(query) }); - } else if (error != nil) { - auto query = make_object( - requestId, - make_object( - 400, - error.UTF8String - ) - ); - strongClient->send({ 1, std::move(query) }); - } - } - }]); - } - return; - } else if (response.object->get_id() == tonlib_api::updateSyncState::ID) { - auto result = tonlib_api::move_object_as(response.object); - if (result->sync_state_->get_id() == tonlib_api::syncStateInProgress::ID) { - auto syncStateInProgress = tonlib_api::move_object_as(result->sync_state_); - int32_t currentDelta = syncStateInProgress->current_seqno_ - syncStateInProgress->from_seqno_; - int32_t fullDelta = syncStateInProgress->to_seqno_ - syncStateInProgress->from_seqno_; - if (currentDelta > 0 && fullDelta > 0) { - float progress = ((float)currentDelta) / ((float)fullDelta); - syncStateUpdated(progress); - } else { - syncStateUpdated(0.0f); - } - } else if (result->sync_state_->get_id() == tonlib_api::syncStateDone::ID) { - syncStateUpdated(1.0f); - } - return; - } - NSNumber *requestId = @(response.id); - [requestHandlersLock lock]; - TONRequestHandler *handler = requestHandlers[requestId]; - [requestHandlers removeObjectForKey:requestId]; - [requestHandlersLock unlock]; - if (handler != nil) { - handler.completion(response.object); - } - }]]; - [thread start]; - - [[NSFileManager defaultManager] createDirectoryAtPath:keystoreDirectory withIntermediateDirectories:true attributes:nil error:nil]; - - SPipe *initializedStatus = _initializedStatus; - [[self requestInitWithConfigString:config blockchainName:blockchainName keystoreDirectory:keystoreDirectory enableExternalRequests:enableExternalRequests] startWithNext:nil error:^(id error) { - NSString *errorText = @"Unknown error"; - if ([error isKindOfClass:[TONError class]]) { - errorText = ((TONError *)error).text; - } - initializedStatus.sink(@(TONInitializationStatusError)); - } completed:^{ - initializedStatus.sink(@(TONInitializationStatusReady)); - }]; - } - return self; -} - -- (void)setupLogging { -#if DEBUG - auto query = make_object( - make_object() - ); - _client->execute({ INT16_MAX + 1, std::move(query) }); -#else - auto query = make_object( - make_object() - ); - _client->execute({ INT16_MAX + 1, std::move(query) }); -#endif -} - -- (NSData * __nullable)decrypt:(NSData *)encryptedData secret:(NSData *)data { - auto query = make_object(makeSecureString(encryptedData), makeSecureString(data)); - tonlib_api::object_ptr result = _client->execute({ INT16_MAX + 1, std::move(query) }).object; - - if (result->get_id() == tonlib_api::error::ID) { - return nil; - } else { - tonlib_api::object_ptr value = tonlib_api::move_object_as(result); - return readSecureString(value->bytes_); - } -} -- (NSData *)encrypt:(NSData *)decryptedData secret:(NSData *)data { - auto query = make_object(makeSecureString(decryptedData), makeSecureString(data)); - tonlib_api::object_ptr result = _client->execute({ INT16_MAX + 1, std::move(query) }).object; - - tonlib_api::object_ptr value = tonlib_api::move_object_as(result); - - return readSecureString(value->bytes_); -} - -- (SSignal *)requestInitWithConfigString:(NSString *)configString blockchainName:(NSString *)blockchainName keystoreDirectory:(NSString *)keystoreDirectory enableExternalRequests:(bool)enableExternalRequests { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else { - [subscriber putCompletion]; - } - }]; - - bool ignoreCache = false; - #if DEBUG - ignoreCache = true; - #endif - - auto query = make_object(make_object( - make_object( - configString.UTF8String, - blockchainName.UTF8String, - enableExternalRequests, - ignoreCache - ), - make_object( - keystoreDirectory.UTF8String - ) - )); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)updateConfig:(NSString *)config blockchainName:(NSString *)blockchainName { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else { - [subscriber putCompletion]; - } - }]; - - auto query = make_object( - make_object( - config.UTF8String, - blockchainName.UTF8String, - _enableExternalRequests, - false - ) - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)validateConfig:(NSString *)config blockchainName:(NSString *)blockchainName { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::options_configInfo::ID) { - auto result = tonlib_api::move_object_as(object); - [subscriber putNext:[[TONValidatedConfig alloc] initWithDefaultWalletId:result->default_wallet_id_]]; - [subscriber putCompletion]; - } else { - assert(false); - } - }]; - - auto query = make_object( - make_object( - config.UTF8String, - blockchainName.UTF8String, - _enableExternalRequests, - false - ) - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)createKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::key::ID) { - auto result = tonlib_api::move_object_as(object); - NSString *publicKey = [[NSString alloc] initWithData:[[NSData alloc] initWithBytes:result->public_key_.data() length:result->public_key_.length()] encoding:NSUTF8StringEncoding]; - if (publicKey == nil) { - [subscriber putError:[[TONError alloc] initWithText:@"Error decoding UTF8 string in createKeyWithLocalPassword"]]; - return; - } - NSData *secret = [[NSData alloc] initWithBytes:result->secret_.data() length:result->secret_.length()]; - [subscriber putNext:[[TONKey alloc] initWithPublicKey:publicKey secret:secret]]; - [subscriber putCompletion]; - } else { - assert(false); - } - }]; - - auto query = make_object( - makeSecureString(localPassword), - makeSecureString(mnemonicPassword), - td::SecureString() - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)getWalletAccountAddressWithPublicKey:(NSString *)publicKey initialWalletId:(int64_t)initialWalletId rwalletInitialPublicKey:(NSString * _Nullable)rwalletInitialPublicKey { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - NSData *publicKeyData = [publicKey dataUsingEncoding:NSUTF8StringEncoding]; - if (publicKeyData == nil) { - [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in getWalletAccountAddressWithPublicKey"]]; - return [[SBlockDisposable alloc] initWithBlock:^{}]; - } - - NSData *rwalletInitialPublicKeyData = nil; - if (rwalletInitialPublicKey != nil) { - rwalletInitialPublicKeyData = [rwalletInitialPublicKey dataUsingEncoding:NSUTF8StringEncoding]; - if (rwalletInitialPublicKeyData == nil) { - [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string for rwalletInitialPublicKey in getWalletAccountAddressWithPublicKey"]]; - return [[SBlockDisposable alloc] initWithBlock:^{}]; - } - } - - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::accountAddress::ID) { - auto result = tonlib_api::move_object_as(object); - [subscriber putNext:[[NSString alloc] initWithUTF8String:result->account_address_.c_str()]]; - [subscriber putCompletion]; - } else { - assert(false); - } - }]; - - tonlib_api::object_ptr initialAccountState; - - std::int32_t revision; - if (rwalletInitialPublicKey != nil) { - initialAccountState = make_object( - makeString(rwalletInitialPublicKeyData), - makeString(publicKeyData), - initialWalletId - ); - revision = -1; - } else { - initialAccountState = tonlib_api::move_object_as(make_object( - makeString(publicKeyData), - initialWalletId - )); - revision = 1; - } - - auto query = make_object( - tonlib_api::move_object_as(initialAccountState), - revision - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)getAccountStateWithAddress:(NSString *)accountAddress { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::fullAccountState::ID) { - auto fullAccountState = tonlib_api::move_object_as(object); - int32_t seqNo = -1; - - bool isRWallet = false; - int64_t unlockedBalance = INT64_MAX; - - if (fullAccountState->account_state_->get_id() == tonlib_api::uninited_accountState::ID) { - seqNo = -1; - } else if (fullAccountState->account_state_->get_id() == tonlib_api::wallet_v3_accountState::ID) { - auto v3AccountState = tonlib_api::move_object_as(fullAccountState->account_state_); - seqNo = v3AccountState->seqno_; - } else if (fullAccountState->account_state_->get_id() == tonlib_api::rwallet_accountState::ID) { - auto rwalletAccountState = tonlib_api::move_object_as(fullAccountState->account_state_); - isRWallet = true; - unlockedBalance = rwalletAccountState->unlocked_balance_; - seqNo = rwalletAccountState->seqno_; - }else { - [subscriber putError:[[TONError alloc] initWithText:@"Unknown type"]]; - return; - } - - TONTransactionId *lastTransactionId = nil; - if (fullAccountState->last_transaction_id_ != nullptr) { - lastTransactionId = [[TONTransactionId alloc] initWithLt:fullAccountState->last_transaction_id_->lt_ transactionHash:makeData(fullAccountState->last_transaction_id_->hash_)]; - } - [subscriber putNext:[[TONAccountState alloc] initWithIsInitialized:false isRWallet:isRWallet balance:fullAccountState->balance_ unlockedBalance:unlockedBalance seqno:-1 lastTransactionId:lastTransactionId syncUtime:fullAccountState->sync_utime_]]; - [subscriber putCompletion]; - } else { - assert(false); - } - }]; - - auto query = make_object(make_object(accountAddress.UTF8String)); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)generateSendGramsQueryFromKey:(TONKey *)key localPassword:(NSData *)localPassword fromAddress:(NSString *)fromAddress toAddress:(NSString *)address amount:(int64_t)amount comment:(NSData *)comment encryptComment:(bool)encryptComment forceIfDestinationNotInitialized:(bool)forceIfDestinationNotInitialized timeout:(int32_t)timeout randomId:(int64_t)randomId { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - if ([_sendGramRandomIds containsObject:@(randomId)]) { - [_sendGramRandomIds addObject:@(randomId)]; - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - } - - NSData *publicKeyData = [key.publicKey dataUsingEncoding:NSUTF8StringEncoding]; - if (publicKeyData == nil) { - [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in sendGramsFromKey"]]; - return [[SBlockDisposable alloc] initWithBlock:^{}]; - } - - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - __weak TON *weakSelf = self; - SQueue *queue = _queue; - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - [queue dispatch:^{ - __strong TON *strongSelf = weakSelf; - if (strongSelf != nil) { - [_sendGramRandomIds removeObject:@(randomId)]; - } - }]; - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::query_info::ID) { - auto result = tonlib_api::move_object_as(object); - TONPreparedSendGramsQuery *preparedQuery = [[TONPreparedSendGramsQuery alloc] initWithQueryId:result->id_ validUntil:result->valid_until_ bodyHash:makeData(result->body_hash_)]; - [subscriber putNext:preparedQuery]; - [subscriber putCompletion]; - } else { - [subscriber putCompletion]; - } - }]; - - tonlib_api::object_ptr inputMessageData; - if (encryptComment && comment.length != 0) { - inputMessageData = make_object( - makeString(comment) - ); - } else { - inputMessageData = make_object( - makeString(comment) - ); - } - std::vector > inputMessages; - inputMessages.push_back(make_object( - make_object(address.UTF8String), - makeString([NSData data]), - amount, - tonlib_api::move_object_as(inputMessageData) - )); - auto inputAction = make_object( - std::move(inputMessages), - forceIfDestinationNotInitialized - ); - - auto query = make_object( - make_object( - make_object( - makeString(publicKeyData), - makeSecureString(key.secret) - ), - makeSecureString(localPassword) - ), - make_object(fromAddress.UTF8String), - timeout, - tonlib_api::move_object_as(inputAction), - nil - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)generateFakeSendGramsQueryFromAddress:(NSString *)fromAddress toAddress:(NSString *)address amount:(int64_t)amount comment:(NSData *)comment encryptComment:(bool)encryptComment forceIfDestinationNotInitialized:(bool)forceIfDestinationNotInitialized timeout:(int32_t)timeout { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::query_info::ID) { - auto result = tonlib_api::move_object_as(object); - TONPreparedSendGramsQuery *preparedQuery = [[TONPreparedSendGramsQuery alloc] initWithQueryId:result->id_ validUntil:result->valid_until_ bodyHash:makeData(result->body_hash_)]; - [subscriber putNext:preparedQuery]; - [subscriber putCompletion]; - } else { - [subscriber putCompletion]; - } - }]; - - tonlib_api::object_ptr inputMessageData; - if (encryptComment && comment.length != 0) { - inputMessageData = make_object( - makeString(comment) - ); - } else { - inputMessageData = make_object( - makeString(comment) - ); - } - std::vector > inputMessages; - inputMessages.push_back(make_object( - make_object(address.UTF8String), - makeString([NSData data]), - amount, - tonlib_api::move_object_as(inputMessageData) - )); - auto inputAction = make_object( - std::move(inputMessages), - forceIfDestinationNotInitialized - ); - - auto query = make_object( - make_object(), - make_object(fromAddress.UTF8String), - timeout, - tonlib_api::move_object_as(inputAction), - nil - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)estimateSendGramsQueryFees:(TONPreparedSendGramsQuery *)preparedQuery { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::query_fees::ID) { - auto result = tonlib_api::move_object_as(object); - TONFees *sourceFees = [[TONFees alloc] initWithInFwdFee:result->source_fees_->in_fwd_fee_ storageFee:result->source_fees_->storage_fee_ gasFee:result->source_fees_->gas_fee_ fwdFee:result->source_fees_->fwd_fee_]; - NSMutableArray *destinationFees = [[NSMutableArray alloc] init]; - for (auto &fee : result->destination_fees_) { - TONFees *destinationFee = [[TONFees alloc] initWithInFwdFee:fee->in_fwd_fee_ storageFee:fee->storage_fee_ gasFee:fee->gas_fee_ fwdFee:fee->fwd_fee_]; - [destinationFees addObject:destinationFee]; - } - - [subscriber putNext:[[TONSendGramsQueryFees alloc] initWithSourceFees:sourceFees destinationFees:destinationFees]]; - [subscriber putCompletion]; - } else { - assert(false); - } - }]; - - auto query = make_object( - preparedQuery.queryId, - true - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)commitPreparedSendGramsQuery:(TONPreparedSendGramsQuery *)preparedQuery { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::ok::ID) { - [subscriber putCompletion]; - } else { - assert(false); - } - }]; - - auto query = make_object( - preparedQuery.queryId - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)exportKey:(TONKey *)key localPassword:(NSData *)localPassword { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - NSData *publicKeyData = [key.publicKey dataUsingEncoding:NSUTF8StringEncoding]; - if (publicKeyData == nil) { - [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in exportKey"]]; - return [[SBlockDisposable alloc] initWithBlock:^{}]; - } - - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::exportedKey::ID) { - auto result = tonlib_api::move_object_as(object); - NSMutableArray *wordList = [[NSMutableArray alloc] init]; - for (auto &it : result->word_list_) { - NSString *string = [[NSString alloc] initWithData:[[NSData alloc] initWithBytes:it.data() length:it.size()] encoding:NSUTF8StringEncoding]; - if (string == nil) { - [subscriber putError:[[TONError alloc] initWithText:@"Error decoding UTF8 string in exportedKey::word_list"]]; - return; - } - [wordList addObject:string]; - } - [subscriber putNext:wordList]; - [subscriber putCompletion]; - } else { - assert(false); - } - }]; - auto query = make_object( - make_object( - make_object( - makeString(publicKeyData), - makeSecureString(key.secret) - ), - makeSecureString(localPassword) - ) - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)importKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword wordList:(NSArray *)wordList { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::key::ID) { - auto result = tonlib_api::move_object_as(object); - NSString *publicKey = [[NSString alloc] initWithData:[[NSData alloc] initWithBytes:result->public_key_.data() length:result->public_key_.length()] encoding:NSUTF8StringEncoding]; - if (publicKey == nil) { - [subscriber putError:[[TONError alloc] initWithText:@"Error decoding UTF8 string in importKeyWithLocalPassword"]]; - return; - } - NSData *secret = [[NSData alloc] initWithBytes:result->secret_.data() length:result->secret_.length()]; - [subscriber putNext:[[TONKey alloc] initWithPublicKey:publicKey secret:secret]]; - [subscriber putCompletion]; - } else { - assert(false); - } - }]; - - std::vector wordVector; - for (NSString *word in wordList) { - NSData *wordData = [word dataUsingEncoding:NSUTF8StringEncoding]; - wordVector.push_back(makeSecureString(wordData)); - } - - auto query = make_object( - makeSecureString(localPassword), - makeSecureString(mnemonicPassword), - make_object(std::move(wordVector))); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)deleteKey:(TONKey *)key { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - NSData *publicKeyData = [key.publicKey dataUsingEncoding:NSUTF8StringEncoding]; - if (publicKeyData == nil) { - [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in deleteKey"]]; - return [[SBlockDisposable alloc] initWithBlock:^{}]; - } - - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else { - [subscriber putCompletion]; - } - }]; - - auto query = make_object( - make_object( - makeString(publicKeyData), - makeSecureString(key.secret) - ) - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)deleteAllKeys { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else { - [subscriber putCompletion]; - } - }]; - - auto query = make_object(); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)getTransactionListWithAddress:(NSString * _Nonnull)address lt:(int64_t)lt hash:(NSData * _Nonnull)hash { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - NSData *addressData = [address dataUsingEncoding:NSUTF8StringEncoding]; - if (addressData == nil) { - [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in getTransactionListWithAddress"]]; - return [[SBlockDisposable alloc] initWithBlock:^{}]; - } - - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::raw_transactions::ID) { - auto result = tonlib_api::move_object_as(object); - NSMutableArray *transactions = [[NSMutableArray alloc] init]; - for (auto &it : result->transactions_) { - TONTransactionId *transactionId = [[TONTransactionId alloc] initWithLt:it->transaction_id_->lt_ transactionHash:makeData(it->transaction_id_->hash_)]; - TONTransactionMessage *inMessage = parseTransactionMessage(it->in_msg_); - NSMutableArray * outMessages = [[NSMutableArray alloc] init]; - for (auto &messageIt : it->out_msgs_) { - TONTransactionMessage *outMessage = parseTransactionMessage(messageIt); - if (outMessage != nil) { - [outMessages addObject:outMessage]; - } - } - [transactions addObject:[[TONTransaction alloc] initWithData:makeData(it->data_) transactionId:transactionId timestamp:it->utime_ storageFee:it->storage_fee_ otherFee:it->other_fee_ inMessage:inMessage outMessages:outMessages]]; - } - [subscriber putNext:transactions]; - [subscriber putCompletion]; - } else { - assert(false); - } - }]; - - auto query = make_object( - make_object(), - make_object( - makeString(addressData) - ), - make_object( - lt, - makeString(hash) - ) - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -- (SSignal *)decryptMessagesWithKey:(TONKey * _Nonnull)key localPassword:(NSData * _Nonnull)localPassword messages:(NSArray * _Nonnull)messages { - return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { - NSData *publicKeyData = [key.publicKey dataUsingEncoding:NSUTF8StringEncoding]; - if (publicKeyData == nil) { - [subscriber putError:[[TONError alloc] initWithText:@"Error encoding UTF8 string in decryptMessagesWithKey"]]; - return [[SBlockDisposable alloc] initWithBlock:^{}]; - } - - uint64_t requestId = _nextRequestId; - _nextRequestId += 1; - - _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { - if (object->get_id() == tonlib_api::error::ID) { - auto error = tonlib_api::move_object_as(object); - [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::msg_dataDecryptedArray::ID) { - auto result = tonlib_api::move_object_as(object); - if (result->elements_.size() != messages.count) { - [subscriber putError:[[TONError alloc] initWithText:@"API interaction error"]]; - } else { - NSMutableArray > *resultMessages = [[NSMutableArray alloc] init]; - int index = 0; - for (auto &it : result->elements_) { - if (it->data_->get_id() == tonlib_api::msg_dataDecryptedText::ID) { - auto dataDecryptedText = tonlib_api::move_object_as(it->data_); - NSString *decryptedString = readString(dataDecryptedText->text_); - if (decryptedString != nil) { - [resultMessages addObject:[[TONTransactionMessageContentsPlainText alloc] initWithText:decryptedString]]; - } else { - [resultMessages addObject:[[TONTransactionMessageContentsEncryptedText alloc] initWithEncryptedData:messages[index]]]; - } - } else { - [resultMessages addObject:[[TONTransactionMessageContentsEncryptedText alloc] initWithEncryptedData:messages[index]]]; - } - index++; - } - [subscriber putNext:resultMessages]; - [subscriber putCompletion]; - } - } else { - assert(false); - } - }]; - - std::vector> inputData; - for (TONEncryptedData *message in messages) { - NSData *sourceAddressData = [message.sourceAddress dataUsingEncoding:NSUTF8StringEncoding]; - if (sourceAddressData == nil) { - continue; - } - - inputData.push_back(make_object( - make_object( - makeString(sourceAddressData) - ), - make_object( - makeString(message.data) - ) - )); - } - - auto query = make_object( - make_object( - make_object( - makeString(publicKeyData), - makeSecureString(key.secret) - ), - makeSecureString(localPassword) - ), - make_object( - std::move(inputData) - ) - ); - _client->send({ requestId, std::move(query) }); - - return [[SBlockDisposable alloc] initWithBlock:^{ - }]; - }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; -} - -@end diff --git a/submodules/UrlHandling/BUILD b/submodules/UrlHandling/BUILD index 4d6dcfb0a7..f1ecafd4b7 100644 --- a/submodules/UrlHandling/BUILD +++ b/submodules/UrlHandling/BUILD @@ -11,7 +11,6 @@ swift_library( ], deps = [ "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", - "//submodules/Postbox:Postbox", "//submodules/TelegramCore:TelegramCore", "//submodules/MtProtoKit:MtProtoKit", "//submodules/AccountContext:AccountContext", diff --git a/submodules/WallpaperResources/BUILD b/submodules/WallpaperResources/BUILD index 999d61068c..96000b45f6 100644 --- a/submodules/WallpaperResources/BUILD +++ b/submodules/WallpaperResources/BUILD @@ -11,7 +11,6 @@ swift_library( ], deps = [ "//submodules/TelegramCore:TelegramCore", - "//submodules/Postbox:Postbox", "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/Display:Display", "//submodules/LocalMediaResources:LocalMediaResources", diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index 07dd9e52d0..490a1d162f 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -3,7 +3,6 @@ import UIKit import SwiftSignalKit import Display import CoreImage -import Postbox import TelegramCore import MediaResources import ImageBlur @@ -21,17 +20,17 @@ import GZip public func wallpaperDatas(account: Account, accountManager: AccountManager, fileReference: FileMediaReference? = nil, representations: [ImageRepresentationWithReference], alwaysShowThumbnailFirst: Bool = false, thumbnail: Bool = false, onlyFullSize: Bool = false, autoFetchFullSize: Bool = false, synchronousLoad: Bool = false) -> Signal<(Data?, Data?, Bool), NoError> { if let smallestRepresentation = smallestImageRepresentation(representations.map({ $0.representation })), let largestRepresentation = largestImageRepresentation(representations.map({ $0.representation })), let smallestIndex = representations.firstIndex(where: { $0.representation == smallestRepresentation }), let largestIndex = representations.firstIndex(where: { $0.representation == largestRepresentation }) { - let maybeFullSize: Signal + let maybeFullSize: Signal if thumbnail, let file = fileReference?.media { maybeFullSize = combineLatest(accountManager.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: false, fetch: false, attemptSynchronously: synchronousLoad), account.postbox.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: false, fetch: false, attemptSynchronously: synchronousLoad)) - |> mapToSignal { maybeSharedData, maybeData -> Signal in + |> mapToSignal { maybeSharedData, maybeData -> Signal in if maybeSharedData.complete { return .single(maybeSharedData) } else if maybeData.complete { return .single(maybeData) } else { return combineLatest(accountManager.mediaBox.resourceData(file.resource), account.postbox.mediaBox.resourceData(file.resource)) - |> mapToSignal { maybeSharedData, maybeData -> Signal in + |> mapToSignal { maybeSharedData, maybeData -> Signal in if maybeSharedData.complete { return accountManager.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: false, fetch: true) } @@ -46,7 +45,7 @@ public func wallpaperDatas(account: Account, accountManager: AccountManager mapToSignal { maybeSharedData, maybeData -> Signal in + |> mapToSignal { maybeSharedData, maybeData -> Signal in if maybeSharedData.complete { return .single(maybeSharedData) } else if maybeData.complete { @@ -57,7 +56,7 @@ public func wallpaperDatas(account: Account, accountManager: AccountManager map { sharedData, data -> MediaResourceData in + |> map { sharedData, data -> EngineRawMediaResourceData in if sharedData.complete && data.complete { if sharedData.size > data.size { return sharedData @@ -87,7 +86,7 @@ public func wallpaperDatas(account: Account, accountManager: AccountManager + let fetchedThumbnail: Signal fetchedThumbnail = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .other, reference: representations[smallestIndex].reference) let fetchedFullSize = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .other, reference: representations[largestIndex].reference) @@ -839,7 +838,7 @@ private func builtinWallpaperData() -> Signal { } |> runOn(Queue.concurrentDefaultQueue()) } -public func settingsBuiltinWallpaperImage(account: Account, thumbnail: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { +public func settingsBuiltinWallpaperImage(thumbnail: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { return builtinWallpaperData() |> map { fullSizeImage in return { arguments in guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { @@ -877,7 +876,7 @@ public func settingsBuiltinWallpaperImage(account: Account, thumbnail: Bool = fa } } -public func photoWallpaper(postbox: Postbox, photoLibraryResource: PhotoLibraryMediaResource) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { +public func photoWallpaper(photoLibraryResource: PhotoLibraryMediaResource) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { let thumbnail = fetchPhotoLibraryImage(localIdentifier: photoLibraryResource.localIdentifier, thumbnail: true) let fullSize = fetchPhotoLibraryImage(localIdentifier: photoLibraryResource.localIdentifier, thumbnail: false) @@ -1172,7 +1171,7 @@ public func themeImage(account: Account, accountManager: AccountManager + let fetchedThumbnail: Signal if let previewRepresentation = previewRepresentation { fetchedThumbnail = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .other, reference: fileReference.resourceReference(previewRepresentation.resource)) } else { diff --git a/third-party/AppCenter/AppCenter.BUILD b/third-party/AppCenter/AppCenter.BUILD deleted file mode 100644 index ce677b8e72..0000000000 --- a/third-party/AppCenter/AppCenter.BUILD +++ /dev/null @@ -1,15 +0,0 @@ -load("@build_bazel_rules_apple//apple:apple.bzl", - "apple_static_framework_import", -) - -apple_static_framework_import( - name = "AppCenter", - framework_imports = glob(["AppCenter-SDK-Apple/iOS/AppCenter.framework/**"]), - visibility = ["//visibility:public"], -) - -apple_static_framework_import( - name = "AppCenterCrashes", - framework_imports = glob(["AppCenter-SDK-Apple/iOS/AppCenterCrashes.framework/**"]), - visibility = ["//visibility:public"], -) diff --git a/third-party/AppCenter/BUILD b/third-party/AppCenter/BUILD deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/third-party/SwiftColor/BUILD b/third-party/SwiftColor/BUILD deleted file mode 100644 index a45048f861..0000000000 --- a/third-party/SwiftColor/BUILD +++ /dev/null @@ -1,17 +0,0 @@ -load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") - -swift_library( - name = "SwiftColor", - module_name = "SwiftColor", - srcs = glob([ - "Sources/**/*.swift", - ]), - copts = [ - "-suppress-warnings", - ], - deps = [ - ], - visibility = [ - "//visibility:public", - ], -) diff --git a/third-party/SwiftColor/Sources/Clamping.swift b/third-party/SwiftColor/Sources/Clamping.swift deleted file mode 100644 index 4154946f98..0000000000 --- a/third-party/SwiftColor/Sources/Clamping.swift +++ /dev/null @@ -1,20 +0,0 @@ -@propertyWrapper -public struct Clamping { - var value: Value - let range: ClosedRange - - public init(wrappedValue value: Value, _ range: ClosedRange) { - precondition(range.contains(value)) - self.value = value - self.range = range - } - - public var wrappedValue: Value { - get { - value - } - set(newValue) { - value = min(max(range.lowerBound, newValue), range.upperBound) - } - } -} diff --git a/third-party/SwiftColor/Sources/ColorSpace.swift b/third-party/SwiftColor/Sources/ColorSpace.swift deleted file mode 100644 index fef838c450..0000000000 --- a/third-party/SwiftColor/Sources/ColorSpace.swift +++ /dev/null @@ -1,3 +0,0 @@ -public enum ColorSpace: Equatable, Sendable { - case rgba -} diff --git a/third-party/SwiftColor/Sources/Pigment+AppKit.swift b/third-party/SwiftColor/Sources/Pigment+AppKit.swift deleted file mode 100644 index 38c875d965..0000000000 --- a/third-party/SwiftColor/Sources/Pigment+AppKit.swift +++ /dev/null @@ -1,24 +0,0 @@ -import Foundation -#if canImport(AppKit) && !targetEnvironment(macCatalyst) -import AppKit - -public extension Pigment { - /// Initialize a `Pigment` using an `NSColor`. - init(_ color: NSColor) { - red = color.redComponent - green = color.greenComponent - blue = color.blueComponent - alpha = color.alphaComponent - } - - var nsColor: NSColor { - NSColor(red: red, green: green, blue: blue, alpha: alpha) - } -} - -public extension NSColor { - var pigment: Pigment { - Pigment(self) - } -} -#endif diff --git a/third-party/SwiftColor/Sources/Pigment+CoreGraphics.swift b/third-party/SwiftColor/Sources/Pigment+CoreGraphics.swift deleted file mode 100644 index 29eaba236e..0000000000 --- a/third-party/SwiftColor/Sources/Pigment+CoreGraphics.swift +++ /dev/null @@ -1,39 +0,0 @@ -import Foundation -#if canImport(CoreGraphics) -import CoreGraphics - -public extension Pigment { - /// Initialize a `Pigment` using an `CGColor`. - init?(_ color: CGColor) { - let components = color.components ?? [] - switch components.count { - case 2: - // Monochrome/Grayscale - // TODO: Express this in 'Color'. - red = 0.0 - green = 0.0 - blue = 0.0 - alpha = components[1] - case 4: - // RGB - red = components[0] - green = components[1] - blue = components[2] - alpha = components[3] - default: - return nil - } - } -} - -public extension CGColor { - static func make(_ color: Pigment) -> CGColor { - if color.red == 0.0, color.green == 0.0, color.blue == 0.0, color.alpha == 0.0 { - // Return the CG color equivalent of `UIColor.clear`. - return CGColor(genericGrayGamma2_2Gray: 0.0, alpha: 0.0) - } - - return CGColor(srgbRed: color.red, green: color.green, blue: color.blue, alpha: color.alpha) - } -} -#endif diff --git a/third-party/SwiftColor/Sources/Pigment+Float.swift b/third-party/SwiftColor/Sources/Pigment+Float.swift deleted file mode 100644 index fbcaf7001a..0000000000 --- a/third-party/SwiftColor/Sources/Pigment+Float.swift +++ /dev/null @@ -1,95 +0,0 @@ -import Foundation - -public extension Pigment { - /// Initialize a `Pigment` using `Float` values leaning towards the 'Red' spectrum. - /// - /// - parameters - /// - red: A value in the range of 0.0 to 1.0 representing the **red** percent. - /// - green: A value in the range of 0.0 to 1.0 representing the **green** percent. - /// - blue: A value in the range of 0.0 to 1.0 representing the **blue** percent. - /// - alpha: A value in the range of 0.0 to 1.0 representing the **alpha/opacity/transparency** percent. - init( - red: Float, - green: Float = 0.0, - blue: Float = 0.0, - alpha: Float = 1.0 - ) { - self.red = Double(red) - self.green = Double(green) - self.blue = Double(blue) - self.alpha = Double(alpha) - } - - /// Initialize a `Pigment` using `Float` values leaning towards the 'Green' spectrum. - /// - /// - parameters: - /// - green: A value in the range of 0.0 to 1.0 representing the **green** percent. - /// - blue: A value in the range of 0.0 to 1.0 representing the **blue** percent. - /// - red: A value in the range of 0.0 to 1.0 representing the **red** percent. - /// - alpha: A value in the range of 0.0 to 1.0 representing the **alpha/opacity/transparency** percent. - init( - green: Float, - blue: Float = 0.0, - red: Float = 0.0, - alpha: Float = 1.0 - ) { - self.red = Double(red) - self.green = Double(green) - self.blue = Double(blue) - self.alpha = Double(alpha) - } - - /// Initialize a `Pigment` using `Float` values leaning towards the 'Blue' spectrum. - /// - /// - parameter: - /// - blue: A value in the range of 0.0 to 1.0 representing the **blue** percent. - /// - red: A value in the range of 0.0 to 1.0 representing the **red** percent. - /// - green: A value in the range of 0.0 to 1.0 representing the **green** percent. - /// - alpha: A value in the range of 0.0 to 1.0 representing the **alpha/opacity/transparency** percent. - init( - blue: Float, - red: Float = 0.0, - green: Float = 0.0, - alpha: Float = 1.0 - ) { - self.red = Double(red) - self.green = Double(green) - self.blue = Double(blue) - self.alpha = Double(alpha) - } - - /// Initialize a `Pigment` using variadic `Float` values. - /// - /// All _values_ should be expressed in the range of 0.0 to 1.0. - /// - /// - parameters: - /// - values: A number of `Float` which are mapped to **red**, **green**, **blue** in that order. - /// - alpha: Amount of _opacity/transparency_ to apply. - init( - _ values: Float..., - alpha: Float - ) { - if values.count > 0 { - red = Double(values[0].clamped(to: 0 ... 1)) - } else { - red = 0.0 - } - if values.count > 1 { - green = Double(values[1].clamped(to: 0 ... 1)) - } else { - green = 0.0 - } - if values.count > 2 { - blue = Double(values[2].clamped(to: 0 ... 1)) - } else { - blue = 0.0 - } - self.alpha = Double(alpha.clamped(to: 0 ... 1)) - } -} - -extension Float { - func clamped(to range: ClosedRange) -> Float { - min(max(range.lowerBound, self), range.upperBound) - } -} diff --git a/third-party/SwiftColor/Sources/Pigment+Hex.swift b/third-party/SwiftColor/Sources/Pigment+Hex.swift deleted file mode 100644 index c969b9538c..0000000000 --- a/third-party/SwiftColor/Sources/Pigment+Hex.swift +++ /dev/null @@ -1,145 +0,0 @@ -import Foundation - -public extension Pigment { - /// Initializes a `Pigment` with an `Int` in the expected format of **0x000**. - /// - /// Used as a short-hand. If the hex 0x123 is provided, it is interpreted as 0x112233. - init( - hex3 hex: Int, - @Clamping(0 ... 1) alpha: Double = 1.0 - ) { - let values = Self.hex3(hex: hex, alpha: alpha) - red = values.red - green = values.green - blue = values.blue - self.alpha = values.alpha - } - - /// Shorthand **0x0000** initializer similar to `init(hex3:alpha:)` where - /// the last digit represent the alpha component. - init( - hex4 hex: Int - ) { - let values = Self.hex4(hex: hex) - red = values.red - green = values.green - blue = values.blue - alpha = values.alpha - } - - /// Initializes with a standard format hex representation of color in the form of **0x1E2C3D**. - init( - hex6 hex: Int, - @Clamping(0 ... 1) alpha: Double = 1.0 - ) { - let values = Self.hex6(hex: hex, alpha: alpha) - red = values.red - green = values.green - blue = values.blue - self.alpha = values.alpha - } - - #if !os(watchOS) - /// Extended form of `init(hex6:alpha:)` expecting **0x112233FF**, that uses the last - /// bits for the alpha component. - init( - hex8 hex: Int - ) { - let values = Self.hex8(hex: hex) - red = values.red - green = values.green - blue = values.blue - alpha = values.alpha - } - #endif - - /// Initializes a `Pigment` with an `Int` representation of an RGB(a) Hex Value - /// - /// This initializer will do its best to interpret the intentions of what is provided. - /// **YOUR RESULTS WILL VARY**, and it's best to use one of the `init(hex?:)` initializers. - /// - /// - Parameter hex: Hex value - /// - Parameter alpha: The opacity value of the color object - init( - _ hex: Int, - alpha: Double? = nil - ) { - #if !os(watchOS) - if hex > 0xFFFFFF { - let values = Self.hex8(hex: hex) - red = values.red - green = values.green - blue = values.blue - self.alpha = values.alpha - return - } - #endif - if hex > 0xFFFF { - let values = Self.hex6(hex: hex, alpha: alpha ?? 1.0) - red = values.red - green = values.green - blue = values.blue - self.alpha = values.alpha - } else if hex > 0xFFF { - let values = Self.hex4(hex: hex) - red = values.red - green = values.green - blue = values.blue - self.alpha = values.alpha - } else { - let values = Self.hex3(hex: hex, alpha: alpha ?? 1.0) - red = values.red - green = values.green - blue = values.blue - self.alpha = values.alpha - } - } -} - -extension Pigment { - static func hex3( - hex: Int, - @Clamping(0 ... 1) alpha: Double = 1.0 - ) -> (red: Double, green: Double, blue: Double, alpha: Double) { - let red = Double(duplicateBits((hex & 0xF00) >> 8)) / 255.0 - let green = Double(duplicateBits((hex & 0x0F0) >> 4)) / 255.0 - let blue = Double(duplicateBits((hex & 0x00F) >> 0)) / 255.0 - return (red, green, blue, alpha) - } - - static func hex4( - hex: Int - ) -> (red: Double, green: Double, blue: Double, alpha: Double) { - let red = Double(duplicateBits((hex & 0xF000) >> 12)) / 255.0 - let green = Double(duplicateBits((hex & 0x0F00) >> 8)) / 255.0 - let blue = Double(duplicateBits((hex & 0x00F0) >> 4)) / 255.0 - let alpha = Double(duplicateBits((hex & 0x000F) >> 0)) / 255.0 - return (red, green, blue, alpha) - } - - static func hex6( - hex: Int, - @Clamping(0 ... 1) alpha: Double = 1.0 - ) -> (red: Double, green: Double, blue: Double, alpha: Double) { - let red = Double((hex & 0xFF0000) >> 16) / 255.0 - let green = Double((hex & 0x00FF00) >> 8) / 255.0 - let blue = Double((hex & 0x0000FF) >> 0) / 255.0 - return (red, green, blue, alpha) - } - - #if !os(watchOS) - static func hex8( - hex: Int - ) -> (red: Double, green: Double, blue: Double, alpha: Double) { - let red = Double((hex & 0xFF00_0000) >> 24) / 255.0 - let green = Double((hex & 0x00FF_0000) >> 16) / 255.0 - let blue = Double((hex & 0x0000_FF00) >> 8) / 255.0 - let alpha = Double((hex & 0x0000_00FF) >> 0) / 255.0 - return (red, green, blue, alpha) - } - #endif - - static func duplicateBits(_ value: Int) -> Int { - (value << 4) + value - } -} diff --git a/third-party/SwiftColor/Sources/Pigment+Int.swift b/third-party/SwiftColor/Sources/Pigment+Int.swift deleted file mode 100644 index 16568d0142..0000000000 --- a/third-party/SwiftColor/Sources/Pigment+Int.swift +++ /dev/null @@ -1,89 +0,0 @@ -import Foundation - -public extension Pigment { - /// Initialize a `Pigment` using `Int` values leaning towards the 'Red' spectrum. - /// - /// - parameters: - /// - red: A value in the range of 0 to 255 representing the **red** bits - /// - green: A value in the range of 0 to 255 representing the **green** bits - /// - blue: A value in the range of 0 to 255 representing the **blue** bits - /// - alpha: A value in the range of 0.0 to 1.0 representing the **alpha/opacity/transparency** percent. - init( - @Clamping(0 ... 255) red: Int, - @Clamping(0 ... 255) green: Int = 0, - @Clamping(0 ... 255) blue: Int = 0, - @Clamping(0.0 ... 1.0) alpha: Double = 1.0 - ) { - self.red = Double(red) / 255.0 - self.green = Double(green) / 255.0 - self.blue = Double(blue) / 255.0 - self.alpha = alpha - } - - /// Initialize a `Pigment` using `Int` values leaning towards the 'Green' spectrum. - /// - /// - parameters: - /// - green: A value in the range of 0 to 255 representing the **green** bits - /// - blue: A value in the range of 0 to 255 representing the **blue** bits - /// - red: A value in the range of 0 to 255 representing the **red** bits - /// - alpha: A value in the range of 0.0 to 1.0 representing the **alpha/opacity/transparency** percent. - init( - @Clamping(0 ... 255) green: Int, - @Clamping(0 ... 255) blue: Int = 0, - @Clamping(0 ... 255) red: Int = 0, - @Clamping(0.0 ... 1.0) alpha: Double = 1.0 - ) { - self.red = Double(red) / 255.0 - self.green = Double(green) / 255.0 - self.blue = Double(blue) / 255.0 - self.alpha = alpha - } - - /// Initialize a `Pigment` using `Int` values leaning towards the 'Blue' spectrum. - /// - /// - parameters: - /// - blue: A value in the range of 0 to 255 representing the **blue** bits - /// - red: A value in the range of 0 to 255 representing the **red** bits - /// - green: A value in the range of 0 to 255 representing the **green** bits - /// - alpha: A value in the range of 0.0 to 1.0 representing the **alpha/opacity/transparency** percent. - init( - @Clamping(0 ... 255) blue: Int, - @Clamping(0 ... 255) red: Int = 0, - @Clamping(0 ... 255) green: Int = 0, - @Clamping(0.0 ... 1.0) alpha: Double = 1.0 - ) { - self.red = Double(red) / 255.0 - self.green = Double(green) / 255.0 - self.blue = Double(blue) / 255.0 - self.alpha = alpha - } - - /// Initialize a `Pigment` using variadic `Int` values. - /// - /// All _values_ should be expressed in the range of 0 to 255. - /// - /// - parameters: - /// - values: A number of `Int` which are mapped to **red**, **green**, **blue** in that order. - /// - alpha: A value in the range of 0.0 to 1.0 representing the **alpha/opacity/transparency** percent. - init( - _ values: Int..., - @Clamping(0 ... 1) alpha: Double - ) { - if values.count > 0 { - red = Double(values[0]) / 255.0 - } else { - red = 0.0 - } - if values.count > 1 { - green = Double(values[1]) / 255.0 - } else { - green = 0.0 - } - if values.count > 2 { - blue = Double(values[2]) / 255.0 - } else { - blue = 0.0 - } - self.alpha = alpha - } -} diff --git a/third-party/SwiftColor/Sources/Pigment+Name.swift b/third-party/SwiftColor/Sources/Pigment+Name.swift deleted file mode 100644 index 8857f8f450..0000000000 --- a/third-party/SwiftColor/Sources/Pigment+Name.swift +++ /dev/null @@ -1,470 +0,0 @@ -import Foundation - -public extension Pigment { - @available(*, deprecated, renamed: "Name") - typealias Keyword = Name - - enum Name: String, CaseIterable { - case aliceBlue - case antiqueWhite - case aqua - case aquamarine - case azure - case beige - case bisque - case black - case blanchedAlmond - case blue - case blueViolet - case brown - case burlywood - case cadetBlue - case chartreuse - case chocolate - case coral - case cornflowerBlue - case cornsilk - case crimson - case cyan - case darkBlue - case darkCyan - case darkGoldenrod - case darkGray - case darkGreen - case darkGrey - case darkKhaki - case darkMagenta - case darkOliveGreen - case darkOrange - case darkOrchid - case darkRed - case darkSalmon - case darkSeagreen - case darkSlateBlue - case darkSlateGray - case darkSlateGrey - case darkTurquoise - case darkViolet - case deepPink - case deepSkyblue - case dimGray - case dimGrey - case dodgerBlue - case firebrick - case floralWhite - case forestGreen - case fuchsia - case gainsboro - case ghostWhite - case gold - case goldenrod - case gray - case green - case greenYellow - case grey - case honeydew - case hotPink - case indianRed - case indigo - case ivory - case khaki - case lavender - case lavenderBlush - case lawnGreen - case lemonChiffon - case lightBlue - case lightCoral - case lightCyan - case lightGoldenrodYellow - case lightGray - case lightGreen - case lightGrey - case lightPink - case lightSalmon - case lightSeagreen - case lightSkyBlue - case lightSlateGray - case lightSlateGrey - case lightSteelBlue - case lightYellow - case lime - case limeGreen - case linen - case magenta - case maroon - case mediumAquamarine - case mediumBlue - case mediumOrchid - case mediumPurple - case mediumSeagreen - case mediumSlateBlue - case mediumSpringGreen - case mediumTurquoise - case mediumVioletRed - case midnightBlue - case mintCream - case mistyRose - case moccasin - case navajoWhite - case navy - case oldLace - case olive - case oliveDrab - case orange - case orangeRed - case orchid - case paleGoldenrod - case paleGreen - case paleTurquoise - case paleVioletRed - case papayaWhip - case peachPuff - case peru - case pink - case plum - case powderBlue - case purple - case red - case rosyBrown - case royalBlue - case saddleBrown - case salmon - case sandyBrown - case seagreen - case seashell - case sienna - case silver - case skyBlue - case slateBlue - case slateGray - case slateGrey - case snow - case springGreen - case steelBlue - case tan - case teal - case thistle - case tomato - case turquoise - case violet - case wheat - case white - case whitesmoke - case yellow - case yellowGreen - - public var rgb: (red: Int, green: Int, blue: Int) { - switch self { - case .aliceBlue: (240, 248, 255) - case .antiqueWhite: (250, 235, 215) - case .aqua: (0, 255, 255) - case .aquamarine: (127, 255, 212) - case .azure: (240, 255, 255) - case .beige: (245, 245, 220) - case .bisque: (255, 228, 196) - case .black: (0, 0, 0) - case .blanchedAlmond: (255, 235, 205) - case .blue: (0, 0, 255) - case .blueViolet: (138, 43, 226) - case .brown: (165, 42, 42) - case .burlywood: (222, 184, 135) - case .cadetBlue: (95, 158, 160) - case .chartreuse: (127, 255, 0) - case .chocolate: (210, 105, 30) - case .coral: (255, 127, 80) - case .cornflowerBlue: (100, 149, 237) - case .cornsilk: (255, 248, 220) - case .crimson: (220, 20, 60) - case .cyan: (0, 255, 255) - case .darkBlue: (0, 0, 139) - case .darkCyan: (0, 139, 139) - case .darkGoldenrod: (184, 134, 11) - case .darkGray: (169, 169, 169) - case .darkGreen: (0, 100, 0) - case .darkGrey: (169, 169, 169) - case .darkKhaki: (189, 183, 107) - case .darkMagenta: (139, 0, 139) - case .darkOliveGreen: (85, 107, 47) - case .darkOrange: (255, 140, 0) - case .darkOrchid: (153, 50, 204) - case .darkRed: (139, 0, 0) - case .darkSalmon: (233, 150, 122) - case .darkSeagreen: (143, 188, 143) - case .darkSlateBlue: (72, 61, 139) - case .darkSlateGray: (47, 79, 79) - case .darkSlateGrey: (47, 79, 79) - case .darkTurquoise: (0, 206, 209) - case .darkViolet: (148, 0, 211) - case .deepPink: (255, 20, 147) - case .deepSkyblue: (0, 191, 255) - case .dimGray: (105, 105, 105) - case .dimGrey: (105, 105, 105) - case .dodgerBlue: (30, 144, 255) - case .firebrick: (178, 34, 34) - case .floralWhite: (255, 250, 240) - case .forestGreen: (34, 139, 34) - case .fuchsia: (255, 0, 255) - case .gainsboro: (220, 220, 220) - case .ghostWhite: (248, 248, 255) - case .gold: (255, 215, 0) - case .goldenrod: (218, 165, 32) - case .gray: (128, 128, 128) - case .green: (0, 128, 0) - case .greenYellow: (173, 255, 47) - case .grey: (128, 128, 128) - case .honeydew: (240, 255, 240) - case .hotPink: (255, 105, 180) - case .indianRed: (205, 92, 92) - case .indigo: (75, 0, 130) - case .ivory: (255, 255, 240) - case .khaki: (240, 230, 140) - case .lavender: (230, 230, 250) - case .lavenderBlush: (255, 240, 245) - case .lawnGreen: (124, 252, 0) - case .lemonChiffon: (255, 250, 205) - case .lightBlue: (173, 216, 230) - case .lightCoral: (240, 128, 128) - case .lightCyan: (224, 255, 255) - case .lightGoldenrodYellow: (250, 250, 210) - case .lightGray: (211, 211, 211) - case .lightGreen: (144, 238, 144) - case .lightGrey: (211, 211, 211) - case .lightPink: (255, 182, 193) - case .lightSalmon: (255, 160, 122) - case .lightSeagreen: (32, 178, 170) - case .lightSkyBlue: (135, 206, 250) - case .lightSlateGray: (119, 136, 153) - case .lightSlateGrey: (119, 136, 153) - case .lightSteelBlue: (176, 196, 222) - case .lightYellow: (255, 255, 224) - case .lime: (0, 255, 0) - case .limeGreen: (50, 205, 50) - case .linen: (250, 240, 230) - case .magenta: (255, 0, 255) - case .maroon: (128, 0, 0) - case .mediumAquamarine: (102, 205, 170) - case .mediumBlue: (0, 0, 205) - case .mediumOrchid: (186, 85, 211) - case .mediumPurple: (147, 112, 219) - case .mediumSeagreen: (60, 179, 113) - case .mediumSlateBlue: (123, 104, 238) - case .mediumSpringGreen: (0, 250, 154) - case .mediumTurquoise: (72, 209, 204) - case .mediumVioletRed: (199, 21, 133) - case .midnightBlue: (25, 25, 112) - case .mintCream: (245, 255, 250) - case .mistyRose: (255, 228, 225) - case .moccasin: (255, 228, 181) - case .navajoWhite: (255, 222, 173) - case .navy: (0, 0, 128) - case .oldLace: (253, 245, 230) - case .olive: (128, 128, 0) - case .oliveDrab: (107, 142, 35) - case .orange: (255, 165, 0) - case .orangeRed: (255, 69, 0) - case .orchid: (218, 112, 214) - case .paleGoldenrod: (238, 232, 170) - case .paleGreen: (152, 251, 152) - case .paleTurquoise: (175, 238, 238) - case .paleVioletRed: (219, 112, 147) - case .papayaWhip: (255, 239, 213) - case .peachPuff: (255, 218, 185) - case .peru: (205, 133, 63) - case .pink: (255, 192, 203) - case .plum: (221, 160, 221) - case .powderBlue: (176, 224, 230) - case .purple: (128, 0, 128) - case .red: (255, 0, 0) - case .rosyBrown: (188, 143, 143) - case .royalBlue: (65, 105, 225) - case .saddleBrown: (139, 69, 19) - case .salmon: (250, 128, 114) - case .sandyBrown: (244, 164, 96) - case .seagreen: (46, 139, 87) - case .seashell: (255, 245, 238) - case .sienna: (160, 82, 45) - case .silver: (192, 192, 192) - case .skyBlue: (135, 206, 235) - case .slateBlue: (106, 90, 205) - case .slateGray: (112, 128, 144) - case .slateGrey: (112, 128, 144) - case .snow: (255, 250, 250) - case .springGreen: (0, 255, 127) - case .steelBlue: (70, 130, 180) - case .tan: (210, 180, 140) - case .teal: (0, 128, 128) - case .thistle: (216, 191, 216) - case .tomato: (255, 99, 71) - case .turquoise: (64, 224, 208) - case .violet: (238, 130, 238) - case .wheat: (245, 222, 179) - case .white: (255, 255, 255) - case .whitesmoke: (245, 245, 245) - case .yellow: (255, 255, 0) - case .yellowGreen: (154, 205, 50) - } - } - - public var pigment: Pigment { - switch self { - case .aliceBlue: Pigment(240, 248, 255, alpha: 1.0) - case .antiqueWhite: Pigment(250, 235, 215, alpha: 1.0) - case .aqua: Pigment(0, 255, 255, alpha: 1.0) - case .aquamarine: Pigment(127, 255, 212, alpha: 1.0) - case .azure: Pigment(240, 255, 255, alpha: 1.0) - case .beige: Pigment(245, 245, 220, alpha: 1.0) - case .bisque: Pigment(255, 228, 196, alpha: 1.0) - case .black: Pigment(0, 0, 0, alpha: 1.0) - case .blanchedAlmond: Pigment(255, 235, 205, alpha: 1.0) - case .blue: Pigment(0, 0, 255, alpha: 1.0) - case .blueViolet: Pigment(138, 43, 226, alpha: 1.0) - case .brown: Pigment(165, 42, 42, alpha: 1.0) - case .burlywood: Pigment(222, 184, 135, alpha: 1.0) - case .cadetBlue: Pigment(95, 158, 160, alpha: 1.0) - case .chartreuse: Pigment(127, 255, 0, alpha: 1.0) - case .chocolate: Pigment(210, 105, 30, alpha: 1.0) - case .coral: Pigment(255, 127, 80, alpha: 1.0) - case .cornflowerBlue: Pigment(100, 149, 237, alpha: 1.0) - case .cornsilk: Pigment(255, 248, 220, alpha: 1.0) - case .crimson: Pigment(220, 20, 60, alpha: 1.0) - case .cyan: Pigment(0, 255, 255, alpha: 1.0) - case .darkBlue: Pigment(0, 0, 139, alpha: 1.0) - case .darkCyan: Pigment(0, 139, 139, alpha: 1.0) - case .darkGoldenrod: Pigment(184, 134, 11, alpha: 1.0) - case .darkGray: Pigment(169, 169, 169, alpha: 1.0) - case .darkGreen: Pigment(0, 100, 0, alpha: 1.0) - case .darkGrey: Pigment(169, 169, 169, alpha: 1.0) - case .darkKhaki: Pigment(189, 183, 107, alpha: 1.0) - case .darkMagenta: Pigment(139, 0, 139, alpha: 1.0) - case .darkOliveGreen: Pigment(85, 107, 47, alpha: 1.0) - case .darkOrange: Pigment(255, 140, 0, alpha: 1.0) - case .darkOrchid: Pigment(153, 50, 204, alpha: 1.0) - case .darkRed: Pigment(139, 0, 0, alpha: 1.0) - case .darkSalmon: Pigment(233, 150, 122, alpha: 1.0) - case .darkSeagreen: Pigment(143, 188, 143, alpha: 1.0) - case .darkSlateBlue: Pigment(72, 61, 139, alpha: 1.0) - case .darkSlateGray: Pigment(47, 79, 79, alpha: 1.0) - case .darkSlateGrey: Pigment(47, 79, 79, alpha: 1.0) - case .darkTurquoise: Pigment(0, 206, 209, alpha: 1.0) - case .darkViolet: Pigment(148, 0, 211, alpha: 1.0) - case .deepPink: Pigment(255, 20, 147, alpha: 1.0) - case .deepSkyblue: Pigment(0, 191, 255, alpha: 1.0) - case .dimGray: Pigment(105, 105, 105, alpha: 1.0) - case .dimGrey: Pigment(105, 105, 105, alpha: 1.0) - case .dodgerBlue: Pigment(30, 144, 255, alpha: 1.0) - case .firebrick: Pigment(178, 34, 34, alpha: 1.0) - case .floralWhite: Pigment(255, 250, 240, alpha: 1.0) - case .forestGreen: Pigment(34, 139, 34, alpha: 1.0) - case .fuchsia: Pigment(255, 0, 255, alpha: 1.0) - case .gainsboro: Pigment(220, 220, 220, alpha: 1.0) - case .ghostWhite: Pigment(248, 248, 255, alpha: 1.0) - case .gold: Pigment(255, 215, 0, alpha: 1.0) - case .goldenrod: Pigment(218, 165, 32, alpha: 1.0) - case .gray: Pigment(128, 128, 128, alpha: 1.0) - case .green: Pigment(0, 128, 0, alpha: 1.0) - case .greenYellow: Pigment(173, 255, 47, alpha: 1.0) - case .grey: Pigment(128, 128, 128, alpha: 1.0) - case .honeydew: Pigment(240, 255, 240, alpha: 1.0) - case .hotPink: Pigment(255, 105, 180, alpha: 1.0) - case .indianRed: Pigment(205, 92, 92, alpha: 1.0) - case .indigo: Pigment(75, 0, 130, alpha: 1.0) - case .ivory: Pigment(255, 255, 240, alpha: 1.0) - case .khaki: Pigment(240, 230, 140, alpha: 1.0) - case .lavender: Pigment(230, 230, 250, alpha: 1.0) - case .lavenderBlush: Pigment(255, 240, 245, alpha: 1.0) - case .lawnGreen: Pigment(124, 252, 0, alpha: 1.0) - case .lemonChiffon: Pigment(255, 250, 205, alpha: 1.0) - case .lightBlue: Pigment(173, 216, 230, alpha: 1.0) - case .lightCoral: Pigment(240, 128, 128, alpha: 1.0) - case .lightCyan: Pigment(224, 255, 255, alpha: 1.0) - case .lightGoldenrodYellow: Pigment(250, 250, 210, alpha: 1.0) - case .lightGray: Pigment(211, 211, 211, alpha: 1.0) - case .lightGreen: Pigment(144, 238, 144, alpha: 1.0) - case .lightGrey: Pigment(211, 211, 211, alpha: 1.0) - case .lightPink: Pigment(255, 182, 193, alpha: 1.0) - case .lightSalmon: Pigment(255, 160, 122, alpha: 1.0) - case .lightSeagreen: Pigment(32, 178, 170, alpha: 1.0) - case .lightSkyBlue: Pigment(135, 206, 250, alpha: 1.0) - case .lightSlateGray: Pigment(119, 136, 153, alpha: 1.0) - case .lightSlateGrey: Pigment(119, 136, 153, alpha: 1.0) - case .lightSteelBlue: Pigment(176, 196, 222, alpha: 1.0) - case .lightYellow: Pigment(255, 255, 224, alpha: 1.0) - case .lime: Pigment(0, 255, 0, alpha: 1.0) - case .limeGreen: Pigment(50, 205, 50, alpha: 1.0) - case .linen: Pigment(250, 240, 230, alpha: 1.0) - case .magenta: Pigment(255, 0, 255, alpha: 1.0) - case .maroon: Pigment(128, 0, 0, alpha: 1.0) - case .mediumAquamarine: Pigment(102, 205, 170, alpha: 1.0) - case .mediumBlue: Pigment(0, 0, 205, alpha: 1.0) - case .mediumOrchid: Pigment(186, 85, 211, alpha: 1.0) - case .mediumPurple: Pigment(147, 112, 219, alpha: 1.0) - case .mediumSeagreen: Pigment(60, 179, 113, alpha: 1.0) - case .mediumSlateBlue: Pigment(123, 104, 238, alpha: 1.0) - case .mediumSpringGreen: Pigment(0, 250, 154, alpha: 1.0) - case .mediumTurquoise: Pigment(72, 209, 204, alpha: 1.0) - case .mediumVioletRed: Pigment(199, 21, 133, alpha: 1.0) - case .midnightBlue: Pigment(25, 25, 112, alpha: 1.0) - case .mintCream: Pigment(245, 255, 250, alpha: 1.0) - case .mistyRose: Pigment(255, 228, 225, alpha: 1.0) - case .moccasin: Pigment(255, 228, 181, alpha: 1.0) - case .navajoWhite: Pigment(255, 222, 173, alpha: 1.0) - case .navy: Pigment(0, 0, 128, alpha: 1.0) - case .oldLace: Pigment(253, 245, 230, alpha: 1.0) - case .olive: Pigment(128, 128, 0, alpha: 1.0) - case .oliveDrab: Pigment(107, 142, 35, alpha: 1.0) - case .orange: Pigment(255, 165, 0, alpha: 1.0) - case .orangeRed: Pigment(255, 69, 0, alpha: 1.0) - case .orchid: Pigment(218, 112, 214, alpha: 1.0) - case .paleGoldenrod: Pigment(238, 232, 170, alpha: 1.0) - case .paleGreen: Pigment(152, 251, 152, alpha: 1.0) - case .paleTurquoise: Pigment(175, 238, 238, alpha: 1.0) - case .paleVioletRed: Pigment(219, 112, 147, alpha: 1.0) - case .papayaWhip: Pigment(255, 239, 213, alpha: 1.0) - case .peachPuff: Pigment(255, 218, 185, alpha: 1.0) - case .peru: Pigment(205, 133, 63, alpha: 1.0) - case .pink: Pigment(255, 192, 203, alpha: 1.0) - case .plum: Pigment(221, 160, 221, alpha: 1.0) - case .powderBlue: Pigment(176, 224, 230, alpha: 1.0) - case .purple: Pigment(128, 0, 128, alpha: 1.0) - case .red: Pigment(255, 0, 0, alpha: 1.0) - case .rosyBrown: Pigment(188, 143, 143, alpha: 1.0) - case .royalBlue: Pigment(65, 105, 225, alpha: 1.0) - case .saddleBrown: Pigment(139, 69, 19, alpha: 1.0) - case .salmon: Pigment(250, 128, 114, alpha: 1.0) - case .sandyBrown: Pigment(244, 164, 96, alpha: 1.0) - case .seagreen: Pigment(46, 139, 87, alpha: 1.0) - case .seashell: Pigment(255, 245, 238, alpha: 1.0) - case .sienna: Pigment(160, 82, 45, alpha: 1.0) - case .silver: Pigment(192, 192, 192, alpha: 1.0) - case .skyBlue: Pigment(135, 206, 235, alpha: 1.0) - case .slateBlue: Pigment(106, 90, 205, alpha: 1.0) - case .slateGray: Pigment(112, 128, 144, alpha: 1.0) - case .slateGrey: Pigment(112, 128, 144, alpha: 1.0) - case .snow: Pigment(255, 250, 250, alpha: 1.0) - case .springGreen: Pigment(0, 255, 127, alpha: 1.0) - case .steelBlue: Pigment(70, 130, 180, alpha: 1.0) - case .tan: Pigment(210, 180, 140, alpha: 1.0) - case .teal: Pigment(0, 128, 128, alpha: 1.0) - case .thistle: Pigment(216, 191, 216, alpha: 1.0) - case .tomato: Pigment(255, 99, 71, alpha: 1.0) - case .turquoise: Pigment(64, 224, 208, alpha: 1.0) - case .violet: Pigment(238, 130, 238, alpha: 1.0) - case .wheat: Pigment(245, 222, 179, alpha: 1.0) - case .white: Pigment(255, 255, 255, alpha: 1.0) - case .whitesmoke: Pigment(245, 245, 245, alpha: 1.0) - case .yellow: Pigment(255, 255, 0, alpha: 1.0) - case .yellowGreen: Pigment(154, 205, 50, alpha: 1.0) - } - } - } - - init( - _ name: Name, - @Clamping(0 ... 1) alpha: Double = 1.0 - ) { - red = Double(name.rgb.red) / 255.0 - green = Double(name.rgb.green) / 255.0 - blue = Double(name.rgb.blue) / 255.0 - self.alpha = alpha - } -} diff --git a/third-party/SwiftColor/Sources/Pigment+String.swift b/third-party/SwiftColor/Sources/Pigment+String.swift deleted file mode 100644 index 22c7b01124..0000000000 --- a/third-party/SwiftColor/Sources/Pigment+String.swift +++ /dev/null @@ -1,76 +0,0 @@ -import Foundation - -public extension Pigment { - init(_ value: String, alpha: Double = 1.0) { - if let keyword = Name.allCases.first(where: { $0.rawValue.caseInsensitiveCompare(value) == .orderedSame }) { - red = keyword.pigment.red - green = keyword.pigment.green - blue = keyword.pigment.blue - self.alpha = alpha - return - } - - if ExtendedKeyword.allCases.contains(where: { $0.rawValue.caseInsensitiveCompare(value) == .orderedSame }) { - red = 1.0 - green = 1.0 - blue = 1.0 - self.alpha = alpha - return - } - - var hex = value - if hex.hasPrefix("#") { - hex = String(hex.dropFirst()) - } - - guard let hexValue = Int(hex, radix: 16) else { - red = 1.0 - green = 1.0 - blue = 1.0 - self.alpha = alpha - return - } - - switch hex.count { - case 3: - let values = Self.hex3(hex: hexValue) - red = values.red - green = values.green - blue = values.blue - self.alpha = values.alpha - case 4: - let values = Self.hex4(hex: hexValue) - red = values.red - green = values.green - blue = values.blue - self.alpha = values.alpha - case 6: - let values = Self.hex6(hex: hexValue, alpha: alpha) - red = values.red - green = values.green - blue = values.blue - self.alpha = values.alpha - #if !os(watchOS) - case 8: - let values = Self.hex8(hex: hexValue) - red = values.red - green = values.green - blue = values.blue - self.alpha = values.alpha - #endif - default: - red = 1.0 - green = 1.0 - blue = 1.0 - self.alpha = alpha - } - } -} - -private extension Pigment { - enum ExtendedKeyword: String, CaseIterable { - case none - case clear - case transparent - } -} diff --git a/third-party/SwiftColor/Sources/Pigment+SwiftUI.swift b/third-party/SwiftColor/Sources/Pigment+SwiftUI.swift deleted file mode 100644 index d07aa1aec1..0000000000 --- a/third-party/SwiftColor/Sources/Pigment+SwiftUI.swift +++ /dev/null @@ -1,9 +0,0 @@ -#if canImport(SwiftUI) -import SwiftUI - -public extension Pigment { - var color: Color { - Color(red: red, green: green, blue: blue, opacity: alpha) - } -} -#endif diff --git a/third-party/SwiftColor/Sources/Pigment+UIKit.swift b/third-party/SwiftColor/Sources/Pigment+UIKit.swift deleted file mode 100644 index 8c96c2cc7e..0000000000 --- a/third-party/SwiftColor/Sources/Pigment+UIKit.swift +++ /dev/null @@ -1,37 +0,0 @@ -import Foundation -#if canImport(UIKit) -import UIKit - -public extension Pigment { - init(_ color: UIColor) { - var redComponent: CGFloat = 1.0 - var greenComponent: CGFloat = 1.0 - var blueComponent: CGFloat = 1.0 - var alphaComponent: CGFloat = 1.0 - - guard color.getRed(&redComponent, green: &greenComponent, blue: &blueComponent, alpha: &alphaComponent) else { - // TODO: Fail Initializer? Default Colors? - red = redComponent - green = greenComponent - blue = blueComponent - alpha = alphaComponent - return - } - - red = redComponent - green = greenComponent - blue = blueComponent - alpha = alphaComponent - } - - var uiColor: UIColor { - UIColor(red: red, green: green, blue: blue, alpha: alpha) - } -} - -public extension UIColor { - var pigment: Pigment { - Pigment(self) - } -} -#endif diff --git a/third-party/SwiftColor/Sources/Pigment.swift b/third-party/SwiftColor/Sources/Pigment.swift deleted file mode 100644 index 3db75b50bb..0000000000 --- a/third-party/SwiftColor/Sources/Pigment.swift +++ /dev/null @@ -1,53 +0,0 @@ -/// A platform agnostic representation of Color -/// -/// The components - red, green, blue, & alpha - are maintained as a floating-point representation. -/// Each value can range from 0.0 to 1.0 (e.g. 0 to 100 percent). -/// -/// 'Pure White' is represented by values all equal to **1.0**. -public struct Pigment: Sendable { - - public let colorSpace: ColorSpace = .rgba - public let red: Double - public let green: Double - public let blue: Double - public let alpha: Double - - public init( - @Clamping(0 ... 1) red: Double = 1.0, - @Clamping(0 ... 1) green: Double = 1.0, - @Clamping(0 ... 1) blue: Double = 1.0, - @Clamping(0 ... 1) alpha: Double = 1.0 - ) { - self.red = red - self.green = green - self.blue = blue - self.alpha = alpha - } -} - -extension Pigment: CustomStringConvertible { - public var description: String { - String(format: "Pigment(red: %.4f, green: %.4f, blue: %.4f, alpha: %.2f)", red, green, blue, alpha) - } -} - -extension Pigment: Equatable { - public static func == (lhs: Pigment, rhs: Pigment) -> Bool { - guard lhs.red == rhs.red else { - return false - } - guard lhs.green == rhs.green else { - return false - } - guard lhs.blue == rhs.blue else { - return false - } - guard lhs.alpha == rhs.alpha else { - return false - } - guard lhs.colorSpace == rhs.colorSpace else { - return false - } - return true - } -} diff --git a/third-party/SwiftSVG/BUILD b/third-party/SwiftSVG/BUILD deleted file mode 100644 index 565ad88ec4..0000000000 --- a/third-party/SwiftSVG/BUILD +++ /dev/null @@ -1,19 +0,0 @@ -load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") - -swift_library( - name = "SwiftSVG", - module_name = "SwiftSVG", - srcs = glob([ - "Sources/**/*.swift", - ]), - copts = [ - "-warnings-as-errors", - ], - deps = [ - "//third-party/XMLCoder", - "//third-party/Swift2D", - ], - visibility = [ - "//visibility:public", - ], -) diff --git a/third-party/SwiftSVG/Sources/Circle.swift b/third-party/SwiftSVG/Sources/Circle.swift deleted file mode 100644 index d42c8b9c73..0000000000 --- a/third-party/SwiftSVG/Sources/Circle.swift +++ /dev/null @@ -1,93 +0,0 @@ -import Swift2D -import XMLCoder - -/// Basic shape, used to draw circles based on a center point and a radius. -/// -/// The arc of a ‘circle’ element begins at the "3 o'clock" point on the radius and progresses towards the -/// "9 o'clock" point. The starting point and direction of the arc are affected by the user space transform -/// in the same manner as the geometry of the element. -/// -/// ## Documentation -/// [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/circle) -/// | [W3](https://www.w3.org/TR/SVG11/shapes.html#CircleElement) -public struct Circle: Element { - - /// The x-axis coordinate of the center of the circle. - public var x: Double = 0.0 - /// The y-axis coordinate of the center of the circle. - public var y: Double = 0.0 - /// The radius of the circle. - public var r: Double = 0.0 - - // MARK: CoreAttributes - - public var id: String? - - // MARK: PresentationAttributes - - public var fillColor: String? - public var fillOpacity: Double? - public var fillRule: Fill.Rule? - public var strokeColor: String? - public var strokeWidth: Double? - public var strokeOpacity: Double? - public var strokeLineCap: Stroke.LineCap? - public var strokeLineJoin: Stroke.LineJoin? - public var strokeMiterLimit: Double? - public var transform: String? - - // MARK: StylingAttributes - - public var style: String? - - enum CodingKeys: String, CodingKey { - case x = "cx" - case y = "cy" - case r - case id - case fillColor = "fill" - case fillOpacity = "fill-opacity" - case fillRule = "fill-rule" - case strokeColor = "stroke" - case strokeWidth = "stroke-width" - case strokeOpacity = "stroke-opacity" - case strokeLineCap = "stroke-linecap" - case strokeLineJoin = "stroke-linejoin" - case strokeMiterLimit = "stroke-miterlimit" - case transform - case style - } - - public init() {} - - public init(x: Double, y: Double, r: Double) { - self.x = x - self.y = y - self.r = r - } -} - -extension Circle: CustomStringConvertible { - public var description: String { - let desc = "" - } -} - -extension Circle: DirectionalCommandRepresentable { - public func commands(clockwise: Bool) throws -> [Path.Command] { - EllipseProcessor(circle: self).commands(clockwise: clockwise) - } -} - -extension Circle: DynamicNodeDecoding { - public static func nodeDecoding(for key: any CodingKey) -> XMLDecoder.NodeDecoding { - .attribute - } -} - -extension Circle: DynamicNodeEncoding { - public static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { - .attribute - } -} diff --git a/third-party/SwiftSVG/Sources/CommandRepresentable.swift b/third-party/SwiftSVG/Sources/CommandRepresentable.swift deleted file mode 100644 index f6bb79f05d..0000000000 --- a/third-party/SwiftSVG/Sources/CommandRepresentable.swift +++ /dev/null @@ -1,15 +0,0 @@ -/// Elements conforming to `CommandRepresentable` can be expressed in the form of `Path.Command`s. -public protocol CommandRepresentable { - func commands() throws -> [Path.Command] -} - -public protocol DirectionalCommandRepresentable: CommandRepresentable { - func commands(clockwise: Bool) throws -> [Path.Command] -} - -public extension DirectionalCommandRepresentable { - /// Defaults to anti/counter-clockwise commands. - func commands() throws -> [Path.Command] { - try commands(clockwise: false) - } -} diff --git a/third-party/SwiftSVG/Sources/Container.swift b/third-party/SwiftSVG/Sources/Container.swift deleted file mode 100644 index c90f0ea33a..0000000000 --- a/third-party/SwiftSVG/Sources/Container.swift +++ /dev/null @@ -1,58 +0,0 @@ -public protocol Container { - var circles: [Circle]? { get set } - var ellipses: [Ellipse]? { get set } - var groups: [Group]? { get set } - var lines: [Line]? { get set } - var paths: [Path]? { get set } - var polygons: [Polygon]? { get set } - var polylines: [Polyline]? { get set } - var rectangles: [Rectangle]? { get set } - var texts: [Text]? { get set } -} - -enum ContainerKeys: String, CodingKey { - case circles = "circle" - case ellipses = "ellipse" - case groups = "g" - case lines = "line" - case paths = "path" - case polylines = "polyline" - case polygons = "polygon" - case rectangles = "rect" - case texts = "text" -} - -public extension Container { - var containerDescription: String { - var contents: String = "" - - let circles = circles?.compactMap(\.description) ?? [] - circles.forEach { contents.append("\n\($0)") } - - let ellipses = ellipses?.compactMap(\.description) ?? [] - ellipses.forEach { contents.append("\n\($0)") } - - let groups = groups?.compactMap(\.description) ?? [] - groups.forEach { contents.append("\n\($0)") } - - let lines = lines?.compactMap(\.description) ?? [] - lines.forEach { contents.append("\n\($0)") } - - let paths = paths?.compactMap(\.description) ?? [] - paths.forEach { contents.append("\n\($0)") } - - let polylines = polylines?.compactMap(\.description) ?? [] - polylines.forEach { contents.append("\n\($0)") } - - let polygons = polygons?.compactMap(\.description) ?? [] - polygons.forEach { contents.append("\n\($0)") } - - let rectangles = rectangles?.compactMap(\.description) ?? [] - rectangles.forEach { contents.append("\n\($0)") } - - let texts = texts?.compactMap(\.description) ?? [] - texts.forEach { contents.append("\n\($0)") } - - return contents - } -} diff --git a/third-party/SwiftSVG/Sources/CoreAttributes.swift b/third-party/SwiftSVG/Sources/CoreAttributes.swift deleted file mode 100644 index df93043baa..0000000000 --- a/third-party/SwiftSVG/Sources/CoreAttributes.swift +++ /dev/null @@ -1,17 +0,0 @@ -public protocol CoreAttributes { - var id: String? { get set } -} - -enum CoreAttributesKeys: String, CodingKey { - case id -} - -public extension CoreAttributes { - var coreDescription: String { - if let id { - "\(CoreAttributesKeys.id.rawValue)=\"\(id)\"" - } else { - "" - } - } -} diff --git a/third-party/SwiftSVG/Sources/Element.swift b/third-party/SwiftSVG/Sources/Element.swift deleted file mode 100644 index d9a612ef8e..0000000000 --- a/third-party/SwiftSVG/Sources/Element.swift +++ /dev/null @@ -1,46 +0,0 @@ -public protocol Element: CoreAttributes, PresentationAttributes, StylingAttributes {} - -public extension Element { - var attributeDescription: String { - var components: [String] = [] - - if !coreDescription.isEmpty { - components.append(coreDescription) - } - if !presentationDescription.isEmpty { - components.append(presentationDescription) - } - if !stylingDescription.isEmpty { - components.append(stylingDescription) - } - - return components.joined(separator: " ") - } -} - -public extension CommandRepresentable where Self: Element { - /// When a `Path` is accessed on an element, the path that is returned should have the supplied transformations - /// applied. - /// - /// For instance, if - /// * a `Path.data` contains relative elements, - /// * and `transformations` contains a `.translate` - /// - /// Than the path created will not only use 'absolute' instructions, but those instructions will be modified to - /// include the required transformation. - func path(applying transformations: [Transformation] = []) throws -> Path { - var _transformations = transformations - _transformations.append(contentsOf: self.transformations) - - let commands = try commands().map { $0.applying(transformations: _transformations) } - - var path = Path(commands: commands) - path.fillColor = fillColor - path.fillOpacity = fillOpacity - path.strokeColor = strokeColor - path.strokeOpacity = strokeOpacity - path.strokeWidth = strokeWidth - - return path - } -} diff --git a/third-party/SwiftSVG/Sources/Ellipse.swift b/third-party/SwiftSVG/Sources/Ellipse.swift deleted file mode 100644 index bbabf36e61..0000000000 --- a/third-party/SwiftSVG/Sources/Ellipse.swift +++ /dev/null @@ -1,93 +0,0 @@ -import Swift2D -import XMLCoder - -/// SVG basic shape, used to create ellipses based on a center coordinate, and both their x and y radius. -/// -/// The arc of an ‘ellipse’ element begins at the "3 o'clock" point on the radius and progresses towards the -/// "9 o'clock" point. The starting point and direction of the arc are affected by the user space transform in the same -/// manner as the geometry of the element. -public struct Ellipse: Element { - - /// The x position of the ellipse. - public var x: Double = 0.0 - /// The y position of the ellipse. - public var y: Double = 0.0 - /// The radius of the ellipse on the x axis. - public var rx: Double = 0.0 - /// The radius of the ellipse on the y axis. - public var ry: Double = 0.0 - - // MARK: CoreAttributes - - public var id: String? - - // MARK: PresentationAttributes - - public var fillColor: String? - public var fillOpacity: Double? - public var fillRule: Fill.Rule? - public var strokeColor: String? - public var strokeWidth: Double? - public var strokeOpacity: Double? - public var strokeLineCap: Stroke.LineCap? - public var strokeLineJoin: Stroke.LineJoin? - public var strokeMiterLimit: Double? - public var transform: String? - - // MARK: StylingAttributes - - public var style: String? - - enum CodingKeys: String, CodingKey { - case x = "cx" - case y = "cy" - case rx - case ry - case id - case fillColor = "fill" - case fillOpacity = "fill-opacity" - case fillRule = "fill-rule" - case strokeColor = "stroke" - case strokeWidth = "stroke-width" - case strokeOpacity = "stroke-opacity" - case strokeLineCap = "stroke-linecap" - case strokeLineJoin = "stroke-linejoin" - case strokeMiterLimit = "stroke-miterlimit" - case transform - case style - } - - public init() {} - - public init(x: Double, y: Double, rx: Double, ry: Double) { - self.x = x - self.y = y - self.rx = rx - self.ry = ry - } -} - -extension Ellipse: CustomStringConvertible { - public var description: String { - let desc = "" - } -} - -extension Ellipse: DirectionalCommandRepresentable { - public func commands(clockwise: Bool) throws -> [Path.Command] { - EllipseProcessor(ellipse: self).commands(clockwise: clockwise) - } -} - -extension Ellipse: DynamicNodeDecoding { - public static func nodeDecoding(for key: any CodingKey) -> XMLDecoder.NodeDecoding { - .attribute - } -} - -extension Ellipse: DynamicNodeEncoding { - public static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { - .attribute - } -} diff --git a/third-party/SwiftSVG/Sources/Extensions/Point+SwiftSVG.swift b/third-party/SwiftSVG/Sources/Extensions/Point+SwiftSVG.swift deleted file mode 100644 index 0c789bcae3..0000000000 --- a/third-party/SwiftSVG/Sources/Extensions/Point+SwiftSVG.swift +++ /dev/null @@ -1,37 +0,0 @@ -import Swift2D - -extension Point { - static var nan: Point { - Point(x: Double.nan, y: Double.nan) - } - - var hasNaN: Bool { - x.isNaN || y.isNaN - } - - /// Returns a copy of the instance with the **x** value replaced with the provided value. - func with(x value: Double) -> Point { - Point(x: value, y: y) - } - - /// Returns a copy of the instance with the **y** value replaced with the provided value. - func with(y value: Double) -> Point { - Point(x: x, y: value) - } - - /// Adjusts the **x** value by the provided amount. - /// - /// This will explicitly check for `.isNaN`, and if encountered, will simply - /// use the provided value. - func adjusting(x value: Double) -> Point { - (x.isNaN) ? with(x: value) : with(x: x + value) - } - - /// Adjusts the **y** value by the provided amount. - /// - /// This will explicitly check for `.isNaN`, and if encountered, will simply - /// use the provided value. - func adjusting(y value: Double) -> Point { - (y.isNaN) ? with(y: value) : with(y: y + value) - } -} diff --git a/third-party/SwiftSVG/Sources/Fill.swift b/third-party/SwiftSVG/Sources/Fill.swift deleted file mode 100644 index 608192aa29..0000000000 --- a/third-party/SwiftSVG/Sources/Fill.swift +++ /dev/null @@ -1,44 +0,0 @@ -import Swift2D - -public struct Fill { - - public var color: String? - public var opacity: Double? - public var rule: Rule = .nonZero - - public init() {} - - /// Presentation attribute defining the algorithm to use to determine the inside part of a shape. - /// - /// The default `Rule` is `.nonzero`. - public enum Rule: String, Sendable, Codable, CaseIterable { - /// The value evenodd determines the "insideness" of a point in the shape by drawing a ray from that point to - /// infinity in any direction and counting the number of path segments from the given shape that the ray - /// crosses. If this number is odd, the point is inside; if even, the point is outside. - case evenOdd = "evenodd" - /// The value nonzero determines the "insideness" of a point in the shape by drawing a ray from that point to - /// infinity in any direction, and then examining the places where a segment of the shape crosses the ray. - /// Starting with a count of zero, add one each time a path segment crosses the ray from left to right and - /// subtract one each time a path segment crosses the ray from right to left. After counting the crossings, if - /// the result is zero then the point is outside the path. Otherwise, it is inside. - case nonZero = "nonzero" - - public init(from decoder: any Decoder) throws { - let container = try decoder.singleValueContainer() - let rawValue = try container.decode(String.self) - guard let rule = Rule(rawValue: rawValue) else { - print("Attempts to decode Fill.Rule with rawValue: '\(rawValue)'") - self = .nonZero - return - } - - self = rule - } - } -} - -extension Fill.Rule: CustomStringConvertible { - public var description: String { - rawValue - } -} diff --git a/third-party/SwiftSVG/Sources/Group.swift b/third-party/SwiftSVG/Sources/Group.swift deleted file mode 100644 index c95d2d0ad5..0000000000 --- a/third-party/SwiftSVG/Sources/Group.swift +++ /dev/null @@ -1,152 +0,0 @@ -import XMLCoder - -/// A container used to group other SVG elements. -/// -/// Grouping constructs, when used in conjunction with the ‘desc’ and ‘title’ elements, provide information -/// about document structure and semantics. -/// -/// ## Documentation -/// [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g) -/// | [W3](https://www.w3.org/TR/SVG11/struct.html#Groups) -public struct Group: Container, Element { - - // Container - public var circles: [Circle]? - public var ellipses: [Ellipse]? - public var groups: [Group]? - public var lines: [Line]? - public var paths: [Path]? - public var polygons: [Polygon]? - public var polylines: [Polyline]? - public var rectangles: [Rectangle]? - public var texts: [Text]? - - // MARK: CoreAttributes - - public var id: String? - public var title: String? - public var desc: String? - - // MARK: PresentationAttributes - - public var fillColor: String? - public var fillOpacity: Double? - public var fillRule: Fill.Rule? - public var strokeColor: String? - public var strokeWidth: Double? - public var strokeOpacity: Double? - public var strokeLineCap: Stroke.LineCap? - public var strokeLineJoin: Stroke.LineJoin? - public var strokeMiterLimit: Double? - public var transform: String? - - // MARK: StylingAttributes - - public var style: String? - - enum CodingKeys: String, CodingKey { - case circles = "circle" - case ellipses = "ellipse" - case groups = "g" - case lines = "line" - case paths = "path" - case polylines = "polyline" - case polygons = "polygon" - case rectangles = "rect" - case texts = "text" - case id - case title - case desc - case fillColor = "fill" - case fillOpacity = "fill-opacity" - case fillRule = "fill-rule" - case strokeColor = "stroke" - case strokeWidth = "stroke-width" - case strokeOpacity = "stroke-opacity" - case strokeLineCap = "stroke-linecap" - case strokeLineJoin = "stroke-linejoin" - case strokeMiterLimit = "stroke-miterlimit" - case transform - case style - } - - public init() {} - - /// A representation of all the sub-`Path`s in the `Group`. - public func subpaths(applying transformations: [Transformation] = []) throws -> [Path] { - var _transformations = transformations - _transformations.append(contentsOf: self.transformations) - - var output: [Path] = [] - - if let circles { - try output.append(contentsOf: circles.compactMap { try $0.path(applying: _transformations) }) - } - - if let ellipses { - try output.append(contentsOf: ellipses.compactMap { try $0.path(applying: _transformations) }) - } - - if let rectangles { - try output.append(contentsOf: rectangles.compactMap { try $0.path(applying: _transformations) }) - } - - if let polygons { - try output.append(contentsOf: polygons.compactMap { try $0.path(applying: _transformations) }) - } - - if let polylines { - try output.append(contentsOf: polylines.compactMap { try $0.path(applying: _transformations) }) - } - - if let paths { - try output.append(contentsOf: paths.map { try $0.path(applying: _transformations) }) - } - - if let groups { - try groups.forEach { - try output.append(contentsOf: $0.subpaths(applying: _transformations)) - } - } - - return output - } -} - -extension Group: CustomStringConvertible { - public var description: String { - var contents: String = "" - - if let title { - contents.append("\n\(title)") - } - - if let desc { - contents.append("\n\(desc)") - } - - contents.append(containerDescription) - - return "\(contents)\n" - } -} - -extension Group: DynamicNodeDecoding { - public static func nodeDecoding(for key: any CodingKey) -> XMLDecoder.NodeDecoding { - if let _ = ContainerKeys(stringValue: key.stringValue) { - return .element - } - - return .attribute - } -} - -extension Group: DynamicNodeEncoding { - public static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { - if let _ = ContainerKeys(stringValue: key.stringValue) { - return .element - } - - return .attribute - } -} diff --git a/third-party/SwiftSVG/Sources/Internal/EllipseProcessor.swift b/third-party/SwiftSVG/Sources/Internal/EllipseProcessor.swift deleted file mode 100644 index 409c2a7163..0000000000 --- a/third-party/SwiftSVG/Sources/Internal/EllipseProcessor.swift +++ /dev/null @@ -1,88 +0,0 @@ -import Foundation -import Swift2D - -struct EllipseProcessor { - - let x: Double - let y: Double - let rx: Double - let ry: Double - - /// The _optimal_ offset for control points when representing a - /// circle/ellipse as 4 bezier curves. - /// - /// [Stack Overflow](https://stackoverflow.com/questions/1734745/how-to-create-circle-with-bézier-curves) - static func controlPointOffset(_ radius: Double) -> Double { - (Double(4.0 / 3.0) * tan(Double.pi / 8.0)) * radius - } - - init(ellipse: Ellipse) { - x = ellipse.x - y = ellipse.y - rx = ellipse.rx - ry = ellipse.ry - } - - init(circle: Circle) { - x = circle.x - y = circle.y - rx = circle.r - ry = circle.r - } - - func commands(clockwise: Bool) -> [Path.Command] { - var commands: [Path.Command] = [] - - let xOffset = Self.controlPointOffset(rx) - let yOffset = Self.controlPointOffset(ry) - - let zero = Point(x: x + rx, y: y) - let ninety = Point(x: x, y: y - ry) - let oneEighty = Point(x: x - rx, y: y) - let twoSeventy = Point(x: x, y: y + ry) - - var cp1: Point = .zero - var cp2: Point = .zero - - // Starting at degree 0 (the right most point) - commands.append(.moveTo(point: zero)) - - if clockwise { - cp1 = Point(x: zero.x, y: zero.y + yOffset) - cp2 = Point(x: twoSeventy.x + xOffset, y: twoSeventy.y) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: twoSeventy)) - - cp1 = Point(x: twoSeventy.x - xOffset, y: twoSeventy.y) - cp2 = Point(x: oneEighty.x, y: oneEighty.y + yOffset) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: oneEighty)) - - cp1 = Point(x: oneEighty.x, y: oneEighty.y - yOffset) - cp2 = Point(x: ninety.x - xOffset, y: ninety.y) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: ninety)) - - cp1 = Point(x: ninety.x + xOffset, y: ninety.y) - cp2 = Point(x: zero.x, y: zero.y - yOffset) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: zero)) - } else { - cp1 = Point(x: zero.x, y: zero.y - yOffset) - cp2 = Point(x: ninety.x + xOffset, y: ninety.y) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: ninety)) - - cp1 = Point(x: ninety.x - xOffset, y: ninety.y) - cp2 = Point(x: oneEighty.x, y: oneEighty.y - yOffset) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: oneEighty)) - - cp1 = Point(x: oneEighty.x, y: oneEighty.y + yOffset) - cp2 = Point(x: twoSeventy.x - xOffset, y: twoSeventy.y) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: twoSeventy)) - - cp1 = Point(x: twoSeventy.x + xOffset, y: twoSeventy.y) - cp2 = Point(x: zero.x, y: zero.y + yOffset) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: zero)) - } - - commands.append(.closePath) - - return commands - } -} diff --git a/third-party/SwiftSVG/Sources/Internal/PathProcessor.swift b/third-party/SwiftSVG/Sources/Internal/PathProcessor.swift deleted file mode 100644 index 25c808c4d7..0000000000 --- a/third-party/SwiftSVG/Sources/Internal/PathProcessor.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Foundation - -struct PathProcessor { - - let data: String - - func commands() throws -> [Path.Command] { - let parser = Path.ComponentParser() - let components = try Path.Component.components(from: data) - return try parser.parse(components) - } -} diff --git a/third-party/SwiftSVG/Sources/Internal/PolygonProcressor.swift b/third-party/SwiftSVG/Sources/Internal/PolygonProcressor.swift deleted file mode 100644 index d05ab1a408..0000000000 --- a/third-party/SwiftSVG/Sources/Internal/PolygonProcressor.swift +++ /dev/null @@ -1,52 +0,0 @@ -import Foundation -import Swift2D - -struct PolygonProcessor { - - let points: String - - func commands() throws -> [Path.Command] { - let pairs = points.components(separatedBy: " ") - let components = pairs.flatMap { $0.components(separatedBy: ",") } - guard components.count > 0 else { - return [] - } - - guard components.count % 2 == 0 else { - // An odd number of components means that parsing probably failed - return [] - } - - var commands: [Path.Command] = [] - - var firstValue: Bool = true - for (idx, component) in components.enumerated() { - guard let _value = Double(component) else { - return commands - } - - let value = Double(_value) - - if firstValue { - if idx == 0 { - commands.append(.moveTo(point: Point(x: value, y: .nan))) - } else { - commands.append(.lineTo(point: Point(x: value, y: .nan))) - } - firstValue = false - } else { - let count = commands.count - guard let modified = try? commands.last?.adjustingArgument(at: 1, by: value) else { - return commands - } - - commands[count - 1] = modified - firstValue = true - } - } - - commands.append(.closePath) - - return commands - } -} diff --git a/third-party/SwiftSVG/Sources/Internal/PolylineProcessor.swift b/third-party/SwiftSVG/Sources/Internal/PolylineProcessor.swift deleted file mode 100644 index a909c4ed3f..0000000000 --- a/third-party/SwiftSVG/Sources/Internal/PolylineProcessor.swift +++ /dev/null @@ -1,54 +0,0 @@ -import Foundation -import Swift2D - -struct PolylineProcessor { - - let points: String - - func commands() throws -> [Path.Command] { - let pairs = points.components(separatedBy: " ") - let components = pairs.flatMap { $0.components(separatedBy: ",") } - let values = components.compactMap { Double($0) }.map { Double($0) } - - guard values.count > 2 else { - // More than just a starting point is required. - return [] - } - - guard values.count % 2 == 0 else { - // An odd number of components means that parsing probably failed - return [] - } - - var commands: [Path.Command] = [] - - let move = values.prefix(upTo: 2) - let segments = values.suffix(from: 2) - - commands.append(.moveTo(point: Point(x: move[0], y: move[1]))) - - var _value: Double = .nan - for value in segments { - if _value.isNaN { - _value = value - } else { - commands.append(.lineTo(point: Point(x: _value, y: value))) - _value = .nan - } - } - - let reversedSegments = segments.dropLast(2).reversed() - for value in reversedSegments { - if _value.isNaN { - _value = value - } else { - commands.append(.lineTo(point: Point(x: _value, y: value))) - _value = .nan - } - } - - commands.append(.closePath) - - return commands - } -} diff --git a/third-party/SwiftSVG/Sources/Internal/RectangleProcessor.swift b/third-party/SwiftSVG/Sources/Internal/RectangleProcessor.swift deleted file mode 100644 index 2b93440834..0000000000 --- a/third-party/SwiftSVG/Sources/Internal/RectangleProcessor.swift +++ /dev/null @@ -1,175 +0,0 @@ -import Swift2D - -struct RectangleProcessor { - - let rectangle: Rectangle - - func commands(clockwise: Bool) -> [Path.Command] { - var rx = rectangle.rx - var ry = rectangle.ry - - if let _rx = rx, _rx > (rectangle.width / 2.0) { - rx = rectangle.width / 2.0 - } - - if let _ry = ry, _ry > (rectangle.height / 2.0) { - ry = rectangle.height / 2.0 - } - - var commands: [Path.Command] = [] - - switch (rx, ry) { - case (.some(let radiusX), .some(let radiusY)) where radiusX != radiusY: - // Use Cubic Bezier Curve to form rounded corners - // TODO: Verify that the control points are right - - var cp1: Point = .zero - var cp2: Point = .zero - var point: Point = Point(x: rectangle.x + radiusX, y: rectangle.y) - - commands.append(.moveTo(point: point)) - - if clockwise { - point = .init(x: rectangle.x + rectangle.width - radiusX, y: rectangle.y) - commands.append(.lineTo(point: point)) - - cp1 = .init(x: rectangle.x + rectangle.width, y: rectangle.y) - cp2 = cp1 - point = .init(x: rectangle.x + rectangle.width, y: rectangle.y + radiusY) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: point)) - - point = .init(x: rectangle.x + rectangle.width, y: rectangle.y + rectangle.height - radiusY) - commands.append(.lineTo(point: point)) - - cp1 = .init(x: rectangle.x + rectangle.width, y: rectangle.y + rectangle.height) - cp2 = cp1 - point = .init(x: rectangle.x + rectangle.width - radiusX, y: rectangle.y + rectangle.height) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: point)) - - point = .init(x: rectangle.x + radiusX, y: rectangle.y + rectangle.height) - commands.append(.lineTo(point: point)) - - cp1 = .init(x: rectangle.x, y: rectangle.y + rectangle.height) - cp2 = cp1 - point = .init(x: rectangle.x, y: rectangle.y + rectangle.height - radiusY) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: point)) - - point = .init(x: rectangle.x, y: rectangle.y + radiusY) - commands.append(.lineTo(point: point)) - - cp1 = .init(x: rectangle.x, y: rectangle.y) - cp2 = cp1 - point = .init(x: rectangle.x + radiusX, y: rectangle.y) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: point)) - } else { - cp1 = .init(x: rectangle.x, y: rectangle.y) - cp2 = cp1 - point = .init(x: rectangle.x, y: rectangle.y + radiusY) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: point)) - - point = .init(x: rectangle.x, y: rectangle.y + rectangle.height - radiusY) - commands.append(.lineTo(point: point)) - - cp1 = .init(x: rectangle.x, y: rectangle.y + rectangle.height) - cp2 = cp1 - point = .init(x: rectangle.x + radiusX, y: rectangle.y + rectangle.height) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: point)) - - point = .init(x: rectangle.x + rectangle.width - radiusX, y: rectangle.y + rectangle.height) - commands.append(.lineTo(point: point)) - - cp1 = .init(x: rectangle.x + rectangle.width, y: rectangle.y + rectangle.height) - cp2 = cp1 - point = .init(x: rectangle.x + rectangle.width, y: rectangle.y + rectangle.height - radiusY) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: point)) - - point = .init(x: rectangle.x + rectangle.width, y: rectangle.y + radiusY) - commands.append(.lineTo(point: point)) - - cp1 = .init(x: rectangle.x + rectangle.width, y: rectangle.y) - cp2 = cp1 - point = .init(x: rectangle.x + rectangle.width - radiusX, y: rectangle.y) - commands.append(.cubicBezierCurve(cp1: cp1, cp2: cp2, point: point)) - } - case (.some(let radius), .none), (.none, .some(let radius)), (.some(let radius), _): - // use Quadratic Bezier Curve to form rounded corners - - var cp: Point = .zero - var point: Point = Point(x: rectangle.x + radius, y: rectangle.y) - - commands.append(.moveTo(point: point)) - - if clockwise { - point = .init(x: (rectangle.x + rectangle.width) - radius, y: rectangle.y) - commands.append(.lineTo(point: point)) - - cp = .init(x: rectangle.x + rectangle.width, y: rectangle.y) - point = .init(x: rectangle.x + rectangle.width, y: rectangle.y + radius) - commands.append(.quadraticBezierCurve(cp: cp, point: point)) - - point = .init(x: rectangle.x + rectangle.width, y: (rectangle.y + rectangle.height) - radius) - commands.append(.lineTo(point: point)) - - cp = .init(x: rectangle.x + rectangle.width, y: rectangle.y + rectangle.height) - point = .init(x: rectangle.x + rectangle.width - radius, y: rectangle.y + rectangle.height) - commands.append(.quadraticBezierCurve(cp: cp, point: point)) - - point = .init(x: rectangle.x + radius, y: rectangle.y + rectangle.height) - commands.append(.lineTo(point: point)) - - cp = .init(x: rectangle.x, y: rectangle.y + rectangle.height) - point = .init(x: rectangle.x, y: rectangle.y + rectangle.height - radius) - commands.append(.quadraticBezierCurve(cp: cp, point: point)) - - point = .init(x: rectangle.x, y: rectangle.y + radius) - commands.append(.lineTo(point: point)) - - cp = .init(x: rectangle.x, y: rectangle.y) - point = .init(x: rectangle.x + radius, y: rectangle.y) - commands.append(.quadraticBezierCurve(cp: cp, point: point)) - } else { - cp = .init(x: rectangle.x, y: rectangle.y) - point = .init(x: rectangle.x, y: rectangle.y + radius) - commands.append(.quadraticBezierCurve(cp: cp, point: point)) - - point = .init(x: rectangle.x, y: rectangle.y + rectangle.height - radius) - commands.append(.lineTo(point: point)) - - cp = .init(x: rectangle.x, y: rectangle.y + rectangle.height) - point = .init(x: rectangle.x + radius, y: rectangle.y + rectangle.height) - commands.append(.quadraticBezierCurve(cp: cp, point: point)) - - point = .init(x: rectangle.x + rectangle.width - radius, y: rectangle.y + rectangle.height) - commands.append(.lineTo(point: point)) - - cp = .init(x: rectangle.x + rectangle.width, y: rectangle.y + rectangle.height) - point = .init(x: rectangle.x + rectangle.width, y: rectangle.y + rectangle.height - radius) - commands.append(.quadraticBezierCurve(cp: cp, point: point)) - - point = .init(x: rectangle.x + rectangle.width, y: rectangle.y + radius) - commands.append(.lineTo(point: point)) - - cp = .init(x: rectangle.x + rectangle.width, y: rectangle.y) - point = .init(x: rectangle.x + rectangle.width - radius, y: rectangle.y) - commands.append(.quadraticBezierCurve(cp: cp, point: point)) - } - case (.none, .none): - // draw three line segments. - commands.append(.moveTo(point: Point(x: rectangle.x, y: rectangle.y))) - - if clockwise { - commands.append(.lineTo(point: Point(x: rectangle.x + rectangle.width, y: rectangle.y))) - commands.append(.lineTo(point: Point(x: rectangle.x + rectangle.width, y: rectangle.y + rectangle.height))) - commands.append(.lineTo(point: Point(x: rectangle.x, y: rectangle.y + rectangle.height))) - } else { - commands.append(.lineTo(point: Point(x: rectangle.x, y: rectangle.y + rectangle.height))) - commands.append(.lineTo(point: Point(x: rectangle.x + rectangle.width, y: rectangle.y + rectangle.height))) - commands.append(.lineTo(point: Point(x: rectangle.x + rectangle.width, y: rectangle.y))) - } - } - - commands.append(.closePath) - - return commands - } -} diff --git a/third-party/SwiftSVG/Sources/Line.swift b/third-party/SwiftSVG/Sources/Line.swift deleted file mode 100644 index 08ee77488f..0000000000 --- a/third-party/SwiftSVG/Sources/Line.swift +++ /dev/null @@ -1,98 +0,0 @@ -import Swift2D -import XMLCoder - -/// SVG basic shape used to create a line connecting two points. -/// -/// ## Documentation -/// [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/line) -/// | [W3](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/line) -public struct Line: Element { - - /// Defines the x-axis coordinate of the line starting point. - public var x1: Double = 0.0 - /// Defines the x-axis coordinate of the line ending point. - public var y1: Double = 0.0 - /// Defines the y-axis coordinate of the line starting point. - public var x2: Double = 0.0 - /// Defines the y-axis coordinate of the line ending point. - public var y2: Double = 0.0 - - // MARK: CoreAttributes - - public var id: String? - - // MARK: PresentationAttributes - - public var fillColor: String? - public var fillOpacity: Double? - public var fillRule: Fill.Rule? - public var strokeColor: String? - public var strokeWidth: Double? - public var strokeOpacity: Double? - public var strokeLineCap: Stroke.LineCap? - public var strokeLineJoin: Stroke.LineJoin? - public var strokeMiterLimit: Double? - public var transform: String? - - // MARK: StylingAttributes - - public var style: String? - - enum CodingKeys: String, CodingKey { - case x1 - case y1 - case x2 - case y2 - case id - case fillColor = "fill" - case fillOpacity = "fill-opacity" - case fillRule = "fill-rule" - case strokeColor = "stroke" - case strokeWidth = "stroke-width" - case strokeOpacity = "stroke-opacity" - case strokeLineCap = "stroke-linecap" - case strokeLineJoin = "stroke-linejoin" - case strokeMiterLimit = "stroke-miterlimit" - case transform - case style - } - - public init() {} - - public init(x1: Double, y1: Double, x2: Double, y2: Double) { - self.x1 = x1 - self.y1 = y1 - self.x2 = x2 - self.y2 = y2 - } -} - -extension Line: CommandRepresentable { - public func commands() throws -> [Path.Command] { - [ - .moveTo(point: Point(x: x1, y: y1)), - .lineTo(point: Point(x: x2, y: y2)), - .lineTo(point: Point(x: x1, y: y1)), - .closePath, - ] - } -} - -extension Line: CustomStringConvertible { - public var description: String { - let desc = "" - } -} - -extension Line: DynamicNodeDecoding { - public static func nodeDecoding(for key: any CodingKey) -> XMLDecoder.NodeDecoding { - .attribute - } -} - -extension Line: DynamicNodeEncoding { - public static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { - .attribute - } -} diff --git a/third-party/SwiftSVG/Sources/Path.Command.swift b/third-party/SwiftSVG/Sources/Path.Command.swift deleted file mode 100644 index e0fb49a729..0000000000 --- a/third-party/SwiftSVG/Sources/Path.Command.swift +++ /dev/null @@ -1,276 +0,0 @@ -import Foundation -import Swift2D - -public extension Path { - /// Path commands are instructions that define a path to be drawn. - /// - /// Each command is composed of a command letter and numbers that represent the command parameters. - enum Command: Equatable, Sendable, CustomStringConvertible { - /// Moves the current drawing point - case moveTo(point: Point) - /// Draw a straight line from the current point to the point provided - case lineTo(point: Point) - /// Draw a smooth curve using three points (+ origin) - case cubicBezierCurve(cp1: Point, cp2: Point, point: Point) - /// Draw a smooth curve using two points (+ origin) - case quadraticBezierCurve(cp: Point, point: Point) - /// Draw a curve defined as a portion of an ellipse - case ellipticalArcCurve(rx: Double, ry: Double, angle: Double, largeArc: Bool, clockwise: Bool, point: Point) - /// ClosePath instructions draw a straight line from the current position to the first point in the path. - case closePath - - public enum Prefix: Character, CaseIterable { - case move = "M" - case relativeMove = "m" - case line = "L" - case relativeLine = "l" - case horizontalLine = "H" - case relativeHorizontalLine = "h" - case verticalLine = "V" - case relativeVerticalLine = "v" - case cubicBezierCurve = "C" - case relativeCubicBezierCurve = "c" - case smoothCubicBezierCurve = "S" - case relativeSmoothCubicBezierCurve = "s" - case quadraticBezierCurve = "Q" - case relativeQuadraticBezierCurve = "q" - case smoothQuadraticBezierCurve = "T" - case relativeSmoothQuadraticBezierCurve = "t" - case ellipticalArcCurve = "A" - case relativeEllipticalArcCurve = "a" - case close = "Z" - case relativeClose = "z" - - public static var characterSet: CharacterSet { - CharacterSet(charactersIn: allCases.map { String($0.rawValue) }.joined()) - } - } - - public enum Coordinates { - case absolute - case relative - } - - public enum Error: Swift.Error { - case message(String) - case invalidAdjustment(Path.Command) - case invalidArgumentPosition(Int, Path.Command) - case invalidRelativeCommand - } - - public var description: String { - switch self { - case .moveTo(let point): - return "\(Prefix.move.rawValue)\(point.x),\(point.y)" - case .lineTo(let point): - return "\(Prefix.line.rawValue)\(point.x),\(point.y)" - case .cubicBezierCurve(let cp1, let cp2, let point): - return "\(Prefix.cubicBezierCurve.rawValue)\(cp1.x),\(cp1.y) \(cp2.x),\(cp2.y) \(point.x),\(point.y)" - case .quadraticBezierCurve(let cp, let point): - return "\(Prefix.quadraticBezierCurve.rawValue)\(cp.x),\(cp.y) \(point.x),\(point.y)" - case .ellipticalArcCurve(let rx, let ry, let angle, let largeArc, let clockwise, let point): - let la = largeArc ? 1 : 0 - let cw = clockwise ? 1 : 0 - return "\(Prefix.ellipticalArcCurve.rawValue)\(rx) \(ry) \(angle) \(la) \(cw) \(point.x) \(point.y)" - case .closePath: - return "\(Prefix.close.rawValue)" - } - } - - /// The primary point that dictates the commands action. - public var point: Point { - switch self { - case .moveTo(let point): point - case .lineTo(let point): point - case .cubicBezierCurve(_, _, let point): point - case .quadraticBezierCurve(_, let point): point - case .ellipticalArcCurve(_, _, _, _, _, let point): point - case .closePath: .zero - } - } - } -} - -public extension Path.Command { - /// Applies the provided `Transformation` to the instances values. - func applying(transformation: Transformation) -> Path.Command { - switch transformation { - case .translate(let x, let y): - switch self { - case .moveTo(let point): - let _point = point.adjusting(x: x).adjusting(y: y) - return .moveTo(point: _point) - case .lineTo(let point): - let _point = point.adjusting(x: x).adjusting(y: y) - return .lineTo(point: _point) - case .cubicBezierCurve(let cp1, let cp2, let point): - let _cp1 = cp1.adjusting(x: x).adjusting(y: y) - let _cp2 = cp2.adjusting(x: x).adjusting(y: y) - let _point = point.adjusting(x: x).adjusting(y: y) - return .cubicBezierCurve(cp1: _cp1, cp2: _cp2, point: _point) - case .quadraticBezierCurve(let cp, let point): - let _cp = cp.adjusting(x: x).adjusting(y: y) - let _point = point.adjusting(x: x).adjusting(y: y) - return .quadraticBezierCurve(cp: _cp, point: _point) - case .ellipticalArcCurve(let rx, let ry, let angle, let largeArc, let clockwise, let point): - let _point = point.adjusting(x: x).adjusting(y: y) - return .ellipticalArcCurve(rx: rx, ry: ry, angle: angle, largeArc: largeArc, clockwise: clockwise, point: _point) - case .closePath: - return self - } - case .matrix: - // TODO: What should occur here? - return self - } - } - - /// Applies multiple transformations in the order they are specified. - func applying(transformations: [Transformation]) -> Path.Command { - var command = self - - for transformation in transformations { - command = command.applying(transformation: transformation) - } - - return command - } -} - -extension Path.Command { - /// Determines if all values are provided (i.e. !.isNaN) - var isComplete: Bool { - switch self { - case .moveTo(let point), .lineTo(let point): - !point.hasNaN - case .cubicBezierCurve(let cp1, let cp2, let point): - !cp1.hasNaN && !cp2.hasNaN && !point.hasNaN - case .quadraticBezierCurve(let cp, let point): - !cp.hasNaN && !point.hasNaN - case .ellipticalArcCurve(let rx, let ry, let angle, _, _, let point): - !rx.isNaN && !ry.isNaN && !angle.isNaN && !point.hasNaN - case .closePath: - true - } - } - - /// The last control point used in drawing the path. - /// - /// Only valid for curves. - var lastControlPoint: Point? { - switch self { - case .cubicBezierCurve(_, let cp2, _): - cp2 - case .quadraticBezierCurve(let cp, _): - cp - default: - nil - } - } - - /// A mirror representation of `lastControlPoint`. - var lastControlPointMirror: Point? { - guard let cp = lastControlPoint else { - return nil - } - - return Point(x: point.x + (point.x - cp.x), y: point.y + (point.y - cp.y)) - } - - /// The total number of argument values the command requires. - var arguments: Int { - switch self { - case .moveTo: 2 - case .lineTo: 2 - case .cubicBezierCurve: 6 - case .quadraticBezierCurve: 4 - case .ellipticalArcCurve: 7 - case .closePath: 0 - } - } - - /// Adjusts a Command argument by a specified amount. - /// - /// A `Point` consumes two positions. So, in the example `.quadraticBezierCurve(cp: .zero, point: .zero)`: - /// * position 0 = Control Point X - /// * position 1 = Control Point Y - /// * position 2 = Point X - /// * position 3 = Point Y - /// - /// - parameter position: The index of the argument parameter to adjust. - /// - parameter value: The value to add to the existing value. If the current value equal `.isNaN`, than the - /// supplied value is used as-is. - /// - throws: `Path.Command.Error` - func adjustingArgument(at position: Int, by value: Double) throws -> Path.Command { - switch self { - case .moveTo(let point): - switch position { - case 0: - return .moveTo(point: point.adjusting(x: value)) - case 1: - return .moveTo(point: point.adjusting(y: value)) - default: - throw Path.Command.Error.invalidArgumentPosition(position, self) - } - case .lineTo(let point): - switch position { - case 0: - return .lineTo(point: point.adjusting(x: value)) - case 1: - return .lineTo(point: point.adjusting(y: value)) - default: - throw Path.Command.Error.invalidArgumentPosition(position, self) - } - case .cubicBezierCurve(let cp1, let cp2, let point): - switch position { - case 0: - return .cubicBezierCurve(cp1: cp1.adjusting(x: value), cp2: cp2, point: point) - case 1: - return .cubicBezierCurve(cp1: cp1.adjusting(y: value), cp2: cp2, point: point) - case 2: - return .cubicBezierCurve(cp1: cp1, cp2: cp2.adjusting(x: value), point: point) - case 3: - return .cubicBezierCurve(cp1: cp1, cp2: cp2.adjusting(y: value), point: point) - case 4: - return .cubicBezierCurve(cp1: cp1, cp2: cp2, point: point.adjusting(x: value)) - case 5: - return .cubicBezierCurve(cp1: cp1, cp2: cp2, point: point.adjusting(y: value)) - default: - throw Path.Command.Error.invalidArgumentPosition(position, self) - } - case .quadraticBezierCurve(let cp, let point): - switch position { - case 0: - return .quadraticBezierCurve(cp: cp.adjusting(x: value), point: point) - case 1: - return .quadraticBezierCurve(cp: cp.adjusting(y: value), point: point) - case 2: - return .quadraticBezierCurve(cp: cp, point: point.adjusting(x: value)) - case 3: - return .quadraticBezierCurve(cp: cp, point: point.adjusting(y: value)) - default: - throw Path.Command.Error.invalidArgumentPosition(position, self) - } - case .ellipticalArcCurve(let rx, let ry, let angle, let largeArc, let clockwise, let point): - switch position { - case 0: - return .ellipticalArcCurve(rx: value, ry: ry, angle: angle, largeArc: largeArc, clockwise: clockwise, point: point) - case 1: - return .ellipticalArcCurve(rx: rx, ry: value, angle: angle, largeArc: largeArc, clockwise: clockwise, point: point) - case 2: - return .ellipticalArcCurve(rx: rx, ry: ry, angle: value, largeArc: largeArc, clockwise: clockwise, point: point) - case 3: - return .ellipticalArcCurve(rx: rx, ry: ry, angle: angle, largeArc: !value.isZero, clockwise: clockwise, point: point) - case 4: - return .ellipticalArcCurve(rx: rx, ry: ry, angle: angle, largeArc: largeArc, clockwise: !value.isZero, point: point) - case 5: - return .ellipticalArcCurve(rx: rx, ry: ry, angle: angle, largeArc: largeArc, clockwise: clockwise, point: point.adjusting(x: value)) - case 6: - return .ellipticalArcCurve(rx: rx, ry: ry, angle: angle, largeArc: largeArc, clockwise: clockwise, point: point.adjusting(y: value)) - default: - throw Path.Command.Error.invalidArgumentPosition(position, self) - } - case .closePath: - throw Path.Command.Error.invalidAdjustment(self) - } - } -} diff --git a/third-party/SwiftSVG/Sources/Path.Component.swift b/third-party/SwiftSVG/Sources/Path.Component.swift deleted file mode 100644 index 6c02251142..0000000000 --- a/third-party/SwiftSVG/Sources/Path.Component.swift +++ /dev/null @@ -1,98 +0,0 @@ -import Foundation - -public extension Path { - /// A unit of a SVG path data string. - enum Component { - case prefix(Command.Prefix) - case value(Double) - - /// Interprets a `Path` `data` attribute into individual `Component`s for command processing. - public static func components(from data: String) throws -> [Component] { - var blocks: [String] = [] - var block: String = "" - - for scalar in data.unicodeScalars { - if scalar == "e" { - // Account for exponential value notation. - block.append(String(scalar)) - continue - } - - if CharacterSet.letters.contains(scalar) { - if !block.isEmpty { - blocks.append(block) - block = "" - } - - blocks.append(String(scalar)) - continue - } - - if CharacterSet.whitespaces.contains(scalar) { - if !block.isEmpty { - blocks.append(block) - block = "" - } - - continue - } - - if CharacterSet(charactersIn: ",").contains(scalar) { - if !block.isEmpty { - blocks.append(block) - block = "" - } - - continue - } - - if CharacterSet(charactersIn: "-").contains(scalar) { - if !block.isEmpty, block.last != "e" { - // Again, account for exponential values. - blocks.append(block) - block = "" - } - - block.append(String(scalar)) - continue - } - - if CharacterSet(charactersIn: ".").contains(scalar) { - if block.contains(".") { - // Already decimal value, this is a new value - blocks.append(block) - block = "" - } - - block.append(String(scalar)) - continue - } - - if CharacterSet.decimalDigits.contains(scalar) { - block.append(String(scalar)) - continue - } - - print("Unhandled Character: \(scalar)") - } - - if !block.isEmpty { - blocks.append(block) - block = "" - } - - return blocks - .filter { !$0.isEmpty } - .compactMap { - if let prefix = Path.Command.Prefix(rawValue: $0.first!) { - .prefix(prefix) - } else if let value = Double($0) { - .value(value) - } else { - // throw in the future? - nil - } - } - } - } -} diff --git a/third-party/SwiftSVG/Sources/Path.ComponentParser.swift b/third-party/SwiftSVG/Sources/Path.ComponentParser.swift deleted file mode 100644 index c64c682a6b..0000000000 --- a/third-party/SwiftSVG/Sources/Path.ComponentParser.swift +++ /dev/null @@ -1,275 +0,0 @@ -import Swift2D - -public extension Path { - /// Utility used to construct a collection of `Path.Command` from a collection of `Path.Component`. - class ComponentParser { - /// The command currently being built - private var command: Path.Command? - /// Coordinate system being used - private var coordinates: Path.Command.Coordinates = .absolute - /// The argument position of the _command_ to be processed. - private var position: Int = 0 - /// Indicates that only a single value will be processed on the next component pass. - private var singleValue: Bool = false - /// The originating coordinates of the path. - private var pathOrigin: Point = .nan - /// The last point as processed by the parser. - private var currentPoint: Point = .zero - - public init() {} - - public func parse(_ components: [Path.Component]) throws -> [Path.Command] { - var commands: [Path.Command] = [] - - try components.forEach { component in - if let command = try parse(component, lastCommand: commands.last) { - commands.append(command) - } - } - - return commands - } - - private func parse(_ component: Path.Component, lastCommand: Path.Command?) throws -> Path.Command? { - switch component { - case .prefix(let prefix): - setup(prefix: prefix, lastCommand: lastCommand) - case .value(let value): - try process(value: value, lastCommand: lastCommand) - } - } - - private func setup(prefix: Path.Command.Prefix, lastCommand: Path.Command?) -> Path.Command? { - position = 0 - singleValue = false - - switch prefix { - case .move: - command = .moveTo(point: .nan) - coordinates = .absolute - case .relativeMove: - command = .moveTo(point: currentPoint) - coordinates = .relative - case .line: - command = .lineTo(point: .nan) - coordinates = .absolute - case .relativeLine: - command = .lineTo(point: currentPoint) - coordinates = .relative - case .horizontalLine: - command = .lineTo(point: currentPoint.with(x: .nan)) - coordinates = .absolute - case .relativeHorizontalLine: - command = .lineTo(point: currentPoint) - coordinates = .relative - singleValue = true - case .verticalLine: - command = .lineTo(point: currentPoint.with(y: .nan)) - coordinates = .absolute - position = 1 - case .relativeVerticalLine: - command = .lineTo(point: currentPoint) - coordinates = .relative - position = 1 - singleValue = true - case .cubicBezierCurve: - command = .cubicBezierCurve(cp1: .nan, cp2: .nan, point: .nan) - coordinates = .absolute - case .relativeCubicBezierCurve: - command = .cubicBezierCurve(cp1: currentPoint, cp2: currentPoint, point: currentPoint) - coordinates = .relative - case .smoothCubicBezierCurve: - if case .cubicBezierCurve(_, let cp, _) = lastCommand { - command = .cubicBezierCurve(cp1: cp.reflecting(around: currentPoint), cp2: .nan, point: .nan) - } else { - command = .cubicBezierCurve(cp1: currentPoint, cp2: .nan, point: .nan) - } - coordinates = .absolute - position = 2 - case .relativeSmoothCubicBezierCurve: - if case .cubicBezierCurve(_, let cp, _) = lastCommand { - command = .cubicBezierCurve(cp1: cp.reflecting(around: cp.reflecting(around: currentPoint)), cp2: currentPoint, point: currentPoint) - } else { - command = .cubicBezierCurve(cp1: currentPoint, cp2: currentPoint, point: currentPoint) - } - coordinates = .relative - position = 2 - case .quadraticBezierCurve: - command = .quadraticBezierCurve(cp: .nan, point: .nan) - coordinates = .absolute - case .relativeQuadraticBezierCurve: - command = .quadraticBezierCurve(cp: currentPoint, point: currentPoint) - coordinates = .relative - case .smoothQuadraticBezierCurve: - if case .quadraticBezierCurve(let cp, _) = lastCommand { - command = .quadraticBezierCurve(cp: cp.reflecting(around: currentPoint), point: .nan) - } else { - command = .quadraticBezierCurve(cp: currentPoint, point: .nan) - } - coordinates = .absolute - position = 2 - case .relativeSmoothQuadraticBezierCurve: - if case .quadraticBezierCurve(let cp, _) = lastCommand { - command = .quadraticBezierCurve(cp: cp.reflecting(around: currentPoint), point: currentPoint) - } else { - command = .quadraticBezierCurve(cp: currentPoint, point: currentPoint) - } - coordinates = .relative - position = 2 - case .ellipticalArcCurve: - command = .ellipticalArcCurve(rx: .nan, ry: .nan, angle: .nan, largeArc: false, clockwise: false, point: .nan) - coordinates = .absolute - case .relativeEllipticalArcCurve: - command = .ellipticalArcCurve(rx: .nan, ry: .nan, angle: .nan, largeArc: false, clockwise: false, point: currentPoint) - coordinates = .relative - case .close, .relativeClose: - currentPoint = pathOrigin - reset() - return .closePath - } - - return nil - } - - private func process(value: Double, lastCommand: Path.Command?) throws -> Path.Command? { - if let command { - try continueCommand(command, with: value) - } else { - try nextCommand(with: value, lastCommand: lastCommand) - } - - if let command, command.isComplete { - switch coordinates { - case .relative: - guard position == -1 else { - return nil - } - - fallthrough - case .absolute: - currentPoint = command.point - if case .moveTo = command { - pathOrigin = command.point - } - reset() - return command - } - } else { - return nil - } - } - - private func continueCommand(_ command: Path.Command, with value: Double) throws { - switch command { - case .moveTo, .cubicBezierCurve, .quadraticBezierCurve, .ellipticalArcCurve: - self.command = try command.adjustingArgument(at: position, by: value) - switch coordinates { - case .absolute: - position += 1 - case .relative: - switch position { - case 0 ... (command.arguments - 2): - position += 1 - case command.arguments - 1: - position = -1 - default: - break // throw? - } - } - case .lineTo: - self.command = try command.adjustingArgument(at: position, by: value) - switch coordinates { - case .absolute: - position += 1 - case .relative: - switch position { - case 0: - if singleValue { - singleValue = false - position = -1 - } else { - position += 1 - } - case 1: - if singleValue { - singleValue = false - } - position = -1 - default: - break // throw? - } - } - case .closePath: - break - } - } - - private func nextCommand(with value: Double, lastCommand: Path.Command?) throws { - guard let command = lastCommand else { - throw Path.Command.Error.invalidRelativeCommand - } - - switch command { - case .moveTo: - switch coordinates { - case .absolute: - self.command = .lineTo(point: Point(x: value, y: .nan)) - position = 1 - case .relative: - let c = Path.Command.lineTo(point: command.point) - self.command = try c.adjustingArgument(at: 0, by: value) - position = 1 - } - case .lineTo: - switch coordinates { - case .absolute: - self.command = .lineTo(point: Point(x: value, y: .nan)) - position = 1 - case .relative: - let c = Path.Command.lineTo(point: command.point) - self.command = try c.adjustingArgument(at: 0, by: value) - position = 1 - } - case .cubicBezierCurve: - switch coordinates { - case .absolute: - self.command = .cubicBezierCurve(cp1: Point(x: value, y: .nan), cp2: .nan, point: .nan) - position = 1 - case .relative: - let c = Path.Command.cubicBezierCurve(cp1: command.point, cp2: command.point, point: command.point) - self.command = try c.adjustingArgument(at: 0, by: value) - position = 1 - } - case .quadraticBezierCurve: - switch coordinates { - case .absolute: - self.command = .quadraticBezierCurve(cp: Point(x: value, y: .nan), point: .nan) - position = 1 - case .relative: - let c = Path.Command.quadraticBezierCurve(cp: command.point, point: command.point) - self.command = try c.adjustingArgument(at: 0, by: value) - position = 1 - } - case .ellipticalArcCurve: - switch coordinates { - case .absolute: - self.command = .ellipticalArcCurve(rx: value, ry: .nan, angle: .nan, largeArc: false, clockwise: false, point: .nan) - position = 1 - case .relative: - let c = Path.Command.ellipticalArcCurve(rx: .nan, ry: .nan, angle: .nan, largeArc: false, clockwise: false, point: command.point) - self.command = try c.adjustingArgument(at: 0, by: value) - position = 1 - } - case .closePath: - break - } - } - - private func reset() { - command = nil - coordinates = .absolute - position = 0 - singleValue = false - } - } -} diff --git a/third-party/SwiftSVG/Sources/Path.swift b/third-party/SwiftSVG/Sources/Path.swift deleted file mode 100644 index 9c02c65704..0000000000 --- a/third-party/SwiftSVG/Sources/Path.swift +++ /dev/null @@ -1,101 +0,0 @@ -import XMLCoder - -/// Generic element to define a shape. -/// -/// A path is defined by including a ‘path’ element in a SVG document which contains a **d="(path data)"** -/// attribute, where the **‘d’** attribute contains the moveto, line, curve (both Cubic and Quadratic Bézier), -/// arc and closepath instructions. -/// -/// ## Documentation -/// [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path) -/// | [W3](https://www.w3.org/TR/SVG11/paths.html) -public struct Path: Element { - - /// The definition of the outline of a shape. - public var data: String = "" - - // MARK: CoreAttributes - - public var id: String? - - // MARK: PresentationAttributes - - public var fillColor: String? - public var fillOpacity: Double? - public var fillRule: Fill.Rule? - public var strokeColor: String? - public var strokeWidth: Double? - public var strokeOpacity: Double? - public var strokeLineCap: Stroke.LineCap? - public var strokeLineJoin: Stroke.LineJoin? - public var strokeMiterLimit: Double? - public var transform: String? - - // MARK: StylingAttributes - - public var style: String? - - enum CodingKeys: String, CodingKey { - case data = "d" - case id - case fillColor = "fill" - case fillOpacity = "fill-opacity" - case fillRule = "fill-rule" - case strokeColor = "stroke" - case strokeWidth = "stroke-width" - case strokeOpacity = "stroke-opacity" - case strokeLineCap = "stroke-linecap" - case strokeLineJoin = "stroke-linejoin" - case strokeMiterLimit = "stroke-miterlimit" - case transform - case style - } - - public init() {} - - public init(data: String) { - self.init() - self.data = data - } - - public init(commands: [Path.Command]) { - self.init() - data = commands.map(\.description).joined() - } -} - -extension Path: CommandRepresentable { - public func commands() throws -> [Command] { - try PathProcessor(data: data).commands() - } -} - -extension Path: CustomStringConvertible { - public var description: String { - "" - } -} - -extension Path: DynamicNodeDecoding { - public static func nodeDecoding(for key: any CodingKey) -> XMLDecoder.NodeDecoding { - .attribute - } -} - -extension Path: DynamicNodeEncoding { - public static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { - .attribute - } -} - -extension Path: Equatable { - public static func == (lhs: Path, rhs: Path) -> Bool { - do { - let lhsCommands = try lhs.commands() - let rhsCommands = try rhs.commands() - return lhsCommands == rhsCommands - } catch { - return false - } - } -} diff --git a/third-party/SwiftSVG/Sources/Polygon.swift b/third-party/SwiftSVG/Sources/Polygon.swift deleted file mode 100644 index 84320b929f..0000000000 --- a/third-party/SwiftSVG/Sources/Polygon.swift +++ /dev/null @@ -1,82 +0,0 @@ -import XMLCoder - -/// Defines a closed shape consisting of a set of connected straight line segments. -/// -/// The last point is connected to the first point. For open shapes, see the `Polyline` element. If an odd number of -/// coordinates is provided, then the element is in error. -/// -/// ## Documentation -/// [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polygon) -/// | [W3](https://www.w3.org/TR/SVG11/shapes.html#PolygonElement) -public struct Polygon: Element { - - /// The points that make up the polygon. - public var points: String = "" - - // MARK: CoreAttributes - - public var id: String? - - // MARK: PresentationAttributes - - public var fillColor: String? - public var fillOpacity: Double? - public var fillRule: Fill.Rule? - public var strokeColor: String? - public var strokeWidth: Double? - public var strokeOpacity: Double? - public var strokeLineCap: Stroke.LineCap? - public var strokeLineJoin: Stroke.LineJoin? - public var strokeMiterLimit: Double? - public var transform: String? - - // MARK: StylingAttributes - - public var style: String? - - enum CodingKeys: String, CodingKey { - case points - case id - case fillColor = "fill" - case fillOpacity = "fill-opacity" - case fillRule = "fill-rule" - case strokeColor = "stroke" - case strokeWidth = "stroke-width" - case strokeOpacity = "stroke-opacity" - case strokeLineCap = "stroke-linecap" - case strokeLineJoin = "stroke-linejoin" - case strokeMiterLimit = "stroke-miterlimit" - case transform - case style - } - - public init() {} - - public init(points: String) { - self.points = points - } -} - -extension Polygon: CommandRepresentable { - public func commands() throws -> [Path.Command] { - try PolygonProcessor(points: points).commands() - } -} - -extension Polygon: CustomStringConvertible { - public var description: String { - "" - } -} - -extension Polygon: DynamicNodeDecoding { - public static func nodeDecoding(for key: any CodingKey) -> XMLDecoder.NodeDecoding { - .attribute - } -} - -extension Polygon: DynamicNodeEncoding { - public static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { - .attribute - } -} diff --git a/third-party/SwiftSVG/Sources/Polyline.swift b/third-party/SwiftSVG/Sources/Polyline.swift deleted file mode 100644 index 5fb8c930c4..0000000000 --- a/third-party/SwiftSVG/Sources/Polyline.swift +++ /dev/null @@ -1,81 +0,0 @@ -import XMLCoder - -/// SVG basic shape that creates straight lines connecting several points. -/// -/// Typically a polyline is used to create open shapes as the last point doesn't have to be connected to the first -/// point. For closed shapes see the `Polygon` element. -/// -/// ## Documentation -/// [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polyline) -/// | [W3](https://www.w3.org/TR/SVG11/shapes.html#PolylineElement) -public struct Polyline: Element { - - public var points: String = "" - - // MARK: CoreAttributes - - public var id: String? - - // MARK: PresentationAttributes - - public var fillColor: String? - public var fillOpacity: Double? - public var fillRule: Fill.Rule? - public var strokeColor: String? - public var strokeWidth: Double? - public var strokeOpacity: Double? - public var strokeLineCap: Stroke.LineCap? - public var strokeLineJoin: Stroke.LineJoin? - public var strokeMiterLimit: Double? - public var transform: String? - - // MARK: StylingAttributes - - public var style: String? - - enum CodingKeys: String, CodingKey { - case points - case id - case fillColor = "fill" - case fillOpacity = "fill-opacity" - case fillRule = "fill-rule" - case strokeColor = "stroke" - case strokeWidth = "stroke-width" - case strokeOpacity = "stroke-opacity" - case strokeLineCap = "stroke-linecap" - case strokeLineJoin = "stroke-linejoin" - case strokeMiterLimit = "stroke-miterlimit" - case transform - case style - } - - public init() {} - - public init(points: String) { - self.points = points - } -} - -extension Polyline: CommandRepresentable { - public func commands() throws -> [Path.Command] { - try PolylineProcessor(points: points).commands() - } -} - -extension Polyline: CustomStringConvertible { - public var description: String { - "" - } -} - -extension Polyline: DynamicNodeDecoding { - public static func nodeDecoding(for key: any CodingKey) -> XMLDecoder.NodeDecoding { - .attribute - } -} - -extension Polyline: DynamicNodeEncoding { - public static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { - .attribute - } -} diff --git a/third-party/SwiftSVG/Sources/PresentationAttributes.swift b/third-party/SwiftSVG/Sources/PresentationAttributes.swift deleted file mode 100644 index 5cd6598df3..0000000000 --- a/third-party/SwiftSVG/Sources/PresentationAttributes.swift +++ /dev/null @@ -1,120 +0,0 @@ -import Foundation -import Swift2D - -public protocol PresentationAttributes { - var fillColor: String? { get set } - var fillOpacity: Double? { get set } - var fillRule: Fill.Rule? { get set } - var strokeColor: String? { get set } - var strokeWidth: Double? { get set } - var strokeOpacity: Double? { get set } - var strokeLineCap: Stroke.LineCap? { get set } - var strokeLineJoin: Stroke.LineJoin? { get set } - var strokeMiterLimit: Double? { get set } - var transform: String? { get set } -} - -enum PresentationAttributesKeys: String, CodingKey { - case fillColor = "fill" - case fillOpacity = "fill-opacity" - case fillRule = "fill-rule" - case strokeColor = "stroke" - case strokeWidth = "stroke-width" - case strokeOpacity = "stroke-opacity" - case strokeLineCap = "stroke-linecap" - case strokeLineJoin = "stroke-linejoin" - case strokeMiterLimit = "stroke-miterlimit" - case transform -} - -public extension PresentationAttributes { - var presentationDescription: String { - var attributes: [String] = [] - - if let fillColor { - attributes.append("\(PresentationAttributesKeys.fillColor.rawValue)=\"\(fillColor)\"") - } - if let fillOpacity { - attributes.append("\(PresentationAttributesKeys.fillOpacity.rawValue)=\"\(fillOpacity)\"") - } - if let fillRule { - attributes.append("\(PresentationAttributesKeys.fillRule.rawValue)=\"\(fillRule.description)\"") - } - if let strokeColor { - attributes.append("\(PresentationAttributesKeys.strokeColor.rawValue)=\"\(strokeColor)\"") - } - if let strokeWidth { - attributes.append("\(PresentationAttributesKeys.strokeWidth.rawValue)=\"\(strokeWidth)\"") - } - if let strokeOpacity { - attributes.append("\(PresentationAttributesKeys.strokeOpacity.rawValue)=\"\(strokeOpacity)\"") - } - if let strokeLineCap { - attributes.append("\(PresentationAttributesKeys.strokeLineCap.rawValue)=\"\(strokeLineCap.description)\"") - } - if let strokeLineJoin { - attributes.append("\(PresentationAttributesKeys.strokeLineJoin.rawValue)=\"\(strokeLineJoin.description)\"") - } - if let strokeMiterLimit { - attributes.append("\(PresentationAttributesKeys.strokeMiterLimit.rawValue)=\"\(strokeMiterLimit)\"") - } - if let transform { - attributes.append("\(PresentationAttributesKeys.transform.rawValue)=\"\(transform)\"") - } - - return attributes.joined(separator: " ") - } - - var transformations: [Transformation] { - let value = transform?.replacingOccurrences(of: " ", with: "") ?? "" - guard !value.isEmpty else { - return [] - } - - let values = value.split(separator: ")").map { $0.appending(")") } - return values.compactMap { Transformation($0) } - } - - var fill: Fill? { - get { - if fillColor == nil, fillOpacity == nil { - return nil - } - - var fill = Fill() - fill.color = fillColor ?? "black" - fill.opacity = fillOpacity ?? 1.0 - return fill - } - set { - fillColor = newValue?.color - fillOpacity = newValue?.opacity - fillRule = newValue?.rule - } - } - - var stroke: Stroke? { - get { - if strokeColor == nil, strokeOpacity == nil { - return nil - } - - var stroke = Stroke() - stroke.color = strokeColor ?? "black" - stroke.opacity = strokeOpacity ?? 1.0 - stroke.width = strokeWidth ?? 1.0 - stroke.lineCap = strokeLineCap ?? .butt - stroke.lineJoin = strokeLineJoin ?? .miter - stroke.miterLimit = strokeMiterLimit - return stroke - } - set { - strokeColor = newValue?.color - strokeOpacity = newValue?.opacity - strokeWidth = newValue?.width - strokeLineCap = newValue?.lineCap - strokeLineJoin = newValue?.lineJoin - strokeMiterLimit = newValue?.miterLimit - } - } -} diff --git a/third-party/SwiftSVG/Sources/Rectangle.swift b/third-party/SwiftSVG/Sources/Rectangle.swift deleted file mode 100644 index 4f663b846d..0000000000 --- a/third-party/SwiftSVG/Sources/Rectangle.swift +++ /dev/null @@ -1,115 +0,0 @@ -import Swift2D -import XMLCoder - -/// Basic SVG shape that draws rectangles, defined by their position, width, and height. -/// -/// The values used for the x- and y-axis rounded corner radii are determined implicitly -/// if the ‘rx’ or ‘ry’ attributes (or both) are not specified, or are specified but with invalid values. -/// -/// ## Documentation -/// [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/rect) -/// | [W3](https://www.w3.org/TR/SVG11/shapes.html#RectElement) -public struct Rectangle: Element { - - /// The x-axis coordinate of the side of the rectangle which - /// has the smaller x-axis coordinate value. - public var x: Double = 0.0 - /// The y-axis coordinate of the side of the rectangle which - /// has the smaller y-axis coordinate value - public var y: Double = 0.0 - /// The width of the rectangle. - public var width: Double = 0.0 - /// The height of the rectangle. - public var height: Double = 0.0 - /// For rounded rectangles, the x-axis radius of the ellipse used - /// to round off the corners of the rectangle. - public var rx: Double? - /// For rounded rectangles, the y-axis radius of the ellipse used - /// to round off the corners of the rectangle. - public var ry: Double? - - // MARK: CoreAttributes - - public var id: String? - - // MARK: PresentationAttributes - - public var fillColor: String? - public var fillOpacity: Double? - public var fillRule: Fill.Rule? - public var strokeColor: String? - public var strokeWidth: Double? - public var strokeOpacity: Double? - public var strokeLineCap: Stroke.LineCap? - public var strokeLineJoin: Stroke.LineJoin? - public var strokeMiterLimit: Double? - public var transform: String? - - // MARK: StylingAttributes - - public var style: String? - - enum CodingKeys: String, CodingKey { - case x - case y - case width - case height - case rx - case ry - case id - case fillColor = "fill" - case fillOpacity = "fill-opacity" - case fillRule = "fill-rule" - case strokeColor = "stroke" - case strokeWidth = "stroke-width" - case strokeOpacity = "stroke-opacity" - case strokeLineCap = "stroke-linecap" - case strokeLineJoin = "stroke-linejoin" - case strokeMiterLimit = "stroke-miterlimit" - case transform - case style - } - - public init() {} - - public init(x: Double, y: Double, width: Double, height: Double, rx: Double? = nil, ry: Double? = nil) { - self.x = x - self.y = y - self.width = width - self.height = height - self.rx = rx - self.ry = ry - } -} - -extension Rectangle: CustomStringConvertible { - public var description: String { - var desc = "" - } -} - -extension Rectangle: DirectionalCommandRepresentable { - public func commands(clockwise: Bool) throws -> [Path.Command] { - RectangleProcessor(rectangle: self).commands(clockwise: clockwise) - } -} - -extension Rectangle: DynamicNodeDecoding { - public static func nodeDecoding(for key: any CodingKey) -> XMLDecoder.NodeDecoding { - .attribute - } -} - -extension Rectangle: DynamicNodeEncoding { - public static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { - .attribute - } -} diff --git a/third-party/SwiftSVG/Sources/SVG+Swift2D.swift b/third-party/SwiftSVG/Sources/SVG+Swift2D.swift deleted file mode 100644 index abf62de434..0000000000 --- a/third-party/SwiftSVG/Sources/SVG+Swift2D.swift +++ /dev/null @@ -1,62 +0,0 @@ -import Foundation -import Swift2D - -public extension SVG { - /// Original size of the document image. - /// - /// Primarily uses the `viewBox` attribute, and will fallback to the 'pixelSize' - var originalSize: Size { - (viewBoxSize ?? pixelSize) ?? .zero - } - - /// Size of the design in a square 'viewBox'. - /// - /// All paths created by this framework are outputted in a 'square'. - var outputSize: Size { - let size = (pixelSize ?? viewBoxSize) ?? .zero - let maxDimension = max(size.width, size.height) - return Size(width: maxDimension, height: maxDimension) - } - - /// Size derived from the `viewBox` document attribute - var viewBoxSize: Size? { - guard let viewBox else { - return nil - } - - let components = viewBox.components(separatedBy: .whitespaces) - guard components.count == 4 else { - return nil - } - - guard let width = Double(components[2]) else { - return nil - } - - guard let height = Double(components[3]) else { - return nil - } - - return Size(width: width, height: height) - } - - /// Size derived from the 'width' & 'height' document attributes - var pixelSize: Size? { - guard let width, !width.isEmpty else { - return nil - } - - guard let height, !height.isEmpty else { - return nil - } - - let widthRawValue = width.replacingOccurrences(of: "px", with: "", options: .caseInsensitive, range: nil) - let heightRawValue = height.replacingOccurrences(of: "px", with: "", options: .caseInsensitive, range: nil) - - guard let w = Double(widthRawValue), let h = Double(heightRawValue) else { - return nil - } - - return Size(width: w, height: h) - } -} diff --git a/third-party/SwiftSVG/Sources/SVG.swift b/third-party/SwiftSVG/Sources/SVG.swift deleted file mode 100644 index cbf3117bbc..0000000000 --- a/third-party/SwiftSVG/Sources/SVG.swift +++ /dev/null @@ -1,160 +0,0 @@ -import Foundation -import XMLCoder - -/// SVG is a language for describing two-dimensional graphics in XML. -/// -/// The svg element is a container that defines a new coordinate system and viewport. It is used as the outermost -/// element of SVG documents, but it can also be used to embed a SVG fragment inside an SVG or HTML document. -/// -/// ## Documentation -/// [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg) -/// | [W3](https://www.w3.org/TR/SVG11/) -public struct SVG: Container { - - public var viewBox: String? - public var width: String? - public var height: String? - public var title: String? - public var desc: String? - - // Container - public var circles: [Circle]? - public var ellipses: [Ellipse]? - public var groups: [Group]? - public var lines: [Line]? - public var paths: [Path]? - public var polygons: [Polygon]? - public var polylines: [Polyline]? - public var rectangles: [Rectangle]? - public var texts: [Text]? - - /// A non-optional, non-spaced representation of the `title`. - public var name: String { - let name = title ?? "SVG Document" - let newTitle = name.components(separatedBy: .punctuationCharacters).joined(separator: "_") - return newTitle.replacingOccurrences(of: " ", with: "_") - } - - enum CodingKeys: String, CodingKey { - case width - case height - case viewBox - case title - case desc - case circles = "circle" - case ellipses = "ellipse" - case groups = "g" - case lines = "line" - case paths = "path" - case polylines = "polyline" - case polygons = "polygon" - case rectangles = "rect" - case texts = "text" - } - - public init() {} - - public init(width: Int, height: Int) { - self.width = "\(width)px" - self.height = "\(height)px" - viewBox = "0 0 \(width) \(height)" - } - - public static func make(from url: URL) throws -> SVG { - guard FileManager.default.fileExists(atPath: url.path) else { - throw CocoaError(.fileNoSuchFile) - } - - let data = try Data(contentsOf: url) - return try make(with: data) - } - - public static func make(with data: Data, decoder: XMLDecoder = XMLDecoder()) throws -> SVG { - try decoder.decode(SVG.self, from: data) - } - - /// A collection of all `Path`s in the document. - public func subpaths() throws -> [Path] { - var output: [Path] = [] - let _transformations: [Transformation] = [] - - if let circles { - try output.append(contentsOf: circles.compactMap { try $0.path(applying: _transformations) }) - } - - if let ellipses { - try output.append(contentsOf: ellipses.compactMap { try $0.path(applying: _transformations) }) - } - - if let rectangles { - try output.append(contentsOf: rectangles.compactMap { try $0.path(applying: _transformations) }) - } - - if let polygons { - try output.append(contentsOf: polygons.compactMap { try $0.path(applying: _transformations) }) - } - - if let polylines { - try output.append(contentsOf: polylines.compactMap { try $0.path(applying: _transformations) }) - } - - if let paths { - try output.append(contentsOf: paths.map { try $0.path(applying: _transformations) }) - } - - if let groups { - try groups.forEach { - try output.append(contentsOf: $0.subpaths(applying: _transformations)) - } - } - - return output - } - - /// A singular path that represents all of the `Command`s within the document. - public func coalescedPath() throws -> Path { - let paths = try subpaths() - let commands = try paths.flatMap { try $0.commands() } - return Path(commands: commands) - } -} - -extension SVG: CustomStringConvertible { - public var description: String { - var contents: String = "" - - if let title { - contents.append("\n\(title)") - } - - if let desc { - contents.append("\n\(desc)") - } - - contents.append(containerDescription) - - return "\(contents)\n" - } -} - -extension SVG: DynamicNodeDecoding { - public static func nodeDecoding(for key: any CodingKey) -> XMLDecoder.NodeDecoding { - switch key { - case CodingKeys.width, CodingKeys.height, CodingKeys.viewBox: - .attribute - default: - .element - } - } -} - -extension SVG: DynamicNodeEncoding { - public static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { - switch key { - case CodingKeys.width, CodingKeys.height, CodingKeys.viewBox: - .attribute - default: - .element - } - } -} diff --git a/third-party/SwiftSVG/Sources/Stroke.swift b/third-party/SwiftSVG/Sources/Stroke.swift deleted file mode 100644 index d68cba3dd4..0000000000 --- a/third-party/SwiftSVG/Sources/Stroke.swift +++ /dev/null @@ -1,64 +0,0 @@ -import Swift2D - -public struct Stroke { - - public var color: String? - public var width: Double? - public var opacity: Double? - public var lineCap: LineCap = .butt - public var lineJoin: LineJoin = .miter - public var miterLimit: Double? - - public init() {} - - /// Presentation attribute defining the shape to be used at the end of open subpaths when they are stroked. - /// - /// The default `LineCap` is `.butt` - public enum LineCap: String, Sendable, Codable, CaseIterable { - /// The stroke for each subpath does not extend beyond its two endpoints. - case butt - /// The end of each subpath the stroke will be extended by a half circle with a diameter equal to the stroke - /// width. - case round - /// The end of each subpath the stroke will be extended by a rectangle with a width equal to half the width of - /// the stroke and a height equal to the width of the stroke. - case square - } - - /// Presentation attribute defining the shape to be used at the corners of paths when they are stroked. - /// - /// The default `LineJoin` is `.miter` - public enum LineJoin: String, Sendable, Codable, CaseIterable { - /// An arcs corner is to be used to join path segments. - /// - /// The arcs shape is formed by extending the outer edges of the stroke at the join point with arcs that have - /// the same curvature as the outer edges at the join point. - case arcs - /// The bevel value indicates that a bevelled corner is to be used to join path segments. - case bevel - /// Indicates that a sharp corner is to be used to join path segments. - /// - /// The corner is formed by extending the outer edges of the stroke at the tangents of the path segments until - /// they intersect. - case miter - /// A sharp corner is to be used to join path segments. - /// - /// The corner is formed by extending the outer edges of the stroke at the tangents of the path segments until - /// they intersect. - case miterClip = "miter-clip" - /// The round value indicates that a round corner is to be used to join path segments. - case round - } -} - -extension Stroke.LineCap: CustomStringConvertible { - public var description: String { - rawValue - } -} - -extension Stroke.LineJoin: CustomStringConvertible { - public var description: String { - rawValue - } -} diff --git a/third-party/SwiftSVG/Sources/StylingAttributes.swift b/third-party/SwiftSVG/Sources/StylingAttributes.swift deleted file mode 100644 index 8c597a42f4..0000000000 --- a/third-party/SwiftSVG/Sources/StylingAttributes.swift +++ /dev/null @@ -1,17 +0,0 @@ -public protocol StylingAttributes { - var style: String? { get set } -} - -enum StylingAttributesKeys: String, CodingKey { - case style -} - -public extension StylingAttributes { - var stylingDescription: String { - if let style { - "\(StylingAttributesKeys.style.rawValue)=\"\(style)\"" - } else { - "" - } - } -} diff --git a/third-party/SwiftSVG/Sources/Text.swift b/third-party/SwiftSVG/Sources/Text.swift deleted file mode 100644 index d54f62fcf6..0000000000 --- a/third-party/SwiftSVG/Sources/Text.swift +++ /dev/null @@ -1,110 +0,0 @@ -import Foundation -import XMLCoder - -/// Graphics element consisting of text -/// -/// It's possible to apply a gradient, pattern, clipping path, mask, or filter to `Text`, like any other SVG graphics element. -/// -/// ## Documentation -/// [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/text) -/// | [W3](https://www.w3.org/TR/SVG11/text.html#TextElement) -public struct Text: Element { - - public var value: String = "" - public var x: Double? - public var y: Double? - public var dx: Double? - public var dy: Double? - - // MARK: CoreAttributes - - public var id: String? - - // MARK: PresentationAttributes - - public var fillColor: String? - public var fillOpacity: Double? - public var fillRule: Fill.Rule? - public var strokeColor: String? - public var strokeWidth: Double? - public var strokeOpacity: Double? - public var strokeLineCap: Stroke.LineCap? - public var strokeLineJoin: Stroke.LineJoin? - public var strokeMiterLimit: Double? - public var transform: String? - - // MARK: StylingAttributes - - public var style: String? - - enum CodingKeys: String, CodingKey { - case value = "" - case x - case y - case dx - case dy - case id - case fillColor = "fill" - case fillOpacity = "fill-opacity" - case fillRule = "fill-rule" - case strokeColor = "stroke" - case strokeWidth = "stroke-width" - case strokeOpacity = "stroke-opacity" - case strokeLineCap = "stroke-linecap" - case strokeLineJoin = "stroke-linejoin" - case strokeMiterLimit = "stroke-miterlimit" - case transform - case style - } - - public init() {} - - public init(value: String) { - self.value = value - } -} - -extension Text: CustomStringConvertible { - public var description: String { - var components: [String] = [] - - if let x, !x.isNaN, !x.isZero { - components.append(String(format: "x=\"%.5f\"", x)) - } - if let y, !y.isNaN, !y.isZero { - components.append(String(format: "y=\"%.5f\"", y)) - } - if let dx, !dx.isNaN, !dx.isZero { - components.append(String(format: "dx=\"%.5f\"", dx)) - } - if let dy, !dy.isNaN, !dy.isZero { - components.append(String(format: "dy=\"%.5f\"", dy)) - } - - components.append(attributeDescription) - - return "\(value)" - } -} - -extension Text: DynamicNodeDecoding { - public static func nodeDecoding(for key: any CodingKey) -> XMLDecoder.NodeDecoding { - switch key { - case CodingKeys.value: - .element - default: - .attribute - } - } -} - -extension Text: DynamicNodeEncoding { - public static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { - switch key { - case CodingKeys.value: - .element - default: - .attribute - } - } -} diff --git a/third-party/SwiftSVG/Sources/Transformation.swift b/third-party/SwiftSVG/Sources/Transformation.swift deleted file mode 100644 index 3fb086d55e..0000000000 --- a/third-party/SwiftSVG/Sources/Transformation.swift +++ /dev/null @@ -1,113 +0,0 @@ -import Foundation -import Swift2D - -/// A modification that should be applied to an element and its children. -/// -/// If a list of transforms is provided, then the net effect is as if each transform had been specified separately in -/// the order provided. -/// -/// For example, -/// ``` -/// -/// -/// -/// ``` -/// is functionally equivalent to: -/// ``` -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// ``` -/// -/// The ‘transform’ attribute is applied to an element before processing any other coordinate or length values supplied -/// for that element. -/// -/// ## Documentation -/// [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform) -/// | [W3](https://www.w3.org/TR/SVG11/coords.html#TransformAttribute) -public enum Transformation { - /// Moves an object by x & y. (Y is assumed to be '0' if not provided) - case translate(x: Double, y: Double) - /// Specifies a transformation in the form of a transformation matrix of six values. - case matrix(a: Double, b: Double, c: Double, d: Double, e: Double, f: Double) - - public enum Prefix: String, CaseIterable { - case translate - case matrix - } - - /// Initializes a new `Transformation` with a raw SVG transformation string. - public init?(_ string: String) { - guard let prefix = Prefix.allCases.first(where: { string.lowercased().hasPrefix($0.rawValue) }) else { - return nil - } - - switch prefix { - case .translate: - guard let start = string.firstIndex(of: "(") else { - return nil - } - - guard let stop = string.lastIndex(of: ")") else { - return nil - } - - var substring = String(string[start ... stop]) - substring = substring.replacingOccurrences(of: "(", with: "") - substring = substring.replacingOccurrences(of: ")", with: "") - - var components = substring.split(separator: " ", omittingEmptySubsequences: true).map { String($0) } - components = components.flatMap { $0.components(separatedBy: ",") } - - let values = components.compactMap { Double($0) }.map { Double($0) } - guard values.count > 0 else { - return nil - } - - if values.count > 1 { - self = .translate(x: values[0], y: values[1]) - } else { - self = .translate(x: values[0], y: 0.0) - } - case .matrix: - guard let start = string.firstIndex(of: "(") else { - return nil - } - - guard let stop = string.lastIndex(of: ")") else { - return nil - } - - var substring = String(string[start ... stop]) - substring = substring.replacingOccurrences(of: "(", with: "") - substring = substring.replacingOccurrences(of: ")", with: "") - - var components = substring.split(separator: " ", omittingEmptySubsequences: true).map { String($0) } - components = components.flatMap { $0.components(separatedBy: ",") } - - let values = components.compactMap { Double($0) }.map { Double($0) } - guard values.count > 5 else { - return nil - } - - self = .matrix(a: values[0], b: values[1], c: values[2], d: values[3], e: values[4], f: values[5]) - } - } -} - -extension Transformation: CustomStringConvertible { - public var description: String { - switch self { - case .translate(let x, let y): - "translate(\(x), \(y))" - case .matrix(let a, let b, let c, let d, let e, let f): - "matrix(\(a), \(b), \(c), \(d), \(e), \(f))" - } - } -} diff --git a/third-party/VectorPlus/BUILD b/third-party/VectorPlus/BUILD deleted file mode 100644 index c7f57a85a1..0000000000 --- a/third-party/VectorPlus/BUILD +++ /dev/null @@ -1,19 +0,0 @@ -load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") - -swift_library( - name = "VectorPlus", - module_name = "VectorPlus", - srcs = glob([ - "Sources/**/*.swift", - ]), - copts = [ - "-warnings-as-errors", - ], - deps = [ - "//third-party/SwiftColor", - "//third-party/SwiftSVG", - ], - visibility = [ - "//visibility:public", - ], -) diff --git a/third-party/VectorPlus/Sources/CoreGraphics/CGContext+Render.swift b/third-party/VectorPlus/Sources/CoreGraphics/CGContext+Render.swift deleted file mode 100644 index a6f3e94d73..0000000000 --- a/third-party/VectorPlus/Sources/CoreGraphics/CGContext+Render.swift +++ /dev/null @@ -1,72 +0,0 @@ -import Swift2D -import SwiftColor -import SwiftSVG -#if canImport(CoreGraphics) -import CoreGraphics - -public extension CGContext { - func render(path: Path, from: Rect, to: Rect) throws { - saveGState() - - let cgPath = CGMutablePath() - - let commands = (try? path.commands()) ?? [] - for (idx, command) in commands.enumerated() { - let previous: Point? = if idx > 0 { - commands[idx - 1].previousPoint - } else { - nil - } - - cgPath.addCommand(command, from: from, to: to, previousPoint: previous) - } - - if let fill = path.fill { - let _color = Pigment(fill.color ?? "black") - if _color.alpha != 0.0 { - let cgColor = CGColor.make(_color) - let color = cgColor.copy(alpha: CGFloat(fill.opacity ?? 1.0)) ?? cgColor - let rule = fill.rule.cgFillRule - - setFillColor(color) - addPath(cgPath) - fillPath(using: rule) - } - } - - if let stroke = path.stroke { - let _color = Pigment(stroke.color ?? "black") - if _color.alpha != 0.0 { - let cgColor = CGColor.make(_color) - let color = cgColor.copy(alpha: CGFloat(stroke.opacity ?? 1.0)) ?? cgColor - let width = stroke.width ?? 1.0 - let lineWidth = width * (to.size.width / from.size.width) - - setLineWidth(CGFloat(lineWidth)) - setStrokeColor(color) - setLineCap(stroke.lineCap.cgLineCap) - setLineJoin(stroke.lineJoin.cgLineJoin) - if let miterLimit = stroke.miterLimit, stroke.lineJoin == .miter { - setMiterLimit(CGFloat(miterLimit)) - } - addPath(cgPath) - strokePath() - } - } - - if path.fill == nil, path.stroke == nil { - let color = CGColor(srgbRed: 0.0, green: 0.0, blue: 0.0, alpha: 1.0) - setFillColor(color) - addPath(cgPath) - fillPath(using: path.fill?.rule.cgFillRule ?? .winding) - } - - restoreGState() - } - - func render(path: Path, in rect: Rect) throws { - try render(path: path, from: rect, to: rect) - } -} - -#endif diff --git a/third-party/VectorPlus/Sources/CoreGraphics/CGMutablePath+Instruction.swift b/third-party/VectorPlus/Sources/CoreGraphics/CGMutablePath+Instruction.swift deleted file mode 100644 index f810e6d883..0000000000 --- a/third-party/VectorPlus/Sources/CoreGraphics/CGMutablePath+Instruction.swift +++ /dev/null @@ -1,45 +0,0 @@ -import Swift2D -import SwiftSVG -#if canImport(CoreGraphics) -import CoreGraphics - -public extension CGMutablePath { - /// Adds a `Path.Command` to a _CoreGraphics path_, using the provided rectangles to correctly scale the parameters. - /// - /// - parameter command: The `Path.Command` to append - /// - parameter from: The `Rect` which originally had the instruction. This is typically the `Document.originalSize`. - /// - parameter to: The `Rect` defining the new size. - /// - parameter previousPoint: The last `Point`, used for Elliptical Arc calculations - func addCommand(_ command: Path.Command, from: Rect, to: Rect, previousPoint: Point? = nil) { - let translated = command.translate(from: from, to: to) - switch translated { - case .moveTo(let point): - move(to: CGPoint(point)) - case .lineTo(let point): - addLine(to: CGPoint(point)) - case .cubicBezierCurve(let cp1, let cp2, let point): - addCurve(to: CGPoint(point), control1: CGPoint(cp1), control2: CGPoint(cp2)) - case .quadraticBezierCurve(let cp, let point): - addQuadCurve(to: CGPoint(point), control: CGPoint(cp)) - case .ellipticalArcCurve(_, _, _, _, _, let point): - guard let previousPoint else { - addLine(to: CGPoint(point)) - return - } - - do { - let curves = try command.convertToCubicBezierCurves(with: previousPoint) - for curve in curves { - addCommand(curve, from: from, to: to) - } - } catch { - print(error) - addLine(to: CGPoint(point)) - } - case .closePath: - closeSubpath() - } - } -} - -#endif diff --git a/third-party/VectorPlus/Sources/CoreGraphics/Fill+CoreGraphics.swift b/third-party/VectorPlus/Sources/CoreGraphics/Fill+CoreGraphics.swift deleted file mode 100644 index e038784c2c..0000000000 --- a/third-party/VectorPlus/Sources/CoreGraphics/Fill+CoreGraphics.swift +++ /dev/null @@ -1,14 +0,0 @@ -import Foundation -import SwiftSVG -#if canImport(CoreGraphics) -import CoreGraphics - -public extension Fill.Rule { - var cgFillRule: CGPathFillRule { - switch self { - case .evenOdd: .evenOdd - case .nonZero: .winding - } - } -} -#endif diff --git a/third-party/VectorPlus/Sources/CoreGraphics/SVG+CGPath.swift b/third-party/VectorPlus/Sources/CoreGraphics/SVG+CGPath.swift deleted file mode 100644 index ef4cadbb66..0000000000 --- a/third-party/VectorPlus/Sources/CoreGraphics/SVG+CGPath.swift +++ /dev/null @@ -1,37 +0,0 @@ -import Swift2D -import SwiftSVG -#if canImport(CoreGraphics) -import CoreGraphics - -public extension SVG { - func path(size: Size) -> CGPath { - guard size.height > 0.0, size.width > 0.0 else { - return CGMutablePath() - } - - guard let paths = try? subpaths() else { - return CGMutablePath() - } - - let from = Rect(origin: .zero, size: originalSize) - let to = Rect(origin: .zero, size: size) - - let path = CGMutablePath() - - for p in paths { - let commands = (try? p.commands()) ?? [] - for (idx, command) in commands.enumerated() { - let previous: Point? = if idx > 0 { - commands[idx - 1].previousPoint - } else { - nil - } - - path.addCommand(command, from: from, to: to, previousPoint: previous) - } - } - - return path - } -} -#endif diff --git a/third-party/VectorPlus/Sources/CoreGraphics/Stroke+CoreGraphics.swift b/third-party/VectorPlus/Sources/CoreGraphics/Stroke+CoreGraphics.swift deleted file mode 100644 index 3744223181..0000000000 --- a/third-party/VectorPlus/Sources/CoreGraphics/Stroke+CoreGraphics.swift +++ /dev/null @@ -1,25 +0,0 @@ -import Foundation -import SwiftSVG -#if canImport(CoreGraphics) -import CoreGraphics - -public extension Stroke.LineCap { - var cgLineCap: CGLineCap { - switch self { - case .butt: .butt - case .round: .round - case .square: .square - } - } -} - -public extension Stroke.LineJoin { - var cgLineJoin: CGLineJoin { - switch self { - case .bevel: .bevel - case .arcs, .miter, .miterClip: .miter - case .round: .round - } - } -} -#endif diff --git a/third-party/VectorPlus/Sources/Fill+VectorPlus.swift b/third-party/VectorPlus/Sources/Fill+VectorPlus.swift deleted file mode 100644 index c7a66cf9fb..0000000000 --- a/third-party/VectorPlus/Sources/Fill+VectorPlus.swift +++ /dev/null @@ -1,29 +0,0 @@ -import SwiftColor -import SwiftSVG - -public extension Fill { - @available(*, deprecated, renamed: "pigment") - var swiftColor: Pigment? { pigment } - - var pigment: Pigment? { - guard let color, !color.isEmpty else { - return nil - } - - let _color = Pigment(color) - guard _color.alpha != 0.0 else { - return nil - } - - return _color - } -} - -public extension Fill.Rule { - var coreGraphicsDescription: String { - switch self { - case .evenOdd: ".evenOdd" - case .nonZero: ".winding" - } - } -} diff --git a/third-party/VectorPlus/Sources/Path+VectorPlus.swift b/third-party/VectorPlus/Sources/Path+VectorPlus.swift deleted file mode 100644 index 6511f6bbac..0000000000 --- a/third-party/VectorPlus/Sources/Path+VectorPlus.swift +++ /dev/null @@ -1,34 +0,0 @@ -import Swift2D -import SwiftSVG - -public extension Path { - func asCoreGraphicsDescription(variable: String = "path", originalSize: Size) throws -> String { - var outputs: [String] = [] - let commands = (try? commands()) ?? [] - for (idx, command) in commands.enumerated() { - let previous: Point? = if idx > 0 { - commands[idx - 1].previousPoint - } else { - nil - } - - let method = command.coreGraphicsDescription(originalSize: originalSize, previousPoint: previous) - let code = "\(variable)\(method)" - outputs.append(code) - } - return outputs.joined(separator: "\n ") - } -} - -public extension Path.Command { - var previousPoint: Point { - switch self { - case .moveTo(let point): point - case .lineTo(let point): point - case .cubicBezierCurve(_, _, let point): point - case .quadraticBezierCurve(_, let point): point - case .ellipticalArcCurve(_, _, _, _, _, let point): point - case .closePath: .zero - } - } -} diff --git a/third-party/VectorPlus/Sources/Path.Command+VectorPlus.swift b/third-party/VectorPlus/Sources/Path.Command+VectorPlus.swift deleted file mode 100644 index 226e57a643..0000000000 --- a/third-party/VectorPlus/Sources/Path.Command+VectorPlus.swift +++ /dev/null @@ -1,216 +0,0 @@ -import Foundation -import Swift2D -import SwiftSVG - -public extension Path.Command { - /// Uses the _Power of Math_ to translate a commands controls/points from one `Rect` to another `Rect`. - func translate(from: Rect, to: Rect) -> Path.Command { - switch self { - case .moveTo(let point): - let _point = VectorPoint(point: point, in: from).translate(to: to) - return .moveTo(point: _point) - case .lineTo(let point): - let _point = VectorPoint(point: point, in: from).translate(to: to) - return .lineTo(point: _point) - case .cubicBezierCurve(let cp1, let cp2, let point): - let _cp1 = VectorPoint(point: cp1, in: from).translate(to: to) - let _cp2 = VectorPoint(point: cp2, in: from).translate(to: to) - let _point = VectorPoint(point: point, in: from).translate(to: to) - return .cubicBezierCurve(cp1: _cp1, cp2: _cp2, point: _point) - case .quadraticBezierCurve(let cp, let point): - let _cp = VectorPoint(point: cp, in: from).translate(to: to) - let _point = VectorPoint(point: point, in: from).translate(to: to) - return .quadraticBezierCurve(cp: _cp, point: _point) - case .ellipticalArcCurve(let rx, let ry, let angle, let largeArc, let clockwise, let point): - let _rx = rx * (from.size.maxRadius / to.size.minRadius) - let _ry = ry * (from.size.maxRadius / to.size.minRadius) - let _point = VectorPoint(point: point, in: from).translate(to: to) - return .ellipticalArcCurve(rx: _rx, ry: _ry, angle: angle, largeArc: largeArc, clockwise: clockwise, point: _point) - case .closePath: - return self - } - } -} - -public extension Path.Command { - func coreGraphicsDescription(originalSize: Size, previousPoint: Point? = nil) -> String { - let rect = Rect(origin: .zero, size: originalSize) - - switch self { - case .moveTo(let point): - let _point = VectorPoint(point: point, in: rect) - return ".move(to: \(_point.coreGraphicsDescription))" - case .lineTo(let point): - let _point = VectorPoint(point: point, in: rect) - return ".addLine(to: \(_point.coreGraphicsDescription))" - case .cubicBezierCurve(let cp1, let cp2, let point): - let _cp1 = VectorPoint(point: cp1, in: rect) - let _cp2 = VectorPoint(point: cp2, in: rect) - let _point = VectorPoint(point: point, in: rect) - return ".addCurve(to: \(_point.coreGraphicsDescription), control1: \(_cp1.coreGraphicsDescription), control2: \(_cp2.coreGraphicsDescription))" - case .quadraticBezierCurve(let cp, let point): - let _cp = VectorPoint(point: cp, in: rect) - let _point = VectorPoint(point: point, in: rect) - return ".addQuadCurve(to: \(_point.coreGraphicsDescription), control: \(_cp.coreGraphicsDescription))" - case .ellipticalArcCurve(_, _, _, _, _, let point): - guard let previousPoint else { - return Path.Command.lineTo(point: point).coreGraphicsDescription(originalSize: originalSize) - } - - do { - let curves = try convertToCubicBezierCurves(with: previousPoint) - return curves.map { $0.coreGraphicsDescription(originalSize: originalSize) }.joined(separator: "\n") - } catch { - print(error) - return Path.Command.lineTo(point: point).coreGraphicsDescription(originalSize: originalSize) - } - case .closePath: - return ".closeSubpath()" - } - } -} - -extension Path.Command { - /// Converts an `.ellipticalArcCurve` into one or more `.cubicBezierCurve`s. - /// https://github.com/colinmeinke/svg-arc-to-cubic-bezier/blob/master/src/index.js - func convertToCubicBezierCurves(with previousPoint: Point) throws -> [Path.Command] { - guard case let .ellipticalArcCurve(rx, ry, angle, largeArg, clockwise, point) = self else { - throw Path.Command.Error.message("\(#function); Only .ellipticalArcCurve is allowed.") - } - - var curves: [Path.Command] = [] - - guard rx > 0.0, ry > 0.0 else { - throw Path.Command.Error.message("\(#function); rx/ry must be greater than 0.0 (zero).") - } - - let sinφ = sin(angle * (.pi * 2.0) / 360.0) - let cosφ = cos(angle * (.pi * 2.0) / 360.0) - - let pxp = cosφ * (previousPoint.x - point.x) / 2 + sinφ * (previousPoint.y - point.y) / 2.0 - let pyp = -sinφ * (previousPoint.x - point.x) / 2 + cosφ * (previousPoint.y - point.y) / 2.0 - - guard pxp != 0.0, pyp != 0.0 else { - throw Path.Command.Error.message("\(#function); math") - } - - var _rx = abs(rx) - var _ry = abs(ry) - - let λ = pow(pxp, 2.0) / pow(_rx, 2.0) + pow(pyp, 2.0) / pow(_ry, 2.0) - - if λ > 1.0 { - _rx *= sqrt(λ) - _ry *= sqrt(λ) - } - - let _arcCenter = arcCenter(previousPoint: previousPoint, point: point, rx: _rx, ry: _ry, largeArc: largeArg, clockwise: clockwise, sinφ: sinφ, cosφ: cosφ, pxp: pxp, pyp: pyp) - let center = _arcCenter.center - var angle1 = _arcCenter.angle1 - var angle2 = _arcCenter.angle2 - - var ratio = abs(angle2) / ((.pi * 2.0) / 4.0) - if abs(1.0 - ratio) < 0.0000001 { - ratio = 1.0 - } - - let segments = max(ceil(ratio), 1) - - angle2 /= segments - - var rawCurves: [(Point, Point, Point)] = [] - for _ in 0 ... Int(segments) { - rawCurves.append(approximateUnitArc(angle1: angle1, angle2: angle2)) - angle1 += angle2 - } - - for rawCurf in rawCurves { - let _cp1 = mapToEllipse(point: rawCurf.0, rx: _rx, ry: _ry, sinφ: sinφ, cosφ: cosφ, center: center) - let _cp2 = mapToEllipse(point: rawCurf.1, rx: _rx, ry: _ry, sinφ: sinφ, cosφ: cosφ, center: center) - let _point = mapToEllipse(point: rawCurf.2, rx: _rx, ry: _ry, sinφ: sinφ, cosφ: cosφ, center: center) - curves.append(.cubicBezierCurve(cp1: _cp1, cp2: _cp2, point: _point)) - } - - return curves - } -} - -private func arcCenter(previousPoint: Point, point: Point, rx: Double, ry: Double, largeArc: Bool, clockwise: Bool, sinφ: Double, cosφ: Double, pxp: Double, pyp: Double) -> - (center: Point, angle1: Double, angle2: Double) -{ - - let rxsq = pow(rx, 2.0) - let rysq = pow(ry, 2.0) - let pxpsq = pow(pxp, 2.0) - let pypsq = pow(pyp, 2.0) - - var radicant = (rxsq * rysq) - (rxsq * pypsq) - (rysq * pxpsq) - if radicant < 0.0 { - radicant = 0.0 - } - - radicant /= (rxsq * pypsq) + (rysq * pxpsq) - radicant = sqrt(radicant) * (largeArc == clockwise ? -1.0 : 1.0) - - let centerxp = radicant * rx / ry * pyp - let centeryp = radicant * -ry / rx * pxp - - let centerx = cosφ * centerxp - sinφ * centeryp + (previousPoint.x + point.x) / 2.0 - let centery = sinφ * centerxp + cosφ * centeryp + (previousPoint.x + point.x) / 2.0 - - let vx1 = (pxp - centerxp) / rx - let vy1 = (pyp - centeryp) / ry - let vx2 = (-pxp - centerxp) / rx - let vy2 = (-pyp - centeryp) / ry - - let angle1 = vectorAngle(u: Point(x: 1, y: 0), v: Point(x: vx1, y: vy1)) - var angle2 = vectorAngle(u: Point(x: vx1, y: vy1), v: Point(x: vx2, y: vy2)) - - if clockwise == false, angle2 > 0.0 { - angle2 -= (.pi * 2.0) - } else if clockwise == true, angle2 < 0.0 { - angle2 += (.pi * 2.0) - } - - return (Point(x: centerx, y: centery), angle1, angle2) -} - -private func vectorAngle(u: Point, v: Point) -> Double { - let sign: Double = ((u.x * v.y - u.y * v.x) < 0.0) ? -1.0 : 1.0 - var dot = u.x * v.x + u.y * v.y - if dot > 1.0 { - dot = 1.0 - } else if dot < -1.0 { - dot = -1.0 - } - - return sign * acos(dot) -} - -private func approximateUnitArc(angle1: Double, angle2: Double) -> (Point, Point, Point) { - // If 90 degree circular arc, use a constant - // as derived from http://spencermortensen.com/articles/bezier-circle - let a: Double = switch angle2 { - case 1.5707963267948966: - 0.551915024494 - case -1.5707963267948966: - -0.551915024494 - default: - 4.0 / 3.0 * tan(angle2 / 4.0) - } - - let x1 = cos(angle1) - let y1 = sin(angle1) - let x2 = cos(angle1 + angle2) - let y2 = sin(angle1 + angle2) - - return (Point(x: x1 - y1 * a, y: y1 + x1 * a), Point(x: x2 + y2 * a, y: y2 - x2 * 1), Point(x: x2, y: y2)) -} - -private func mapToEllipse(point: Point, rx: Double, ry: Double, sinφ: Double, cosφ: Double, center: Point) -> Point { - let x = point.x * rx - let y = point.y * ry - let xp = cosφ * x - sinφ * y - let yp = sinφ * x + cosφ * y - return Point(x: xp + center.x, y: yp + center.y) -} diff --git a/third-party/VectorPlus/Sources/Pigment+VectorPlus.swift b/third-party/VectorPlus/Sources/Pigment+VectorPlus.swift deleted file mode 100644 index ea9b3e7e04..0000000000 --- a/third-party/VectorPlus/Sources/Pigment+VectorPlus.swift +++ /dev/null @@ -1,7 +0,0 @@ -import SwiftColor - -public extension Pigment { - var coreGraphicsDescription: String { - "CGColor(srgbRed: \(red), green: \(green), blue: \(blue), alpha: \(alpha))" - } -} diff --git a/third-party/VectorPlus/Sources/Point+VectorPlus.swift b/third-party/VectorPlus/Sources/Point+VectorPlus.swift deleted file mode 100644 index 716a66f023..0000000000 --- a/third-party/VectorPlus/Sources/Point+VectorPlus.swift +++ /dev/null @@ -1,7 +0,0 @@ -import Swift2D - -public extension Point { - var coreGraphicsDescription: String { - "CGPoint(x: \(x), y: \(y))" - } -} diff --git a/third-party/VectorPlus/Sources/Rect+VectorPlus.swift b/third-party/VectorPlus/Sources/Rect+VectorPlus.swift deleted file mode 100644 index d66f66f6d6..0000000000 --- a/third-party/VectorPlus/Sources/Rect+VectorPlus.swift +++ /dev/null @@ -1,7 +0,0 @@ -import Swift2D - -public extension Rect { - var coreGraphicsDescription: String { - "CGRect(origin: \(origin.coreGraphicsDescription), size: \(size.coreGraphicsDescription))" - } -} diff --git a/third-party/VectorPlus/Sources/SVG+AppleSymbols.swift b/third-party/VectorPlus/Sources/SVG+AppleSymbols.swift deleted file mode 100644 index 8eb5759507..0000000000 --- a/third-party/VectorPlus/Sources/SVG+AppleSymbols.swift +++ /dev/null @@ -1,324 +0,0 @@ -import Foundation -import Swift2D -import SwiftSVG -import XMLCoder - -public extension SVG { - - static func encodeDocument(_ document: SVG, encoder: XMLEncoder = XMLEncoder()) throws -> Data { - let rootAttributes: [String: String] = [ - "version": "1.1", - "xmlns": "http://www.w3.org/2000/svg", - "xmlns:xlink": "http://www.w3.org/1999/xlink", - ] - let header = XMLHeader(version: 1.0, encoding: "UTF-8", standalone: nil) - return try encoder.encode(document, withRootKey: "svg", rootAttributes: rootAttributes, header: header) - } - - static func appleSymbols(path: Path, in rect: Rect) throws -> SVG { - var document = SVG(width: 3300, height: 2200) - document.groups = try [.appleSymbolsNotes, .appleSymbolsGuides, .appleSymbols(path: path, in: rect)] - return document - } -} - -public extension Group { - static var appleSymbolsNotes: Group { - var group = Group() - - group.id = "Notes" - group.rectangles = [] - group.lines = [] - group.texts = [] - group.groups = [] - - var artboard = Rectangle(x: 0, y: 0, width: 3300, height: 2200) - artboard.id = "artboard" - artboard.style = "fill:white;opacity:1" - group.rectangles?.append(artboard) - - var topLine = Line(x1: 263, y1: 292, x2: 3036, y2: 292) - topLine.style = "fill:none;stroke:black;opacity:1;stroke-width:0.5;" - group.lines?.append(topLine) - - var bottomLine = Line(x1: 263, y1: 1903, x2: 3036, y2: 1903) - bottomLine.style = "fill:none;stroke:black;opacity:1;stroke-width:0.5;" - group.lines?.append(bottomLine) - - var text = Text() - text.style = "stroke:none;fill:black;font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",Helvetica,sans-serif;font-weight:bold;" - text.transform = "matrix(1 0 0 1 263 322)" - text.value = "Weight/Scale Variations" - group.texts?.append(text) - - text.style = "stroke:none;fill:black;font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",Helvetica,sans-serif;text-anchor:middle" - text.transform = "matrix(1 0 0 1 559.711 322)" - text.value = "Ultralight" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 856.422 322)" - text.value = "Thin" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 1153.13 322)" - text.value = "Light" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 1449.84 322)" - text.value = "Regular" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 1746.56 322)" - text.value = "Medium" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 2043.27 322)" - text.value = "Semibold" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 2339.98 322)" - text.value = "Bold" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 2636.69 322)" - text.value = "Heavy" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 2933.4 322)" - text.value = "Black" - group.texts?.append(text) - - var path = Path(data: "M 9.24805 0.830078 C 13.5547 0.830078 17.1387 -2.74414 17.1387 -7.05078 C 17.1387 -11.3574 13.5449 -14.9316 9.23828 -14.9316 C 4.94141 -14.9316 1.36719 -11.3574 1.36719 -7.05078 C 1.36719 -2.74414 4.95117 0.830078 9.24805 0.830078 Z M 9.24805 -0.654297 C 5.70312 -0.654297 2.87109 -3.49609 2.87109 -7.05078 C 2.87109 -10.6055 5.69336 -13.4473 9.23828 -13.4473 C 12.793 -13.4473 15.6348 -10.6055 15.6445 -7.05078 C 15.6543 -3.49609 12.8027 -0.654297 9.24805 -0.654297 Z M 9.22852 -3.42773 C 9.69727 -3.42773 9.9707 -3.74023 9.9707 -4.25781 L 9.9707 -6.31836 L 12.1973 -6.31836 C 12.6953 -6.31836 13.0371 -6.57227 13.0371 -7.04102 C 13.0371 -7.51953 12.7148 -7.7832 12.1973 -7.7832 L 9.9707 -7.7832 L 9.9707 -10.0098 C 9.9707 -10.5273 9.69727 -10.8496 9.22852 -10.8496 C 8.75977 -10.8496 8.50586 -10.5078 8.50586 -10.0098 L 8.50586 -7.7832 L 6.29883 -7.7832 C 5.78125 -7.7832 5.44922 -7.51953 5.44922 -7.04102 C 5.44922 -6.57227 5.80078 -6.31836 6.29883 -6.31836 L 8.50586 -6.31836 L 8.50586 -4.25781 C 8.50586 -3.75977 8.75977 -3.42773 9.22852 -3.42773 Z") - var subGroup = Group("", path: path, transform: "matrix(1 0 0 1 263 1933)") - group.groups?.append(subGroup) - - path.data = "M 11.709 2.91016 C 17.1582 2.91016 21.6699 -1.60156 21.6699 -7.05078 C 21.6699 -12.4902 17.1484 -17.0117 11.6992 -17.0117 C 6.25977 -17.0117 1.74805 -12.4902 1.74805 -7.05078 C 1.74805 -1.60156 6.26953 2.91016 11.709 2.91016 Z M 11.709 1.25 C 7.09961 1.25 3.41797 -2.44141 3.41797 -7.05078 C 3.41797 -11.6504 7.08984 -15.3516 11.6992 -15.3516 C 16.3086 -15.3516 20 -11.6504 20.0098 -7.05078 C 20.0195 -2.44141 16.3184 1.25 11.709 1.25 Z M 11.6895 -2.41211 C 12.207 -2.41211 12.5195 -2.77344 12.5195 -3.33984 L 12.5195 -6.23047 L 15.5762 -6.23047 C 16.123 -6.23047 16.5039 -6.51367 16.5039 -7.03125 C 16.5039 -7.55859 16.1426 -7.86133 15.5762 -7.86133 L 12.5195 -7.86133 L 12.5195 -10.9277 C 12.5195 -11.5039 12.207 -11.8555 11.6895 -11.8555 C 11.1719 -11.8555 10.8789 -11.4844 10.8789 -10.9277 L 10.8789 -7.86133 L 7.83203 -7.86133 C 7.26562 -7.86133 6.89453 -7.55859 6.89453 -7.03125 C 6.89453 -6.51367 7.28516 -6.23047 7.83203 -6.23047 L 10.8789 -6.23047 L 10.8789 -3.33984 C 10.8789 -2.79297 11.1719 -2.41211 11.6895 -2.41211 Z" - subGroup.paths = [path] - subGroup.transform = "matrix(1 0 0 1 281.506 1933)" - group.groups?.append(subGroup) - - path.data = "M 14.9707 5.67383 C 21.9336 5.67383 27.6953 -0.078125 27.6953 -7.04102 C 27.6953 -14.0039 21.9238 -19.7559 14.9609 -19.7559 C 8.00781 -19.7559 2.25586 -14.0039 2.25586 -7.04102 C 2.25586 -0.078125 8.01758 5.67383 14.9707 5.67383 Z M 14.9707 3.85742 C 8.93555 3.85742 4.08203 -1.00586 4.08203 -7.04102 C 4.08203 -13.0762 8.92578 -17.9395 14.9609 -17.9395 C 21.0059 -17.9395 25.8594 -13.0762 25.8691 -7.04102 C 25.8789 -1.00586 21.0156 3.85742 14.9707 3.85742 Z M 14.9512 -1.06445 C 15.5176 -1.06445 15.8691 -1.45508 15.8691 -2.06055 L 15.8691 -6.13281 L 20.1074 -6.13281 C 20.6934 -6.13281 21.1133 -6.46484 21.1133 -7.02148 C 21.1133 -7.59766 20.7227 -7.93945 20.1074 -7.93945 L 15.8691 -7.93945 L 15.8691 -12.1875 C 15.8691 -12.8027 15.5176 -13.1934 14.9512 -13.1934 C 14.3848 -13.1934 14.0625 -12.7832 14.0625 -12.1875 L 14.0625 -7.93945 L 9.83398 -7.93945 C 9.21875 -7.93945 8.80859 -7.59766 8.80859 -7.02148 C 8.80859 -6.46484 9.23828 -6.13281 9.83398 -6.13281 L 14.0625 -6.13281 L 14.0625 -2.06055 C 14.0625 -1.47461 14.3848 -1.06445 14.9512 -1.06445 Z" - subGroup.paths = [path] - subGroup.transform = "matrix(1 0 0 1 304.924 1933)" - group.groups?.append(subGroup) - - text.style = "stroke:none;fill:black;font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",Helvetica,sans-serif;font-weight:bold;" - text.transform = "matrix(1 0 0 1 263 1953)" - text.value = "Design Variations" - group.texts?.append(text) - - text.style = "none;fill:black;font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",Helvetica,sans-serif;" - text.transform = "matrix(1 0 0 1 263 1971)" - text.value = "Symbols are supported in up to nine weights and three scales." - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 263 1989)" - text.value = "For optimal layout with text and other symbols, vertically align" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 263 2007)" - text.value = "symbols with the adjacent text." - group.texts?.append(text) - - var rect = Rectangle(x: 776, y: 1919, width: 3, height: 14) - rect.style = "fill:#00AEEF;stroke:none;opacity:0.4;" - group.rectangles?.append(rect) - - path.data = "M 10.5273 0 L 12.373 0 L 7.17773 -14.0918 L 5.43945 -14.0918 L 0.244141 0 L 2.08984 0 L 3.50586 -4.0332 L 9.11133 -4.0332 Z M 6.2793 -11.9531 L 6.33789 -11.9531 L 8.59375 -5.52734 L 4.02344 -5.52734 Z" - subGroup.paths = [path] - subGroup.transform = "matrix(1 0 0 1 779 1933)" - group.groups?.append(subGroup) - - rect.x = 791.617 - group.rectangles?.append(rect) - - text.style = "stroke:none;fill:black;font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",Helvetica,sans-serif;font-weight:bold;" - text.transform = "matrix(1 0 0 1 776 1953)" - text.value = "Margins" - group.texts?.append(text) - - text.style = "stroke:none;fill:black;font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",Helvetica,sans-serif;" - text.transform = "matrix(1 0 0 1 776 1971)" - text.value = "Leading and trailing margins on the left and right side of each symbol" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 776 1989)" - text.value = "can be adjusted by modifying the width of the blue rectangles." - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 776 2007)" - text.value = "Modifications are automatically applied proportionally to all" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 776 2025)" - text.value = "scales and weights." - group.texts?.append(text) - - path.data = "M 2.83203 3.11523 L 4.375 4.6582 C 5.22461 5.48828 6.19141 5.41992 7.06055 4.46289 L 17.2754 -6.66016 C 17.7051 -6.36719 18.0957 -6.37695 18.5645 -6.47461 L 19.6094 -6.68945 L 20.3027 -5.99609 L 20.2539 -5.47852 C 20.1855 -4.95117 20.3516 -4.53125 20.8496 -4.0332 L 21.6602 -3.22266 C 22.168 -2.71484 22.8223 -2.68555 23.3008 -3.16406 L 26.5527 -6.41602 C 27.0312 -6.89453 27.0117 -7.54883 26.5039 -8.05664 L 25.6836 -8.87695 C 25.1855 -9.375 24.7754 -9.55078 24.2383 -9.47266 L 23.7109 -9.41406 L 23.0566 -10.0781 L 23.3398 -11.2207 C 23.4863 -11.7871 23.3398 -12.2559 22.7148 -12.8613 L 20.3027 -15.2539 C 16.7578 -18.7793 12.2266 -18.6719 9.11133 -15.5371 C 8.69141 -15.1074 8.64258 -14.5215 8.91602 -14.0918 C 9.15039 -13.7207 9.62891 -13.4961 10.2734 -13.6621 C 11.7871 -14.043 13.3008 -13.9258 14.7852 -12.9199 L 14.1602 -11.3379 C 13.9258 -10.752 13.9453 -10.2734 14.1797 -9.83398 L 3.01758 0.439453 C 2.08008 1.30859 1.97266 2.25586 2.83203 3.11523 Z M 10.6738 -15.1465 C 13.3398 -17.1387 16.6504 -16.8262 19.0527 -14.4141 L 21.6797 -11.8066 C 21.9141 -11.5723 21.9434 -11.3867 21.8848 -11.0938 L 21.5039 -9.53125 L 23.0762 -7.95898 L 24.043 -8.04688 C 24.3262 -8.07617 24.4141 -8.05664 24.6387 -7.83203 L 25.2637 -7.20703 L 22.5098 -4.46289 L 21.8848 -5.07812 C 21.6602 -5.30273 21.6406 -5.40039 21.6699 -5.68359 L 21.7578 -6.64062 L 20.1953 -8.20312 L 18.5742 -7.89062 C 18.291 -7.83203 18.1445 -7.83203 17.9102 -8.07617 L 15.7324 -10.2539 C 15.5078 -10.4883 15.4785 -10.625 15.6055 -10.9473 L 16.5527 -13.2227 C 14.9512 -14.7559 12.8418 -15.6055 10.8008 -14.9512 C 10.7129 -14.9219 10.6445 -14.9414 10.6152 -14.9805 C 10.5859 -15.0293 10.5859 -15.0781 10.6738 -15.1465 Z M 4.10156 2.41211 C 3.61328 1.91406 3.78906 1.61133 4.12109 1.30859 L 15.0781 -8.80859 L 16.3086 -7.57812 L 6.15234 3.34961 C 5.84961 3.68164 5.46875 3.7793 5.06836 3.37891 Z" - subGroup.paths = [path] - subGroup.transform = "matrix(1 0 0 1 1289 1933)" - group.groups?.append(subGroup) - - text.style = "stroke:none;fill:black;font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",Helvetica,sans-serif;font-weight:bold;" - text.transform = "matrix(1 0 0 1 1289 1953)" - text.value = "Exporting" - group.texts?.append(text) - - text.style = "stroke:none;fill:black;font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",Helvetica,sans-serif;" - text.transform = "matrix(1 0 0 1 1289 1971)" - text.value = "Symbols should be outlined when exporting to ensure the" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 1289 1989)" - text.value = "design is preserved when submitting to Xcode." - group.texts?.append(text) - - text.id = "template-version" - text.style = "stroke:none;fill:black;font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",Helvetica,sans-serif;text-anchor:end;" - text.transform = "matrix(1 0 0 1 3036 1933)" - text.value = "Template v.2.0" - group.texts?.append(text) - - text.id = nil - text.transform = "matrix(1 0 0 1 3036 1969)" - text.value = "Typeset at 100 points" - group.texts?.append(text) - - text.style = "stroke:none;fill:black;font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",Helvetica,sans-serif;" - text.transform = "matrix(1 0 0 1 263 726)" - text.value = "Small" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 263 1156)" - text.value = "Medium" - group.texts?.append(text) - - text.transform = "matrix(1 0 0 1 263 1586)" - text.value = "Large" - group.texts?.append(text) - - return group - } - - static var appleSymbolsGuides: Group { - var group = Group() - - group.id = "Guides" - group.groups = [] - group.lines = [] - - var hRef = Group() - hRef.id = "H-reference" - hRef.style = "fill:#27AAE1;stroke:none;" - hRef.transform = "matrix(1 0 0 1 339 696)" - hRef.paths = [Path(data: "M 54.9316 0 L 57.666 0 L 30.5664 -70.459 L 28.0762 -70.459 L 0.976562 0 L 3.66211 0 L 12.9395 -24.4629 L 45.7031 -24.4629 Z M 29.1992 -67.0898 L 29.4434 -67.0898 L 44.8242 -26.709 L 13.8184 -26.709 Z")] - group.groups?.append(hRef) - - var baseline = Line(x1: 263, y1: 696, x2: 3036, y2: 696) - baseline.id = "Baseline-S" - baseline.style = "fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.577;" - group.lines?.append(baseline) - - var capline = Line(x1: 263, y1: 625.541, x2: 3036, y2: 625.541) - capline.id = "Capline-S" - capline.style = "fill:none;stroke:#27AAE1;opacity:1;stroke-width:0.577;" - group.lines?.append(capline) - - hRef.transform = "matrix(1 0 0 1 339 1126)" - hRef.paths = [Path(data: "M 54.9316 0 L 57.666 0 L 30.5664 -70.459 L 28.0762 -70.459 L 0.976562 0 L 3.66211 0 L 12.9395 -24.4629 L 45.7031 -24.4629 Z M 29.1992 -67.0898 L 29.4434 -67.0898 L 44.8242 -26.709 L 13.8184 -26.709 Z")] - group.groups?.append(hRef) - - baseline.id = "Baseline-M" - baseline.y1 = 1126 - baseline.y2 = 1126 - group.lines?.append(baseline) - - capline.id = "Capline-M" - capline.y1 = 1055.54 - capline.y2 = 1055.54 - group.lines?.append(capline) - - hRef.transform = "matrix(1 0 0 1 339 1556)" - hRef.paths = [Path(data: "M 54.9316 0 L 57.666 0 L 30.5664 -70.459 L 28.0762 -70.459 L 0.976562 0 L 3.66211 0 L 12.9395 -24.4629 L 45.7031 -24.4629 Z M 29.1992 -67.0898 L 29.4434 -67.0898 L 44.8242 -26.709 L 13.8184 -26.709 Z")] - group.groups?.append(hRef) - - baseline.id = "Baseline-L" - baseline.y1 = 1556 - baseline.y2 = 1556 - group.lines?.append(baseline) - - capline.id = "Capline-L" - capline.y1 = 1485.54 - capline.y2 = 1485.54 - group.lines?.append(capline) - - var margin = Line(x1: 1399.72, y1: 1030.79, x2: 1399.72, y2: 1150.12) - margin.id = "left-margin" - margin.style = "fill:none;stroke:#00AEEF;stroke-width:0.5;opacity:1.0;" - group.lines?.append(margin) - - margin = Line(x1: 1499.97, y1: 1030.79, x2: 1499.97, y2: 1150.12) - margin.id = "right-margin" - margin.style = "fill:none;stroke:#00AEEF;stroke-width:0.5;opacity:1.0;" - group.lines?.append(margin) - - return group - } - - static func appleSymbols(path: Path, in rect: Rect) throws -> Group { - var group = Group() - - group.id = "Symbols" - - let translations: [(name: String, size: Float, center: Point)] = [ - ("Ultralight-S", 0.75, .init(x: 559.0, y: 661.0)), - ("Thin-S", 0.76, .init(x: 857.0, y: 661.0)), - ("Light-S", 0.78, .init(x: 1153.0, y: 661.0)), - ("Regular-S", 0.79, .init(x: 1449.5, y: 661.0)), - ("Medium-S", 0.80, .init(x: 1747.0, y: 661.0)), - ("Semibold-S", 0.81, .init(x: 2043.0, y: 661.0)), - ("Bold-S", 0.82, .init(x: 2340.0, y: 661.0)), - ("Heavy-S", 0.85, .init(x: 2636.5, y: 661.0)), - ("Black-S", 0.86, .init(x: 2933.0, y: 661.0)), - ("Ultralight-M", 0.95, .init(x: 559.0, y: 1091.0)), - ("Thin-M", 0.96, .init(x: 857.0, y: 1091.0)), - ("Light-M", 0.98, .init(x: 1153.0, y: 1091.0)), - ("Regular-M", 1.00, .init(x: 1449.5, y: 1091.0)), - ("Medium-M", 1.02, .init(x: 1747.0, y: 1091.0)), - ("Semibold-M", 1.03, .init(x: 2043.0, y: 1091.0)), - ("Bold-M", 1.05, .init(x: 2340.0, y: 1091.0)), - ("Heavy-M", 1.07, .init(x: 2636.5, y: 1091.0)), - ("Black-M", 1.10, .init(x: 2933.0, y: 1091.0)), - ("Ultralight-L", 1.22, .init(x: 559.0, y: 1521.0)), - ("Thin-L", 1.24, .init(x: 857.0, y: 1521.0)), - ("Light-L", 1.26, .init(x: 1153.0, y: 1521.0)), - ("Regular-L", 1.28, .init(x: 1449.5, y: 1521.0)), - ("Medium-L", 1.30, .init(x: 1747.0, y: 1521.0)), - ("Semibold-L", 1.31, .init(x: 2043.0, y: 1521.0)), - ("Bold-L", 1.33, .init(x: 2340.0, y: 1521.0)), - ("Heavy-L", 1.36, .init(x: 2636.5, y: 1521.0)), - ("Black-L", 1.39, .init(x: 2933.0, y: 1521.0)), - ] - - group.groups = try translations.map { symbol -> Group in - let size = Size(width: 100.0 * symbol.size, height: 100.0 * symbol.size) - let to = Rect(origin: .zero, size: size) - let commands = try path.commands().map { $0.translate(from: rect, to: to) } - let p = Path(commands: commands) - let matrixOrigin = Point(x: symbol.center.x - size.width / 2.0, y: symbol.center.y - size.height / 2.0) - let matrix: Transformation = .matrix(a: 1, b: 0, c: 0, d: 1, e: matrixOrigin.x, f: matrixOrigin.y) - return Group(symbol.name, path: p, transform: matrix.description) - } - - return group - } -} - -private extension Group { - init(_ id: String, path: Path, transform: String) { - self.init() - self.id = id - self.transform = transform - paths = [path] - } -} diff --git a/third-party/VectorPlus/Sources/SVG+Template.swift b/third-party/VectorPlus/Sources/SVG+Template.swift deleted file mode 100644 index 6dbd962d84..0000000000 --- a/third-party/VectorPlus/Sources/SVG+Template.swift +++ /dev/null @@ -1,56 +0,0 @@ -import Foundation -import Swift2D -import SwiftSVG - -public extension SVG { - func asImageViewSubclass() throws -> String { - let instructions = try asCoreGraphicsDescription() - let renders = try asCGContextDescription() - - return imageViewSubclassTemplate - .replacingOccurrences(of: "{{name}}", with: name) - .replacingOccurrences(of: "{{width}}", with: String(format: "%.1f", originalSize.width)) - .replacingOccurrences(of: "{{height}}", with: String(format: "%.1f", originalSize.height)) - .replacingOccurrences(of: "{{instructions}}", with: instructions) - .replacingOccurrences(of: "{{render}}", with: renders) - } -} - -private extension SVG { - func asCoreGraphicsDescription(variable: String = "path") throws -> String { - try subpaths().map { try $0.asCoreGraphicsDescription(variable: variable, originalSize: originalSize) }.joined(separator: "\n ") - } - - func asCGContextDescription() throws -> String { - var outputs: [String] = [] - - let paths = try subpaths() - try paths.forEach { path in - let instructions = try path.asCoreGraphicsDescription(variable: "path", originalSize: originalSize) - let fillColor = path.fill?.pigment?.coreGraphicsDescription ?? "nil" - let fillOpacity = (path.fillOpacity != nil) ? "\(path.fillOpacity!)" : "nil" - let fillRule = (path.fillRule ?? .nonZero).coreGraphicsDescription - let strokeColor = path.stroke?.pigment?.coreGraphicsDescription ?? "nil" - let strokeOpacity = (path.strokeOpacity != nil) ? "\(path.strokeOpacity!)" : "nil" - let strokeWidth = (path.strokeWidth != nil) ? "\(path.strokeWidth!) * (size.width / width)" : "nil" - let strokeLineCap = (path.strokeLineCap != nil) ? "\(path.strokeLineCap!.coreGraphicsDescription)" : "nil" - let strokeLineJoin = (path.strokeLineJoin != nil) ? "\(path.strokeLineJoin!.coreGraphicsDescription)" : "nil" - let strokeMiterLimit = (path.strokeMiterLimit != nil) ? "\(path.strokeMiterLimit!)" : "nil" - - outputs.append(contextTemplate - .replacingOccurrences(of: "{{instructions}}", with: instructions) - .replacingOccurrences(of: "{{fillColor}}", with: fillColor) - .replacingOccurrences(of: "{{fillOpacity}}", with: fillOpacity) - .replacingOccurrences(of: "{{fillRule}}", with: fillRule) - .replacingOccurrences(of: "{{strokeColor}}", with: strokeColor) - .replacingOccurrences(of: "{{strokeOpacity}}", with: strokeOpacity) - .replacingOccurrences(of: "{{strokeWidth}}", with: strokeWidth) - .replacingOccurrences(of: "{{strokeLineCap}}", with: strokeLineCap) - .replacingOccurrences(of: "{{strokeLineJoin}}", with: strokeLineJoin) - .replacingOccurrences(of: "{{strokeMiterLimit}}", with: strokeMiterLimit) - ) - } - - return outputs.joined(separator: "\n ") - } -} diff --git a/third-party/VectorPlus/Sources/Size+VectorPlus.swift b/third-party/VectorPlus/Sources/Size+VectorPlus.swift deleted file mode 100644 index 3ec4a7bbd4..0000000000 --- a/third-party/VectorPlus/Sources/Size+VectorPlus.swift +++ /dev/null @@ -1,7 +0,0 @@ -import Swift2D - -public extension Size { - var coreGraphicsDescription: String { - "CGSize(width: \(width), height: \(height))" - } -} diff --git a/third-party/VectorPlus/Sources/Stroke+VectorPlus.swift b/third-party/VectorPlus/Sources/Stroke+VectorPlus.swift deleted file mode 100644 index 0d933d2aca..0000000000 --- a/third-party/VectorPlus/Sources/Stroke+VectorPlus.swift +++ /dev/null @@ -1,40 +0,0 @@ -import SwiftColor -import SwiftSVG - -public extension Stroke { - @available(*, deprecated, renamed: "pigment") - var swiftColor: Pigment? { pigment } - - var pigment: Pigment? { - guard let color, !color.isEmpty else { - return nil - } - - let _color = Pigment(color) - guard _color.alpha != 0.0 else { - return nil - } - - return _color - } -} - -public extension Stroke.LineCap { - var coreGraphicsDescription: String { - switch self { - case .butt: ".butt" - case .round: ".round" - case .square: ".square" - } - } -} - -public extension Stroke.LineJoin { - var coreGraphicsDescription: String { - switch self { - case .bevel: ".bevel" - case .arcs, .miter, .miterClip: ".miter" - case .round: ".round" - } - } -} diff --git a/third-party/VectorPlus/Sources/Template+UIImageView.swift b/third-party/VectorPlus/Sources/Template+UIImageView.swift deleted file mode 100644 index a6b03c8f47..0000000000 --- a/third-party/VectorPlus/Sources/Template+UIImageView.swift +++ /dev/null @@ -1,177 +0,0 @@ -let imageViewSubclassTemplate: String = """ -#if canImport(UIKit) -import UIKit - -@IBDesignable -public class {{name}}: UIImageView { - - public static let width: CGFloat = {{width}} - public static let height: CGFloat = {{height}} - public let width: CGFloat = {{width}} - public let height: CGFloat = {{height}} - - public var widthToHeightAspectRatio: CGFloat { - guard width != .nan, width > 0.0 else { - return 0.0 - } - - guard height != .nan, height > 0.0 else { - return 0.0 - } - - return width / height - } - - public var heightToWidthAspectRatio: CGFloat { - guard height != .nan, height > 0.0 else { - return 0.0 - } - - guard width != .nan, width > 0.0 else { - return 0.0 - } - - return height / width - } - - public override init(frame: CGRect) { - super.init(frame: frame) - updateSubviews() - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - updateSubviews() - } - - public override var intrinsicContentSize: CGSize { - return CGSize(width: width, height: height) - } - - public override var bounds: CGRect { - didSet { - updateSubviews() - } - } - - public override func prepareForInterfaceBuilder() { - super.prepareForInterfaceBuilder() - updateSubviews() - } - - public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - updateSubviews() - } - - public func updateSubviews() { - image = Self.image(size: bounds.size) - } - - public static func path(size: CGSize) -> CGPath { - guard size.height > 0.0 && size.width > 0.0 else { - return CGMutablePath() - } - - let radius = max(size.width / 2.0, size.height / 2.0) - let center = CGPoint(x: size.width / 2.0, y: size.height / 2.0) - - let path = CGMutablePath() - {{instructions}} - return path - } - - public static func image(size: CGSize) -> UIImage? { - guard size.height > 0.0 && size.width > 0.0 else { - return nil - } - - let radius = max(size.width / 2.0, size.height / 2.0) - let center = CGPoint(x: size.width / 2.0, y: size.height / 2.0) - - defer { - UIGraphicsEndImageContext() - } - - UIGraphicsBeginImageContextWithOptions(size, false, 0.0) - - guard let context = UIGraphicsGetCurrentContext() else { - return nil - } - - {{render}} - - return UIGraphicsGetImageFromCurrentImageContext() - } - - private static func radians(_ degree: Float) -> CGFloat { - return CGFloat(degree) * (.pi / CGFloat(180)) - } -} - -private extension CGContext { - func rendering(_ block: (CGContext) -> Void) { - block(self) - } -} - -#endif - -""" - -let contextTemplate: String = """ - context.rendering { (ctx) in - ctx.saveGState() - - let path = CGMutablePath() - {{instructions}} - - let defaultColor: CGColor = CGColor(srgbRed: 0.0, green: 0.0, blue: 0.0, alpha: 1.0) - let pathFillColor: CGColor? = {{fillColor}} - let pathFillOpacity: CGFloat? = {{fillOpacity}} - let pathFillRule: CGPathFillRule = {{fillRule}} - let pathStrokeColor: CGColor? = {{strokeColor}} - let pathStrokeOpacity: CGFloat? = {{strokeOpacity}} - let pathStrokeWidth: CGFloat? = {{strokeWidth}} - let pathStrokeLineCap: CGLineCap? = {{strokeLineCap}} - let pathStrokeLineJoin: CGLineJoin? = {{strokeLineJoin}} - let pathStrokeMiterLimit: CGFloat? = {{strokeMiterLimit}} - - if pathFillColor != nil && pathFillOpacity != nil { - let opacity = pathFillOpacity ?? 1.0 - let color = (pathFillColor ?? defaultColor).copy(alpha: opacity) ?? defaultColor - - ctx.setFillColor(color) - ctx.addPath(path) - ctx.fillPath(using: pathFillRule) - } - - if pathStrokeColor != nil && pathStrokeOpacity != nil { - let opacity = pathStrokeOpacity ?? 1.0 - let color = (pathStrokeColor ?? defaultColor).copy(alpha: opacity) ?? defaultColor - let lineWidth = pathStrokeWidth ?? 1.0 - - ctx.setLineWidth(lineWidth) - ctx.setStrokeColor(color) - if let lineCap = pathStrokeLineCap { - ctx.setLineCap(lineCap) - } - if let lineJoin = pathStrokeLineJoin { - ctx.setLineJoin(lineJoin) - if let miterLimit = pathStrokeMiterLimit, lineJoin == .miter { - ctx.setMiterLimit(miterLimit) - } - } - ctx.addPath(path) - ctx.strokePath() - } - - if (pathFillColor == nil && pathFillOpacity == nil) && (pathStrokeColor == nil && pathStrokeOpacity == nil) { - ctx.setFillColor(defaultColor) - ctx.addPath(path) - ctx.fillPath(using: pathFillRule) - } - - ctx.restoreGState() - } -""" diff --git a/third-party/VectorPlus/Sources/UIKit/SVG+UIImage.swift b/third-party/VectorPlus/Sources/UIKit/SVG+UIImage.swift deleted file mode 100644 index ea336be4f7..0000000000 --- a/third-party/VectorPlus/Sources/UIKit/SVG+UIImage.swift +++ /dev/null @@ -1,43 +0,0 @@ -#if canImport(UIKit) -import Swift2D -import SwiftSVG -import UIKit - -public extension SVG { - func uiImage(size: Size) -> UIImage? { - guard size.height > 0.0, size.width > 0.0 else { - return nil - } - - let from = Rect(origin: .zero, size: originalSize) - let to = Rect(origin: .zero, size: size) - - let paths: [Path] - do { - paths = try subpaths() - } catch { - return nil - } - - defer { - UIGraphicsEndImageContext() - } - - UIGraphicsBeginImageContextWithOptions(CGSize(size), false, 0.0) - - guard let context = UIGraphicsGetCurrentContext() else { - return nil - } - - for path in paths { - try? context.render(path: path, from: from, to: to) - } - - return UIGraphicsGetImageFromCurrentImageContext() - } - - func pngData(size: Size) -> Data? { - uiImage(size: size)?.pngData() - } -} -#endif diff --git a/third-party/VectorPlus/Sources/UIKit/SVGImageView.swift b/third-party/VectorPlus/Sources/UIKit/SVGImageView.swift deleted file mode 100644 index b5131c915a..0000000000 --- a/third-party/VectorPlus/Sources/UIKit/SVGImageView.swift +++ /dev/null @@ -1,81 +0,0 @@ -import Swift2D -import SwiftSVG -#if canImport(UIKit) && !os(watchOS) -import UIKit - -@IBDesignable open class SVGImageView: UIImageView { - - public var width: CGFloat { - CGFloat(svg.originalSize.width) - } - - public var height: CGFloat { - CGFloat(svg.originalSize.height) - } - - open var svg: SVG = SVG() { - didSet { - updateSubviews() - } - } - - public var widthToHeightAspectRatio: CGFloat { - guard !width.isNaN, width > 0.0 else { - return 0.0 - } - - guard !height.isNaN, height > 0.0 else { - return 0.0 - } - - return width / height - } - - public var heightToWidthAspectRatio: CGFloat { - guard !height.isNaN, height > 0.0 else { - return 0.0 - } - - guard !width.isNaN, width > 0.0 else { - return 0.0 - } - - return height / width - } - - override public init(frame: CGRect) { - super.init(frame: frame) - updateSubviews() - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - updateSubviews() - } - - override public var intrinsicContentSize: CGSize { - CGSize(width: width, height: height) - } - - override public var bounds: CGRect { - didSet { - updateSubviews() - } - } - - override public func prepareForInterfaceBuilder() { - super.prepareForInterfaceBuilder() - updateSubviews() - } - - override public func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - updateSubviews() - } - - public func updateSubviews() { - image = svg.uiImage(size: Size(bounds.size)) - } -} - -#endif diff --git a/third-party/VectorPlus/Sources/VectorPoint.swift b/third-party/VectorPlus/Sources/VectorPoint.swift deleted file mode 100644 index 91f81b1d20..0000000000 --- a/third-party/VectorPlus/Sources/VectorPoint.swift +++ /dev/null @@ -1,126 +0,0 @@ -import Swift2D - -/// A cartesian-based struct that describes the relationship of any particular `Point` to the _origin_ of a `Rect`. -public struct VectorPoint { - public enum Sign: String { - case plus = "+" - case minus = "-" - } - - public typealias Offset = (sign: Sign, multiplier: Double) - - public var x: Offset - public var y: Offset - - public init(x: Offset, y: Offset) { - self.x = x - self.y = y - } - - /// Initializes a `VectorPoint` for a given `Point` container in the provided `Rect`. - public init(point: Point, in rect: Rect) { - let radius = rect.size.maxRadius - let cartesianPoint = Self.cartesianPoint(for: point, in: rect) - - if cartesianPoint.x < 0 { - x = (.minus, abs(cartesianPoint.x) / radius) - } else { - x = (.plus, cartesianPoint.x / radius) - } - - if cartesianPoint.y < 0 { - y = (.plus, abs(cartesianPoint.y) / radius) - } else { - y = (.minus, cartesianPoint.y / radius) - } - } -} - -// MARK: - CustomStringConvertible - -extension VectorPoint: CustomStringConvertible { - public var description: String { - "VectorPoint(x: (\(x.sign.rawValue), \(x.multiplier)), y: (\(y.sign.rawValue), \(y.multiplier)))" - } -} - -// MARK: - Equatable - -extension VectorPoint: Equatable { - public static func == (lhs: VectorPoint, rhs: VectorPoint) -> Bool { - guard lhs.x.sign == rhs.x.sign else { - return false - } - guard lhs.x.multiplier == rhs.x.multiplier else { - return false - } - guard lhs.y.sign == rhs.y.sign else { - return false - } - guard lhs.y.multiplier == rhs.y.multiplier else { - return false - } - - return true - } -} - -// MARK: - - -public extension VectorPoint { - /// Translates the provided point within the `Rect` from using the top-left - /// as the _origin_, to using the center as the _origin_. - /// - /// For example: Given `Rect(x: 0, y: 0, width: 100, height: 100)`, the point - /// `Point(x: 25, y: 25)` would translate to `Point(x: -25, y: 25)`. - static func cartesianPoint(for point: Point, in rect: Rect) -> Point { - let origin = Point(x: rect.size.width / 2.0, y: rect.size.height / 2.0) - var cartesianPoint: Point = .zero - - if point.x < origin.x { - cartesianPoint = cartesianPoint.x(-(origin.x - point.x)) - } else if point.x > origin.x { - cartesianPoint = cartesianPoint.x(point.x - origin.x) - } - - if point.y > origin.y { - cartesianPoint = cartesianPoint.y(-(point.y - origin.y)) - } else if point.y < origin.y { - cartesianPoint = cartesianPoint.y(origin.y - point.y) - } - - return cartesianPoint - } -} - -// MARK: - Instance Functionality - -public extension VectorPoint { - /// Calculates the `Point` for this instance in the specified `Rect`. - func translate(to rect: Rect) -> Point { - translate(to: rect.size) - } - - /// Calculates the `Point` in the desired output size - func translate(to outputSize: Size) -> Point { - let center = outputSize.center - let radius = outputSize.minRadius - - switch (x.sign, y.sign) { - case (.plus, .plus): - return Point(x: center.x + (radius * x.multiplier), y: center.y + (radius * y.multiplier)) - case (.plus, .minus): - return Point(x: center.x + (radius * x.multiplier), y: center.y - (radius * y.multiplier)) - case (.minus, .plus): - return Point(x: center.x - (radius * x.multiplier), y: center.y + (radius * y.multiplier)) - case (.minus, .minus): - return Point(x: center.x - (radius * x.multiplier), y: center.y - (radius * y.multiplier)) - } - } -} - -public extension VectorPoint { - var coreGraphicsDescription: String { - "CGPoint(x: center.x \(x.sign.rawValue) (radius * \(x.multiplier)), y: center.y \(y.sign.rawValue) (radius * \(y.multiplier)))" - } -}