From 670bd2d45afae150a923a7ce87e7ca0c5e67050a Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Sat, 6 Jul 2019 15:39:30 +0200 Subject: [PATCH 01/41] Various UI fixes --- NotificationContent/Info.plist | 2 +- NotificationService/Info.plist | 2 +- Share/Info.plist | 2 +- SiriIntents/Info.plist | 2 +- Telegram-iOS/Info.plist | 2 +- Watch/App/Info.plist | 2 +- Watch/Extension/Info.plist | 2 +- Widget/Info.plist | 2 +- .../TelegramCore/TelegramPeerNotificationSettings.swift | 4 ++-- .../TelegramUI/ChatMessageAvatarAccessoryItem.swift | 6 +++++- .../TelegramUI/TelegramUI/ChatTextInputAttributes.swift | 2 +- .../TelegramUI/TelegramUI/MediaInputPaneTrendingItem.swift | 3 ++- 12 files changed, 18 insertions(+), 13 deletions(-) diff --git a/NotificationContent/Info.plist b/NotificationContent/Info.plist index def5291df2..fc4fb2678a 100644 --- a/NotificationContent/Info.plist +++ b/NotificationContent/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9 + 5.9.1 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/NotificationService/Info.plist b/NotificationService/Info.plist index ff3b9530b1..de5dc6bfcd 100644 --- a/NotificationService/Info.plist +++ b/NotificationService/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9 + 5.9.1 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/Share/Info.plist b/Share/Info.plist index 9ca0244ac4..a28ea585bc 100644 --- a/Share/Info.plist +++ b/Share/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9 + 5.9.1 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/SiriIntents/Info.plist b/SiriIntents/Info.plist index db4a9902b3..2a6a05825c 100644 --- a/SiriIntents/Info.plist +++ b/SiriIntents/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9 + 5.9.1 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/Telegram-iOS/Info.plist b/Telegram-iOS/Info.plist index 1a8de0bd71..1c01c0b648 100644 --- a/Telegram-iOS/Info.plist +++ b/Telegram-iOS/Info.plist @@ -185,7 +185,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 5.9 + 5.9.1 CFBundleSignature ???? CFBundleURLTypes diff --git a/Watch/App/Info.plist b/Watch/App/Info.plist index fe81e58b75..a24eeb4c0d 100644 --- a/Watch/App/Info.plist +++ b/Watch/App/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 5.9 + 5.9.1 CFBundleVersion ${BUILD_NUMBER} UISupportedInterfaceOrientations diff --git a/Watch/Extension/Info.plist b/Watch/Extension/Info.plist index ef838bd935..7d5914d543 100644 --- a/Watch/Extension/Info.plist +++ b/Watch/Extension/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9 + 5.9.1 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/Widget/Info.plist b/Widget/Info.plist index 3660ec2d30..74ebe90850 100644 --- a/Widget/Info.plist +++ b/Widget/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9 + 5.9.1 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/submodules/TelegramCore/TelegramCore/TelegramPeerNotificationSettings.swift b/submodules/TelegramCore/TelegramCore/TelegramPeerNotificationSettings.swift index 154d1b922b..aa6e6fa00a 100644 --- a/submodules/TelegramCore/TelegramCore/TelegramPeerNotificationSettings.swift +++ b/submodules/TelegramCore/TelegramCore/TelegramPeerNotificationSettings.swift @@ -136,9 +136,9 @@ public enum PeerNotificationDisplayPreviews { case .default: encoder.encodeInt32(0, forKey: "p.v") case .show: - encoder.encodeInt32(0, forKey: "p.v") + encoder.encodeInt32(1, forKey: "p.v") case .hide: - encoder.encodeInt32(0, forKey: "p.v") + encoder.encodeInt32(2, forKey: "p.v") } } } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAvatarAccessoryItem.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAvatarAccessoryItem.swift index 9aaed1628c..b5c777c419 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAvatarAccessoryItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAvatarAccessoryItem.swift @@ -67,6 +67,10 @@ final class ChatMessageAvatarAccessoryItemNode: ListViewAccessoryItemNode { } func setPeer(account: Account, theme: PresentationTheme, synchronousLoad:Bool, peer: Peer, authorOfMessage: MessageReference?, emptyColor: UIColor) { - self.avatarNode.setPeer(account: account, theme: theme, peer: peer, authorOfMessage: authorOfMessage, emptyColor: emptyColor, synchronousLoad: synchronousLoad) + var overrideImage: AvatarNodeImageOverride? + if peer.isDeleted { + overrideImage = .deletedIcon + } + self.avatarNode.setPeer(account: account, theme: theme, peer: peer, authorOfMessage: authorOfMessage, overrideImage: overrideImage, emptyColor: emptyColor, synchronousLoad: synchronousLoad) } } diff --git a/submodules/TelegramUI/TelegramUI/ChatTextInputAttributes.swift b/submodules/TelegramUI/TelegramUI/ChatTextInputAttributes.swift index a9166ab9e6..032306111a 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTextInputAttributes.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTextInputAttributes.swift @@ -666,7 +666,7 @@ func convertMarkdownToAttributes(_ text: NSAttributedString) -> NSAttributedStri while let match = regex.firstMatch(in: string as String, range: NSMakeRange(0, string.length)) { let matchIndex = stringOffset + match.range.location - result.append(text.attributedSubstring(from: NSMakeRange(0, match.range.location))) + result.append(text.attributedSubstring(from: NSMakeRange(text.length - string.length, match.range.location))) var pre = match.range(at: 3) if pre.location != NSNotFound { diff --git a/submodules/TelegramUI/TelegramUI/MediaInputPaneTrendingItem.swift b/submodules/TelegramUI/TelegramUI/MediaInputPaneTrendingItem.swift index 04cf0a09bf..571d79455c 100644 --- a/submodules/TelegramUI/TelegramUI/MediaInputPaneTrendingItem.swift +++ b/submodules/TelegramUI/TelegramUI/MediaInputPaneTrendingItem.swift @@ -114,6 +114,7 @@ final class TrendingTopItemNode: ASDisplayNode { self?.imageNode.alpha = 0.0 } animationNode.setup(account: account, resource: item.file.resource, width: 160, height: 160, mode: .cached) + self.loadDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: stickerPackFileReference(item.file), resource: item.file.resource).start()) } else { self.imageNode.setSignal(chatMessageSticker(account: account, file: item.file, small: true, synchronousLoad: synchronousLoads), attemptSynchronously: synchronousLoads) @@ -121,8 +122,8 @@ final class TrendingTopItemNode: ASDisplayNode { self.animationNode = nil currentAnimationNode.removeFromSupernode() } + self.loadDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: stickerPackFileReference(item.file), resource: chatMessageStickerResource(file: item.file, small: true)).start()) } - self.loadDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: stickerPackFileReference(item.file), resource: chatMessageStickerResource(file: item.file, small: true)).start()) } func updatePreviewing(animated: Bool, isPreviewing: Bool) { From 6e060bddedf4473fcf4d23ab795789a39f71c3bf Mon Sep 17 00:00:00 2001 From: Peter <> Date: Sat, 6 Jul 2019 20:34:08 +0300 Subject: [PATCH 02/41] Isolate rlottie drawing --- .../rlottie/src/lottie/lottieanimation.cpp | 2 +- .../Sources/rlottie/src/vector/config.h | 2 +- .../Sources/rlottie/src/vector/vraster.cpp | 19 ++++++++++++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/submodules/RLottie/Sources/rlottie/src/lottie/lottieanimation.cpp b/submodules/RLottie/Sources/rlottie/src/lottie/lottieanimation.cpp index 61f23ff9b8..7b11f4f8ce 100644 --- a/submodules/RLottie/Sources/rlottie/src/lottie/lottieanimation.cpp +++ b/submodules/RLottie/Sources/rlottie/src/lottie/lottieanimation.cpp @@ -113,7 +113,7 @@ void AnimationImpl::init(const std::shared_ptr &model) mRenderInProgress = false; } -#if false //def LOTTIE_THREAD_SUPPORT +#ifdef LOTTIE_THREAD_SUPPORT #include #include "vtaskqueue.h" diff --git a/submodules/RLottie/Sources/rlottie/src/vector/config.h b/submodules/RLottie/Sources/rlottie/src/vector/config.h index dde0e17724..596ad11616 100644 --- a/submodules/RLottie/Sources/rlottie/src/vector/config.h +++ b/submodules/RLottie/Sources/rlottie/src/vector/config.h @@ -2,7 +2,7 @@ #define CONFIG_H // enable threading -#define LOTTIE_THREAD_SUPPORT +//#define LOTTIE_THREAD_SUPPORT //enable logging //#define LOTTIE_LOGGING_SUPPORT diff --git a/submodules/RLottie/Sources/rlottie/src/vector/vraster.cpp b/submodules/RLottie/Sources/rlottie/src/vector/vraster.cpp index 3f24e3dd70..fec83e83b5 100644 --- a/submodules/RLottie/Sources/rlottie/src/vector/vraster.cpp +++ b/submodules/RLottie/Sources/rlottie/src/vector/vraster.cpp @@ -346,7 +346,7 @@ struct VRleTask { sw_ft_grays_raster.raster_render(nullptr, ¶ms); } - void operator()(FTOutline &outRef, SW_FT_Stroker &stroker) + void update(FTOutline &outRef, SW_FT_Stroker &stroker) { if (mGenerateStroke) { // Stroke Task outRef.convert(mPath); @@ -481,13 +481,23 @@ public: ~RleTaskScheduler() { SW_FT_Stroker_Done(stroker); } - void process(VTask task) { (*task)(outlineRef, stroker); } + void process(VTask task) { (*task).update(outlineRef, stroker); } }; #endif struct VRasterizer::VRasterizerImpl { VRleTask mTask; - + FTOutline outlineRef; + SW_FT_Stroker stroker; + + VRasterizerImpl() { + SW_FT_Stroker_New(&stroker); + } + + ~VRasterizerImpl() { + SW_FT_Stroker_Done(stroker); + } + VRle & rle() { return mTask.rle(); } VRleTask &task() { return mTask; } }; @@ -505,8 +515,7 @@ void VRasterizer::init() void VRasterizer::updateRequest() { - VTask taskObj = VTask(d, &d->task()); - RleTaskScheduler::instance().process(std::move(taskObj)); + d->task().update(d->outlineRef, d->stroker); } void VRasterizer::rasterize(VPath path, FillRule fillRule, const VRect &clip) From f57f5b663795f96c4fe56bb698e4d3e73a8a90bb Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Sun, 7 Jul 2019 00:02:23 +0200 Subject: [PATCH 03/41] Increased animated sticker file size limit --- .../TelegramUI/TelegramUI/AnimatedStickerUtils.swift | 11 ++++++++--- .../TelegramUI/TelegramUI/ChatMessageItem.swift | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift index 901a8a5d14..c836c4afe1 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift @@ -69,16 +69,21 @@ private func validateAnimationLayers(_ layers: [Any]?) -> Bool { } func validateAnimationComposition(json: [AnyHashable: Any]) -> Bool { + let validDimensions: [Int] = [100, 512] + let validFramerates: [Int] = [30, 60] + guard let tgs = json["tgs"] as? Int, tgs == 1 else { return false } - guard let width = json["w"] as? Int, width == 512 else { + guard let width = json["w"] as? Int, validDimensions.contains(width) else { return false } - guard let height = json["h"] as? Int, height == 512 else { + guard let height = json["h"] as? Int, validDimensions.contains(height) else { + return false + } + guard let fps = json["fr"] as? Int, validFramerates.contains(fps) else { return false } - return true } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift index a4e3848a4d..d020ec179c 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift @@ -353,7 +353,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { loop: for media in self.message.media { if let telegramFile = media as? TelegramMediaFile { - if telegramFile.isAnimatedSticker, let size = telegramFile.size, size > 0 && size <= 64 * 1024 { + if telegramFile.isAnimatedSticker, let size = telegramFile.size, size > 0 && size <= 128 * 1024 { viewClassName = ChatMessageAnimatedStickerItemNode.self break loop } From 4f2f717239f5740168e6685dde9a310ad9fef157 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Sun, 7 Jul 2019 16:12:50 +0200 Subject: [PATCH 04/41] Fixed lottie file parsing --- .../rlottie/src/lottie/lottieloader.cpp | 6 +++++ .../rlottie/src/lottie/lottieparser.cpp | 26 ++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/submodules/RLottie/Sources/rlottie/src/lottie/lottieloader.cpp b/submodules/RLottie/Sources/rlottie/src/lottie/lottieloader.cpp index 28b4e4b1ce..d9383f6dd4 100644 --- a/submodules/RLottie/Sources/rlottie/src/lottie/lottieloader.cpp +++ b/submodules/RLottie/Sources/rlottie/src/lottie/lottieloader.cpp @@ -93,6 +93,9 @@ bool LottieLoader::load(const std::string &path) LottieParser parser(const_cast(buf.str().data()), dirname(path).c_str()); mModel = parser.model(); + + if (!mModel) return false; + LottieFileCache::instance().add(path, mModel); f.close(); @@ -110,6 +113,9 @@ bool LottieLoader::loadFromData(std::string &&jsonData, const std::string &key, LottieParser parser(const_cast(jsonData.c_str()), resourcePath.c_str()); mModel = parser.model(); + + if (!mModel) return false; + LottieFileCache::instance().add(key, mModel); return true; diff --git a/submodules/RLottie/Sources/rlottie/src/lottie/lottieparser.cpp b/submodules/RLottie/Sources/rlottie/src/lottie/lottieparser.cpp index 614ea335ca..a0d40122d6 100644 --- a/submodules/RLottie/Sources/rlottie/src/lottie/lottieparser.cpp +++ b/submodules/RLottie/Sources/rlottie/src/lottie/lottieparser.cpp @@ -587,6 +587,12 @@ void LottieParserImpl::parseComposition() Skip(key); } } + + if (comp->mVersion.empty()) { + // don't have a valid bodymovin header + return; + } + resolveLayerRefs(); comp->setStatic(comp->mRootLayer->isStatic()); comp->mRootLayer->mInFrame = comp->mStartFrame; @@ -699,8 +705,10 @@ std::shared_ptr LottieParserImpl::parseAsset() bool staticFlag = true; while (NextArrayValue()) { std::shared_ptr layer = parseLayer(); - staticFlag = staticFlag && layer->isStatic(); - asset->mLayers.push_back(layer); + if (layer) { + staticFlag = staticFlag && layer->isStatic(); + asset->mLayers.push_back(layer); + } } asset->setStatic(staticFlag); } else { @@ -735,8 +743,10 @@ void LottieParserImpl::parseLayers(LOTCompositionData *comp) EnterArray(); while (NextArrayValue()) { std::shared_ptr layer = parseLayer(true); - staticFlag = staticFlag && layer->isStatic(); - comp->mRootLayer->mChildren.push_back(layer); + if (layer) { + staticFlag = staticFlag && layer->isStatic(); + comp->mRootLayer->mChildren.push_back(layer); + } } comp->mRootLayer->setStatic(staticFlag); } @@ -904,6 +914,11 @@ std::shared_ptr LottieParserImpl::parseLayer(bool record) Skip(key); } } + + if (!layer->mTransform) { + // not a valid layer + return nullptr; + } layer->mCompRef = compRef; @@ -1240,6 +1255,7 @@ LOTTrimData::TrimType LottieParserImpl::getTrimType() break; default: RAPIDJSON_ASSERT(0); + return LOTTrimData::TrimType::Individually; break; } } @@ -2229,6 +2245,8 @@ LottieParser::LottieParser(char *str, const char *dir_path) std::shared_ptr LottieParser::model() { + if (!d->composition()) return nullptr; + std::shared_ptr model = std::make_shared(); model->mRoot = d->composition(); model->mRoot->processRepeaterObjects(); From 529dfcd10aed9f8876240c3f5f407c53eb7fc16f Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Sun, 7 Jul 2019 16:40:40 +0200 Subject: [PATCH 05/41] Fixed gunzip --- submodules/GZip/Sources/GZip.h | 4 ++-- submodules/GZip/Sources/GZip.m | 14 +++++++++++--- .../TelegramUI/AnimatedStickerNode.swift | 2 +- .../TelegramUI/AnimatedStickerUtils.swift | 4 ++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/submodules/GZip/Sources/GZip.h b/submodules/GZip/Sources/GZip.h index ee4c756f4d..ea1f93b9b3 100644 --- a/submodules/GZip/Sources/GZip.h +++ b/submodules/GZip/Sources/GZip.h @@ -10,8 +10,8 @@ FOUNDATION_EXPORT const unsigned char GZipVersionString[]; extern "C" { #endif -NSData *TGGZipData(NSData *data, float level); -NSData * _Nullable TGGUnzipData(NSData *data); +NSData * _Nonnull TGGZipData(NSData * _Nonnull data, float level); +NSData * _Nullable TGGUnzipData(NSData * _Nonnull data, uint sizeLimit); #ifdef __cplusplus } diff --git a/submodules/GZip/Sources/GZip.m b/submodules/GZip/Sources/GZip.m index 4d55ac33bc..9e7a828e7d 100644 --- a/submodules/GZip/Sources/GZip.m +++ b/submodules/GZip/Sources/GZip.m @@ -42,7 +42,7 @@ NSData *TGGZipData(NSData *data, float level) { return output; } -NSData * _Nullable TGGUnzipData(NSData *data) +NSData * _Nullable TGGUnzipData(NSData *data, uint sizeLimit) { if (data.length == 0 || !TGIsGzippedData(data)) { return nil; @@ -61,12 +61,20 @@ NSData * _Nullable TGGUnzipData(NSData *data) int status = Z_OK; output = [NSMutableData dataWithCapacity:data.length * 2]; while (status == Z_OK) { + if (sizeLimit > 0 && stream.total_out > sizeLimit) { + return nil; + } + if (stream.total_out >= output.length) { - output.length += data.length / 2; + NSUInteger length = output.length + data.length / 2; + if (sizeLimit > 0 && length > sizeLimit) { + return nil; + } + output.length = length; } stream.next_out = (uint8_t *)output.mutableBytes + stream.total_out; stream.avail_out = (uInt)(output.length - stream.total_out); - status = inflate (&stream, Z_SYNC_FLUSH); + status = inflate(&stream, Z_SYNC_FLUSH); } if (inflateEnd(&stream) == Z_OK) { if (status == Z_STREAM_END) { diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift index bb5986a994..a7a817af47 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift @@ -214,7 +214,7 @@ private final class AnimatedStickerDirectFrameSource: AnimatedStickerFrameSource self.width = width self.height = height self.currentFrame = 0 - guard let rawData = TGGUnzipData(data) else { + guard let rawData = TGGUnzipData(data, 1024 * 1024) else { return nil } guard let animation = LottieInstance(data: rawData, cacheKey: "") else { diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift index c836c4afe1..c9baab8fa8 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift @@ -98,7 +98,7 @@ func fetchCompressedLottieFirstFrameAJpeg(data: Data, size: CGSize, cacheKey: St return } - let decompressedData = TGGUnzipData(data) + let decompressedData = TGGUnzipData(data, 1024 * 1024) if let decompressedData = decompressedData, let player = LottieInstance(data: decompressedData, cacheKey: cacheKey) { if cancelled.with({ $0 }) { return @@ -193,7 +193,7 @@ func experimentalConvertCompressedLottieToCombinedMp4(data: Data, size: CGSize, var deltaTime: Double = 0 var compressionTime: Double = 0 - let decompressedData = TGGUnzipData(data) + let decompressedData = TGGUnzipData(data, 1024 * 1024) if let decompressedData = decompressedData, let player = LottieInstance(data: decompressedData, cacheKey: cacheKey) { let endFrame = Int(player.frameCount) From 1aa9c3d871cf3055b731761d1a0ff6abb2740813 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Sun, 7 Jul 2019 17:01:38 +0200 Subject: [PATCH 06/41] Added some format checks --- submodules/RLottie/Sources/LottieInstance.mm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/submodules/RLottie/Sources/LottieInstance.mm b/submodules/RLottie/Sources/LottieInstance.mm index 849339297b..499469e2d8 100644 --- a/submodules/RLottie/Sources/LottieInstance.mm +++ b/submodules/RLottie/Sources/LottieInstance.mm @@ -20,6 +20,17 @@ _frameCount = (int32_t)_animation->totalFrame(); _frameRate = (int32_t)_animation->frameRate(); + + size_t width = 0; + size_t height = 0; + _animation->size(width, height); + + if (width != height || (width != 100 && width != 512)) { + return nil; + } + if ((_frameRate > 30 && _frameRate != 60) || _animation->duration() > 4.5) { + return nil; + } } return self; } From 7ff263736cc72c47966a430391455501f8dde111 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Sun, 7 Jul 2019 17:12:31 +0200 Subject: [PATCH 07/41] Added tgs check --- submodules/RLottie/Sources/rlottie/inc/rlottie.h | 2 ++ .../Sources/rlottie/src/lottie/lottieanimation.cpp | 8 +++++++- .../RLottie/Sources/rlottie/src/lottie/lottiemodel.h | 2 ++ .../RLottie/Sources/rlottie/src/lottie/lottieparser.cpp | 5 ++++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/submodules/RLottie/Sources/rlottie/inc/rlottie.h b/submodules/RLottie/Sources/rlottie/inc/rlottie.h index 74def69ebc..ab70720b2b 100644 --- a/submodules/RLottie/Sources/rlottie/inc/rlottie.h +++ b/submodules/RLottie/Sources/rlottie/inc/rlottie.h @@ -423,6 +423,8 @@ public: * @internal */ ~Animation(); + + bool isTgs() const; private: void setValue(Color_Type, Property, const std::string &, Color); diff --git a/submodules/RLottie/Sources/rlottie/src/lottie/lottieanimation.cpp b/submodules/RLottie/Sources/rlottie/src/lottie/lottieanimation.cpp index 7b11f4f8ce..91514858e7 100644 --- a/submodules/RLottie/Sources/rlottie/src/lottie/lottieanimation.cpp +++ b/submodules/RLottie/Sources/rlottie/src/lottie/lottieanimation.cpp @@ -47,7 +47,8 @@ public: Surface render(size_t frameNo, const Surface &surface); std::future renderAsync(size_t frameNo, Surface &&surface); const LOTLayerNode * renderTree(size_t frameNo, const VSize &size); - + bool isTgs() const { return mModel->isTgs(); } + const LayerInfoList &layerInfoList() const { return mModel->layerInfoList(); @@ -266,6 +267,11 @@ std::unique_ptr Animation::loadFromFile(const std::string &path) return nullptr; } +bool Animation::isTgs() const +{ + return d->isTgs(); +} + void Animation::size(size_t &width, size_t &height) const { VSize sz = d->size(); diff --git a/submodules/RLottie/Sources/rlottie/src/lottie/lottiemodel.h b/submodules/RLottie/Sources/rlottie/src/lottie/lottiemodel.h index 6fe933593e..2353cb7a05 100644 --- a/submodules/RLottie/Sources/rlottie/src/lottie/lottiemodel.h +++ b/submodules/RLottie/Sources/rlottie/src/lottie/lottiemodel.h @@ -569,6 +569,7 @@ public: VSize size() const {return mSize;} void processRepeaterObjects(); public: + int mTgs; std::string mVersion; VSize mSize; long mStartFrame{0}; @@ -954,6 +955,7 @@ public: class LOTModel { public: + bool isTgs() const {return mRoot->mTgs == 1;} bool isStatic() const {return mRoot->isStatic();} double duration() const {return mRoot->duration();} size_t totalFrame() const {return mRoot->totalFrame();} diff --git a/submodules/RLottie/Sources/rlottie/src/lottie/lottieparser.cpp b/submodules/RLottie/Sources/rlottie/src/lottie/lottieparser.cpp index a0d40122d6..9def4aa8a0 100644 --- a/submodules/RLottie/Sources/rlottie/src/lottie/lottieparser.cpp +++ b/submodules/RLottie/Sources/rlottie/src/lottie/lottieparser.cpp @@ -558,7 +558,10 @@ void LottieParserImpl::parseComposition() LOTCompositionData *comp = sharedComposition.get(); compRef = comp; while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "v")) { + if (0 == strcmp(key, "tgs")) { + RAPIDJSON_ASSERT(PeekType() == kNumberType); + comp->mTgs = GetInt(); + }else if (0 == strcmp(key, "v")) { RAPIDJSON_ASSERT(PeekType() == kStringType); comp->mVersion = std::string(GetString()); } else if (0 == strcmp(key, "w")) { From 12cfc4650b4375401f536c4287a65fb14d5a3dec Mon Sep 17 00:00:00 2001 From: Peter <> Date: Wed, 10 Jul 2019 14:51:11 +0400 Subject: [PATCH 08/41] Bump version --- NotificationContent/Info.plist | 2 +- NotificationService/Info.plist | 2 +- Share/Info.plist | 2 +- SiriIntents/Info.plist | 2 +- Telegram-iOS/Info.plist | 2 +- Watch/App/Info.plist | 2 +- Watch/Extension/Info.plist | 2 +- Widget/Info.plist | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/NotificationContent/Info.plist b/NotificationContent/Info.plist index fc4fb2678a..c99413d85f 100644 --- a/NotificationContent/Info.plist +++ b/NotificationContent/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9.1 + 5.10 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/NotificationService/Info.plist b/NotificationService/Info.plist index de5dc6bfcd..56035c8f67 100644 --- a/NotificationService/Info.plist +++ b/NotificationService/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9.1 + 5.10 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/Share/Info.plist b/Share/Info.plist index a28ea585bc..8c086c756a 100644 --- a/Share/Info.plist +++ b/Share/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9.1 + 5.10 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/SiriIntents/Info.plist b/SiriIntents/Info.plist index 2a6a05825c..cbb4b58170 100644 --- a/SiriIntents/Info.plist +++ b/SiriIntents/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9.1 + 5.10 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/Telegram-iOS/Info.plist b/Telegram-iOS/Info.plist index 1c01c0b648..86c07932ab 100644 --- a/Telegram-iOS/Info.plist +++ b/Telegram-iOS/Info.plist @@ -185,7 +185,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 5.9.1 + 5.10 CFBundleSignature ???? CFBundleURLTypes diff --git a/Watch/App/Info.plist b/Watch/App/Info.plist index a24eeb4c0d..6a22ec2a10 100644 --- a/Watch/App/Info.plist +++ b/Watch/App/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 5.9.1 + 5.10 CFBundleVersion ${BUILD_NUMBER} UISupportedInterfaceOrientations diff --git a/Watch/Extension/Info.plist b/Watch/Extension/Info.plist index 7d5914d543..4b90eb9880 100644 --- a/Watch/Extension/Info.plist +++ b/Watch/Extension/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9.1 + 5.10 CFBundleVersion ${BUILD_NUMBER} NSExtension diff --git a/Widget/Info.plist b/Widget/Info.plist index 74ebe90850..beab95bb21 100644 --- a/Widget/Info.plist +++ b/Widget/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 5.9.1 + 5.10 CFBundleVersion ${BUILD_NUMBER} NSExtension From 3c292874911c12e0a89fe0161fbe0201d4d46dc4 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Tue, 30 Jul 2019 21:32:48 +0300 Subject: [PATCH 09/41] API update --- submodules/TelegramApi/Sources/Api0.swift | 1 + submodules/TelegramApi/Sources/Api1.swift | 12 ++ .../TelegramCore/CachedStickerPack.swift | 116 +++++++++++------- .../TelegramCore/LoadedStickerPack.swift | 2 + .../ManagedSecretChatOutgoingOperations.swift | 18 ++- .../TelegramCore/Namespaces.swift | 1 + .../PendingMessageUploadedContent.swift | 2 + .../TelegramCore/StickerSetInstallation.swift | 3 + .../SynchronizeSavedStickersOperation.swift | 2 + .../TelegramCore/TelegramMediaFile.swift | 13 ++ 10 files changed, 120 insertions(+), 50 deletions(-) diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index c07fbd6e77..06a2721880 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -538,6 +538,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-4838507] = { return Api.InputStickerSet.parse_inputStickerSetEmpty($0) } dict[-1645763991] = { return Api.InputStickerSet.parse_inputStickerSetID($0) } dict[-2044933984] = { return Api.InputStickerSet.parse_inputStickerSetShortName($0) } + dict[42402760] = { return Api.InputStickerSet.parse_inputStickerSetAnimatedEmoji($0) } dict[-1729618630] = { return Api.BotInfo.parse_botInfo($0) } dict[-1519637954] = { return Api.updates.State.parse_state($0) } dict[372165663] = { return Api.FoundGif.parse_foundGif($0) } diff --git a/submodules/TelegramApi/Sources/Api1.swift b/submodules/TelegramApi/Sources/Api1.swift index 11639e00bd..391a88b56b 100644 --- a/submodules/TelegramApi/Sources/Api1.swift +++ b/submodules/TelegramApi/Sources/Api1.swift @@ -13607,6 +13607,7 @@ public extension Api { case inputStickerSetEmpty case inputStickerSetID(id: Int64, accessHash: Int64) case inputStickerSetShortName(shortName: String) + case inputStickerSetAnimatedEmoji public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { @@ -13628,6 +13629,12 @@ public extension Api { buffer.appendInt32(-2044933984) } serializeString(shortName, buffer: buffer, boxed: false) + break + case .inputStickerSetAnimatedEmoji: + if boxed { + buffer.appendInt32(42402760) + } + break } } @@ -13640,6 +13647,8 @@ public extension Api { return ("inputStickerSetID", [("id", id), ("accessHash", accessHash)]) case .inputStickerSetShortName(let shortName): return ("inputStickerSetShortName", [("shortName", shortName)]) + case .inputStickerSetAnimatedEmoji: + return ("inputStickerSetAnimatedEmoji", []) } } @@ -13671,6 +13680,9 @@ public extension Api { return nil } } + public static func parse_inputStickerSetAnimatedEmoji(_ reader: BufferReader) -> InputStickerSet? { + return Api.InputStickerSet.inputStickerSetAnimatedEmoji + } } public enum BotInfo: TypeConstructorDescription { diff --git a/submodules/TelegramCore/TelegramCore/CachedStickerPack.swift b/submodules/TelegramCore/TelegramCore/CachedStickerPack.swift index b041c7eca2..d31e5e06f7 100644 --- a/submodules/TelegramCore/TelegramCore/CachedStickerPack.swift +++ b/submodules/TelegramCore/TelegramCore/CachedStickerPack.swift @@ -54,9 +54,13 @@ public enum CachedStickerPackResult { case result(StickerPackCollectionInfo, [ItemCollectionItem], Bool) } -func cacheStickerPack(transaction: Transaction, info: StickerPackCollectionInfo, items: [ItemCollectionItem]) { +func cacheStickerPack(transaction: Transaction, info: StickerPackCollectionInfo, items: [ItemCollectionItem], reference: StickerPackReference? = nil) { transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(info.id)), entry: CachedStickerPack(info: info, items: items.map { $0 as! StickerPackItem }, hash: info.hash), collectionSpec: collectionSpec) transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(shortName: info.shortName)), entry: CachedStickerPack(info: info, items: items.map { $0 as! StickerPackItem }, hash: info.hash), collectionSpec: collectionSpec) + + if let reference = reference, case .animatedEmoji = reference { + transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: Namespaces.ItemCollection.CloudAnimatedEmoji, id: 0))), entry: CachedStickerPack(info: info, items: items.map { $0 as! StickerPackItem }, hash: info.hash), collectionSpec: collectionSpec) + } } public func cachedStickerPack(postbox: Postbox, network: Network, reference: StickerPackReference, forceRemote: Bool) -> Signal { @@ -76,30 +80,44 @@ public func cachedStickerPack(postbox: Postbox, network: Network, reference: Sti let namespace = Namespaces.ItemCollection.CloudStickerPacks var previousHash: Int32? switch reference { - case let .id(id, _): - if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id)))) as? CachedStickerPack, let info = cached.info { - previousHash = cached.hash - let current: CachedStickerPackResult = .result(info, cached.items, false) - if cached.hash != info.hash { - return (current, true, previousHash) + case let .id(id, _): + if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id)))) as? CachedStickerPack, let info = cached.info { + previousHash = cached.hash + let current: CachedStickerPackResult = .result(info, cached.items, false) + if cached.hash != info.hash { + return (current, true, previousHash) + } else { + return (current, true, previousHash) + } } else { - return (current, true, previousHash) + return (.fetching, true, nil) } - } else { - return (.fetching, true, nil) - } - case let .name(shortName): - if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(shortName: shortName))) as? CachedStickerPack, let info = cached.info { - previousHash = cached.hash - let current: CachedStickerPackResult = .result(info, cached.items, false) - if cached.hash != info.hash { - return (current, true, previousHash) + case let .name(shortName): + if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(shortName: shortName))) as? CachedStickerPack, let info = cached.info { + previousHash = cached.hash + let current: CachedStickerPackResult = .result(info, cached.items, false) + if cached.hash != info.hash { + return (current, true, previousHash) + } else { + return (current, true, previousHash) + } } else { - return (current, true, previousHash) + return (.fetching, true, nil) + } + case .animatedEmoji: + let namespace = Namespaces.ItemCollection.CloudAnimatedEmoji + let id: ItemCollectionId.Id = 0 + if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id)))) as? CachedStickerPack, let info = cached.info { + previousHash = cached.hash + let current: CachedStickerPackResult = .result(info, cached.items, false) + if cached.hash != info.hash { + return (current, true, previousHash) + } else { + return (current, true, previousHash) + } + } else { + return (.fetching, true, nil) } - } else { - return (.fetching, true, nil) - } } } |> mapToSignal { result, loadRemote, previousHash in @@ -111,10 +129,8 @@ public func cachedStickerPack(postbox: Postbox, network: Network, reference: Sti } return postbox.transaction { transaction -> CachedStickerPackResult in if let result = result { - cacheStickerPack(transaction: transaction, info: result.0, items: result.1) - + cacheStickerPack(transaction: transaction, info: result.0, items: result.1, reference: reference) let currentInfo = transaction.getItemCollectionInfo(collectionId: result.0.id) as? StickerPackCollectionInfo - return .result(result.0, result.1, currentInfo != nil) } else { return .none @@ -134,30 +150,42 @@ public func cachedStickerPack(postbox: Postbox, network: Network, reference: Sti func cachedStickerPack(transaction: Transaction, reference: StickerPackReference) -> (StickerPackCollectionInfo, [ItemCollectionItem], Bool)? { let namespace = Namespaces.ItemCollection.CloudStickerPacks switch reference { - case let .id(id, _): - if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { - let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) - if !items.isEmpty { - return (currentInfo, items, true) + case let .id(id, _): + if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { + let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) + if !items.isEmpty { + return (currentInfo, items, true) + } } - } - if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id)))) as? CachedStickerPack, let info = cached.info { - return (info, cached.items, false) - } - case let .name(shortName): - for info in transaction.getItemCollectionsInfos(namespace: namespace) { - if let info = info.1 as? StickerPackCollectionInfo { - if info.shortName == shortName { - let items = transaction.getItemCollectionItems(collectionId: info.id) - if !items.isEmpty { - return (info, items, true) + if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id)))) as? CachedStickerPack, let info = cached.info { + return (info, cached.items, false) + } + case let .name(shortName): + for info in transaction.getItemCollectionsInfos(namespace: namespace) { + if let info = info.1 as? StickerPackCollectionInfo { + if info.shortName == shortName { + let items = transaction.getItemCollectionItems(collectionId: info.id) + if !items.isEmpty { + return (info, items, true) + } } } } - } - if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(shortName: shortName))) as? CachedStickerPack, let info = cached.info { - return (info, cached.items, false) - } + if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(shortName: shortName))) as? CachedStickerPack, let info = cached.info { + return (info, cached.items, false) + } + case .animatedEmoji: + let namespace = Namespaces.ItemCollection.CloudAnimatedEmoji + let id: ItemCollectionId.Id = 0 + if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo { + let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id)) + if !items.isEmpty { + return (currentInfo, items, true) + } + } + if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id)))) as? CachedStickerPack, let info = cached.info { + return (info, cached.items, false) + } } return nil } diff --git a/submodules/TelegramCore/TelegramCore/LoadedStickerPack.swift b/submodules/TelegramCore/TelegramCore/LoadedStickerPack.swift index a2c7843238..05b0385db8 100644 --- a/submodules/TelegramCore/TelegramCore/LoadedStickerPack.swift +++ b/submodules/TelegramCore/TelegramCore/LoadedStickerPack.swift @@ -20,6 +20,8 @@ extension StickerPackReference { return .inputStickerSetID(id: id, accessHash: accessHash) case let .name(name): return .inputStickerSetShortName(shortName: name) + case .animatedEmoji: + return .inputStickerSetAnimatedEmoji } } } diff --git a/submodules/TelegramCore/TelegramCore/ManagedSecretChatOutgoingOperations.swift b/submodules/TelegramCore/TelegramCore/ManagedSecretChatOutgoingOperations.swift index 861c0607df..e7dd9f46a1 100644 --- a/submodules/TelegramCore/TelegramCore/ManagedSecretChatOutgoingOperations.swift +++ b/submodules/TelegramCore/TelegramCore/ManagedSecretChatOutgoingOperations.swift @@ -504,6 +504,8 @@ private func decryptedAttributes46(_ attributes: [TelegramMediaFileAttribute], t if let (info, _, _) = cachedStickerPack(transaction: transaction, reference: packReference) { stickerSet = .inputStickerSetShortName(shortName: info.shortName) } + default: + stickerSet = .inputStickerSetEmpty } } result.append(.documentAttributeSticker(alt: displayText, stickerset: stickerSet)) @@ -553,6 +555,8 @@ private func decryptedAttributes73(_ attributes: [TelegramMediaFileAttribute], t if let (info, _, _) = cachedStickerPack(transaction: transaction, reference: packReference) { stickerSet = .inputStickerSetShortName(shortName: info.shortName) } + default: + stickerSet = .inputStickerSetEmpty } } result.append(.documentAttributeSticker(alt: displayText, stickerset: stickerSet)) @@ -600,12 +604,14 @@ private func decryptedAttributes101(_ attributes: [TelegramMediaFileAttribute], var stickerSet: SecretApi101.InputStickerSet = .inputStickerSetEmpty if let packReference = packReference { switch packReference { - case let .name(name): - stickerSet = .inputStickerSetShortName(shortName: name) - case .id: - if let (info, _, _) = cachedStickerPack(transaction: transaction, reference: packReference) { - stickerSet = .inputStickerSetShortName(shortName: info.shortName) - } + case let .name(name): + stickerSet = .inputStickerSetShortName(shortName: name) + case .id: + if let (info, _, _) = cachedStickerPack(transaction: transaction, reference: packReference) { + stickerSet = .inputStickerSetShortName(shortName: info.shortName) + } + default: + stickerSet = .inputStickerSetEmpty } } result.append(.documentAttributeSticker(alt: displayText, stickerset: stickerSet)) diff --git a/submodules/TelegramCore/TelegramCore/Namespaces.swift b/submodules/TelegramCore/TelegramCore/Namespaces.swift index 76df73b2ee..367b947145 100644 --- a/submodules/TelegramCore/TelegramCore/Namespaces.swift +++ b/submodules/TelegramCore/TelegramCore/Namespaces.swift @@ -42,6 +42,7 @@ public struct Namespaces { public static let CloudStickerPacks: Int32 = 0 public static let CloudMaskPacks: Int32 = 1 public static let EmojiKeywords: Int32 = 2 + public static let CloudAnimatedEmoji: Int32 = 3 } public struct OrderedItemList { diff --git a/submodules/TelegramCore/TelegramCore/PendingMessageUploadedContent.swift b/submodules/TelegramCore/TelegramCore/PendingMessageUploadedContent.swift index c2df28501e..d4a62c5ba5 100644 --- a/submodules/TelegramCore/TelegramCore/PendingMessageUploadedContent.swift +++ b/submodules/TelegramCore/TelegramCore/PendingMessageUploadedContent.swift @@ -417,6 +417,8 @@ func inputDocumentAttributesFromFileAttributes(_ fileAttributes: [TelegramMediaF stickerSet = .inputStickerSetID(id: id, accessHash: accessHash) case let .name(name): stickerSet = .inputStickerSetShortName(shortName: name) + default: + stickerSet = .inputStickerSetEmpty } } var inputMaskCoords: Api.MaskCoords? diff --git a/submodules/TelegramCore/TelegramCore/StickerSetInstallation.swift b/submodules/TelegramCore/TelegramCore/StickerSetInstallation.swift index a22a100c4c..f1c18c9545 100644 --- a/submodules/TelegramCore/TelegramCore/StickerSetInstallation.swift +++ b/submodules/TelegramCore/TelegramCore/StickerSetInstallation.swift @@ -39,6 +39,9 @@ public func requestStickerSet(postbox: Postbox, network: Network, reference: Sti case let .id(id, accessHash): collectionId = ItemCollectionId(namespace: Namespaces.ItemCollection.CloudStickerPacks, id: id) input = .inputStickerSetID(id: id, accessHash: accessHash) + case .animatedEmoji: + collectionId = nil + input = .inputStickerSetAnimatedEmoji } let localSignal: (ItemCollectionId) -> Signal<(ItemCollectionInfo, [ItemCollectionItem])?, NoError> = { collectionId in diff --git a/submodules/TelegramCore/TelegramCore/SynchronizeSavedStickersOperation.swift b/submodules/TelegramCore/TelegramCore/SynchronizeSavedStickersOperation.swift index 7e985d73da..284361edd5 100644 --- a/submodules/TelegramCore/TelegramCore/SynchronizeSavedStickersOperation.swift +++ b/submodules/TelegramCore/TelegramCore/SynchronizeSavedStickersOperation.swift @@ -128,6 +128,8 @@ public func addSavedSticker(postbox: Postbox, network: Network, file: TelegramMe if !found { fetchReference = packReference } + case .animatedEmoji: + break } if let fetchReference = fetchReference { return network.request(Api.functions.messages.getStickerSet(stickerset: fetchReference.apiInputStickerSet)) diff --git a/submodules/TelegramCore/TelegramCore/TelegramMediaFile.swift b/submodules/TelegramCore/TelegramCore/TelegramMediaFile.swift index 57b2b4297e..b475a37ca9 100644 --- a/submodules/TelegramCore/TelegramCore/TelegramMediaFile.swift +++ b/submodules/TelegramCore/TelegramCore/TelegramMediaFile.swift @@ -20,6 +20,7 @@ private let typeHasLinkedStickers: Int32 = 6 public enum StickerPackReference: PostboxCoding, Hashable, Equatable { case id(id: Int64, accessHash: Int64) case name(String) + case animatedEmoji public init(decoder: PostboxDecoder) { switch decoder.decodeInt32ForKey("r", orElse: 0) { @@ -27,6 +28,8 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable { self = .id(id: decoder.decodeInt64ForKey("i", orElse: 0), accessHash: decoder.decodeInt64ForKey("h", orElse: 0)) case 1: self = .name(decoder.decodeStringForKey("n", orElse: "")) + case 2: + self = .animatedEmoji default: self = .name("") assertionFailure() @@ -42,6 +45,8 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable { case let .name(name): encoder.encodeInt32(1, forKey: "r") encoder.encodeString(name, forKey: "n") + case .animatedEmoji: + encoder.encodeInt32(2, forKey: "r") } } @@ -59,6 +64,12 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable { } else { return false } + case .animatedEmoji: + if case .animatedEmoji = rhs { + return true + } else { + return false + } } } } @@ -510,6 +521,8 @@ extension StickerPackReference { self = .id(id: id, accessHash: accessHash) case let .inputStickerSetShortName(shortName): self = .name(shortName) + case .inputStickerSetAnimatedEmoji: + self = .animatedEmoji } } } From dded7c451a9b281f4e36baaf9ea1d902534eef65 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 31 Jul 2019 00:27:23 +0300 Subject: [PATCH 10/41] Cloud animated emojis --- .../TelegramCore/TelegramCore/Account.swift | 2 +- .../ManagedAnimatedEmojiUpdates.swift | 24 ++++++++ .../project.pbxproj | 4 ++ .../TelegramUI/AnimatedStickerUtils.swift | 22 ------- .../ChatHistoryEntriesForView.swift | 17 ++++-- .../TelegramUI/ChatHistoryEntry.swift | 34 ++++++++--- .../TelegramUI/ChatHistoryGridNode.swift | 3 +- .../TelegramUI/ChatHistoryListNode.swift | 26 +++++++-- .../ChatMessageAnimatedStickerItemNode.swift | 58 ++++++++++--------- .../TelegramUI/ChatMessageItem.swift | 8 ++- .../ChatMessageStickerItemNode.swift | 8 +-- .../ChatRecentActionsHistoryTransition.swift | 56 +++++++++--------- .../TelegramUI/EmojiResources.swift | 34 ++++++----- .../ForwardPrivacyChatPreviewItem.swift | 2 +- .../TelegramUI/TelegramUI/MessageUtils.swift | 8 --- .../ThemePreviewControllerNode.swift | 10 ++-- .../ThemeSettingsChatPreviewItem.swift | 4 +- .../WallpaperGalleryController.swift | 4 +- 18 files changed, 188 insertions(+), 136 deletions(-) create mode 100644 submodules/TelegramCore/TelegramCore/ManagedAnimatedEmojiUpdates.swift diff --git a/submodules/TelegramCore/TelegramCore/Account.swift b/submodules/TelegramCore/TelegramCore/Account.swift index 6b0ca3fc4a..bdf726a392 100644 --- a/submodules/TelegramCore/TelegramCore/Account.swift +++ b/submodules/TelegramCore/TelegramCore/Account.swift @@ -1303,8 +1303,8 @@ public class Account { self.managedOperationsDisposable.add(managedLocalizationUpdatesOperations(accountManager: accountManager, postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedPendingPeerNotificationSettings(postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedSynchronizeAppLogEventsOperations(postbox: self.postbox, network: self.network).start()) - self.managedOperationsDisposable.add(managedNotificationSettingsBehaviors(postbox: self.postbox).start()) + self.managedOperationsDisposable.add(managedAnimatedEmojiUpdates(postbox: self.postbox, network: self.network).start()) let mediaBox = postbox.mediaBox self.storageSettingsDisposable = accountManager.sharedData(keys: [SharedDataKeys.cacheStorageSettings]).start(next: { [weak mediaBox] sharedData in diff --git a/submodules/TelegramCore/TelegramCore/ManagedAnimatedEmojiUpdates.swift b/submodules/TelegramCore/TelegramCore/ManagedAnimatedEmojiUpdates.swift new file mode 100644 index 0000000000..4083e8209f --- /dev/null +++ b/submodules/TelegramCore/TelegramCore/ManagedAnimatedEmojiUpdates.swift @@ -0,0 +1,24 @@ +import Foundation +#if os(macOS) +import PostboxMac +import SwiftSignalKitMac +import MtProtoKitMac +import TelegramApiMac +#else +import Postbox +import SwiftSignalKit +import TelegramApi +#if BUCK +import MtProtoKit +#else +import MtProtoKitDynamic +#endif +#endif + +func managedAnimatedEmojiUpdates(postbox: Postbox, network: Network) -> Signal { + let poll = loadedStickerPack(postbox: postbox, network: network, reference: .animatedEmoji, forceActualized: false) + |> mapToSignal { _ -> Signal in + return .complete() + } + return (poll |> then(.complete() |> suspendAwareDelay(2.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart +} diff --git a/submodules/TelegramCore/TelegramCore_Xcode.xcodeproj/project.pbxproj b/submodules/TelegramCore/TelegramCore_Xcode.xcodeproj/project.pbxproj index 8c1f72db21..5cdbd6676f 100644 --- a/submodules/TelegramCore/TelegramCore_Xcode.xcodeproj/project.pbxproj +++ b/submodules/TelegramCore/TelegramCore_Xcode.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 09028386218E5DBB0067EFBD /* ManagedVoipConfigurationUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09028385218E5DBB0067EFBD /* ManagedVoipConfigurationUpdates.swift */; }; 090E778322A9862100CD99F5 /* ChannelOwnershipTransfer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090E778222A9862100CD99F5 /* ChannelOwnershipTransfer.swift */; }; 090E779022AAABC600CD99F5 /* PeersNearby.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090E778F22AAABC600CD99F5 /* PeersNearby.swift */; }; + 0925903722F0D02D003D6283 /* ManagedAnimatedEmojiUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0925903622F0D02D003D6283 /* ManagedAnimatedEmojiUpdates.swift */; }; 093857A82243D87900EB6A54 /* ManagedSynchronizeEmojiKeywordsOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 093857A62243D87800EB6A54 /* ManagedSynchronizeEmojiKeywordsOperations.swift */; }; 093857A92243D87900EB6A54 /* SynchronizeEmojiKeywordsOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 093857A72243D87900EB6A54 /* SynchronizeEmojiKeywordsOperation.swift */; }; 093857AB2243D88D00EB6A54 /* EmojiKeywords.swift in Sources */ = {isa = PBXBuildFile; fileRef = 093857AA2243D88C00EB6A54 /* EmojiKeywords.swift */; }; @@ -827,6 +828,7 @@ 09028385218E5DBB0067EFBD /* ManagedVoipConfigurationUpdates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedVoipConfigurationUpdates.swift; sourceTree = ""; }; 090E778222A9862100CD99F5 /* ChannelOwnershipTransfer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelOwnershipTransfer.swift; sourceTree = ""; }; 090E778F22AAABC600CD99F5 /* PeersNearby.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeersNearby.swift; sourceTree = ""; }; + 0925903622F0D02D003D6283 /* ManagedAnimatedEmojiUpdates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedAnimatedEmojiUpdates.swift; sourceTree = ""; }; 093857A62243D87800EB6A54 /* ManagedSynchronizeEmojiKeywordsOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizeEmojiKeywordsOperations.swift; sourceTree = ""; }; 093857A72243D87900EB6A54 /* SynchronizeEmojiKeywordsOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizeEmojiKeywordsOperation.swift; sourceTree = ""; }; 093857AA2243D88C00EB6A54 /* EmojiKeywords.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmojiKeywords.swift; sourceTree = ""; }; @@ -1582,6 +1584,7 @@ 093857A62243D87800EB6A54 /* ManagedSynchronizeEmojiKeywordsOperations.swift */, D0CA8E4A227209C4008A74C3 /* ManagedSynchronizeGroupMessageStats.swift */, D06CA13422772EB20094E707 /* ManagedNotificationSettingsBehaviors.swift */, + 0925903622F0D02D003D6283 /* ManagedAnimatedEmojiUpdates.swift */, ); name = State; sourceTree = ""; @@ -2351,6 +2354,7 @@ D00D34421E6EDD2E0057B307 /* ManagedSynchronizeConsumeMessageContentsOperations.swift in Sources */, D08984FB2118816A00918162 /* Reachability.m in Sources */, D0DA1D321F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift in Sources */, + 0925903722F0D02D003D6283 /* ManagedAnimatedEmojiUpdates.swift in Sources */, D099D7491EEF418D00A3128C /* HistoryViewChannelStateValidation.swift in Sources */, C23BC3871E9BE3CA00D79F92 /* ImportContact.swift in Sources */, D0D376E622DCCFD600FA7D7C /* SlowMode.swift in Sources */, diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift index d3d6ad1502..60af58a4e5 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift @@ -321,25 +321,3 @@ func fetchLocalBundleResource(postbox: Postbox, resource: LocalBundleResource) - return EmptyDisposable } } - -private let emojis: [String: (String, CGFloat)] = [ - "👍": ("thumbs_up_1", 450.0), - "👍🏻": ("thumbs_up_2", 450.0), - "👍🏼": ("thumbs_up_3", 450.0), - "👍🏽": ("thumbs_up_4", 450.0), - "👍🏾": ("thumbs_up_5", 450.0), - "👍🏿": ("thumbs_up_6", 450.0), - "😂": ("lol", 350.0), - "😒": ("meh", 350.0), - "❤️": ("heart", 350.0), - "🥳": ("celeb", 430.0), - "😳": ("confused", 350.0) -] - -func animatedEmojiResource(emoji: String) -> (LocalBundleResource, CGFloat)? { - if let (name, size) = emojis[emoji] { - return (LocalBundleResource(name: name, ext: "tgs"), size) - } else { - return nil - } -} diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryEntriesForView.swift index 8a6185d5ec..50b44fc043 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryEntriesForView.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryEntriesForView.swift @@ -2,7 +2,7 @@ import Foundation import Postbox import TelegramCore -func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, includeUnreadEntry: Bool, includeEmptyEntry: Bool, includeChatInfoEntry: Bool, includeSearchEntry: Bool, reverse: Bool, groupMessages: Bool, selectedMessages: Set?, presentationData: ChatPresentationData, historyAppearsCleared: Bool) -> [ChatHistoryEntry] { +func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, includeUnreadEntry: Bool, includeEmptyEntry: Bool, includeChatInfoEntry: Bool, includeSearchEntry: Bool, reverse: Bool, groupMessages: Bool, selectedMessages: Set?, presentationData: ChatPresentationData, historyAppearsCleared: Bool, associatedData: ChatMessageItemAssociatedData) -> [ChatHistoryEntry] { if historyAppearsCleared { return [] } @@ -36,6 +36,15 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, if let author = entry.message.author { adminRank = adminRanks[author.id] } + + var contentTypeHint: ChatMessageEntryContentType = .generic + if presentationData.largeEmoji { + if let _ = associatedData.animatedEmojiStickers[entry.message.text.trimmedEmoji] { + contentTypeHint = .animatedEmoji + } else if messageIsElligibleForLargeEmoji(entry.message) { + contentTypeHint = .largeEmoji + } + } if groupMessages { if !groupBucket.isEmpty && entry.message.groupInfo != groupBucket[0].0.groupInfo { @@ -49,7 +58,7 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, } else { selection = .none } - groupBucket.append((entry.message, entry.isRead, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact))) + groupBucket.append((entry.message, entry.isRead, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint))) } else { let selection: ChatHistoryMessageSelection if let selectedMessages = selectedMessages { @@ -57,7 +66,7 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, } else { selection = .none } - entries.append(.MessageEntry(entry.message, presentationData, entry.isRead, entry.monthLocation, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact))) + entries.append(.MessageEntry(entry.message, presentationData, entry.isRead, entry.monthLocation, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint))) } } else { let selection: ChatHistoryMessageSelection @@ -66,7 +75,7 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, } else { selection = .none } - entries.append(.MessageEntry(entry.message, presentationData, entry.isRead, entry.monthLocation, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact))) + entries.append(.MessageEntry(entry.message, presentationData, entry.isRead, entry.monthLocation, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint))) } } diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryEntry.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryEntry.swift index f6e80d0e50..5bd86c2ab5 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryEntry.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryEntry.swift @@ -24,9 +24,28 @@ public enum ChatHistoryMessageSelection: Equatable { } } +public enum ChatMessageEntryContentType { + case generic + case largeEmoji + case animatedEmoji +} + public struct ChatMessageEntryAttributes: Equatable { let rank: CachedChannelAdminRank? let isContact: Bool + let contentTypeHint: ChatMessageEntryContentType + + init(rank: CachedChannelAdminRank?, isContact: Bool, contentTypeHint: ChatMessageEntryContentType) { + self.rank = rank + self.isContact = isContact + self.contentTypeHint = contentTypeHint + } + + public init() { + self.rank = nil + self.isContact = false + self.contentTypeHint = .generic + } } enum ChatHistoryEntry: Identifiable, Comparable { @@ -38,16 +57,17 @@ enum ChatHistoryEntry: Identifiable, Comparable { var stableId: UInt64 { switch self { - case let .MessageEntry(message, presentationData, _, _, _, _): - var type = 2 - if presentationData.largeEmoji && message.elligibleForLargeEmoji && messageIsElligibleForLargeEmoji(message) { - if animatedEmojiResource(emoji: message.text) != nil { + case let .MessageEntry(message, _, _, _, _, attributes): + let type: UInt64 + switch attributes.contentTypeHint { + case .generic: + type = 2 + case .largeEmoji: type = 3 - } else { + case .animatedEmoji: type = 4 - } } - return UInt64(message.stableId) | ((UInt64(type) << 40)) + return UInt64(message.stableId) | ((type << 40)) case let .MessageGroupEntry(groupInfo, _, _): return UInt64(groupInfo.stableId) | ((UInt64(2) << 40)) case .UnreadEntry: diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryGridNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryGridNode.swift index 02a771d8f6..8b92fce4e7 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryGridNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryGridNode.swift @@ -301,7 +301,8 @@ public final class ChatHistoryGridNode: GridNode, ChatHistoryNode { } } - let processedView = ChatHistoryView(originalView: view, filteredEntries: chatHistoryEntriesForView(location: .peer(peerId), view: view, includeUnreadEntry: false, includeEmptyEntry: false, includeChatInfoEntry: false, includeSearchEntry: false, reverse: false, groupMessages: false, selectedMessages: nil, presentationData: chatPresentationData, historyAppearsCleared: false), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: false), id: id) + let associatedData = ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: false) + let processedView = ChatHistoryView(originalView: view, filteredEntries: chatHistoryEntriesForView(location: .peer(peerId), view: view, includeUnreadEntry: false, includeEmptyEntry: false, includeChatInfoEntry: false, includeSearchEntry: false, reverse: false, groupMessages: false, selectedMessages: nil, presentationData: chatPresentationData, historyAppearsCleared: false, associatedData: associatedData), associatedData: associatedData, id: id) let previous = previousView.swap(processedView) let rawTransition = preparedChatHistoryViewTransition(from: previous, to: processedView, reason: reason, reverse: false, chatLocation: .peer(peerId), controllerInteraction: controllerInteraction, scrollPosition: scrollPosition, initialData: nil, keyboardButtonsMessage: nil, cachedData: nil, cachedDataMessages: nil, readStateData: nil, flashIndicators: flashIndicators) diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift index 3a3c40bfea..283150d331 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift @@ -253,7 +253,7 @@ private final class ChatHistoryTransactionOpaqueState { } } -private func extractAssociatedData(chatLocation: ChatLocation, view: MessageHistoryView, automaticDownloadNetworkType: MediaAutoDownloadNetworkType) -> ChatMessageItemAssociatedData { +private func extractAssociatedData(chatLocation: ChatLocation, view: MessageHistoryView, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, animatedEmojiStickers: [String: StickerPackItem]) -> ChatMessageItemAssociatedData { var automaticMediaDownloadPeerType: MediaAutoDownloadPeerType = .channel var contactsPeerIds: Set = Set() if case let .peer(peerId) = chatLocation { @@ -292,7 +292,7 @@ private func extractAssociatedData(chatLocation: ChatLocation, view: MessageHist } } } - let associatedData = ChatMessageItemAssociatedData(automaticDownloadPeerType: automaticMediaDownloadPeerType, automaticDownloadNetworkType: automaticDownloadNetworkType, isRecentActions: false, contactsPeerIds: contactsPeerIds) + let associatedData = ChatMessageItemAssociatedData(automaticDownloadPeerType: automaticMediaDownloadPeerType, automaticDownloadNetworkType: automaticDownloadNetworkType, isRecentActions: false, contactsPeerIds: contactsPeerIds, animatedEmojiStickers: animatedEmojiStickers) return associatedData } @@ -517,11 +517,27 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } |> distinctUntilChanged + let animatedEmojiStickers = loadedStickerPack(postbox: context.account.postbox, network: context.account.network, reference: .animatedEmoji, forceActualized: false) + |> map { result -> [String: StickerPackItem] in + switch result { + case let .result(_, items, _): + var animatedEmojiStickers: [String: StickerPackItem] = [:] + for case let item as StickerPackItem in items { + if let emoji = item.getStringRepresentationsOfIndexKeys().first { + animatedEmojiStickers[emoji] = item + } + } + return animatedEmojiStickers + default: + return [:] + } + } + let previousHistoryAppearsCleared = Atomic(value: nil) let nextTransitionVersion = Atomic(value: 0) - let historyViewTransitionDisposable = combineLatest(queue: messageViewQueue, historyViewUpdate, self.chatPresentationDataPromise.get(), selectedMessages, automaticDownloadNetworkType, self.historyAppearsClearedPromise.get()).start(next: { [weak self] update, chatPresentationData, selectedMessages, networkType, historyAppearsCleared in + let historyViewTransitionDisposable = combineLatest(queue: messageViewQueue, historyViewUpdate, self.chatPresentationDataPromise.get(), selectedMessages, automaticDownloadNetworkType, self.historyAppearsClearedPromise.get(), animatedEmojiStickers).start(next: { [weak self] update, chatPresentationData, selectedMessages, networkType, historyAppearsCleared, animatedEmojiStickers in func applyHole() { Queue.mainQueue().async { if let strongSelf = self { @@ -590,9 +606,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { reverse = reverseValue } - let associatedData = extractAssociatedData(chatLocation: chatLocation, view: view, automaticDownloadNetworkType: networkType) + let associatedData = extractAssociatedData(chatLocation: chatLocation, view: view, automaticDownloadNetworkType: networkType, animatedEmojiStickers: animatedEmojiStickers) - let processedView = ChatHistoryView(originalView: view, filteredEntries: chatHistoryEntriesForView(location: chatLocation, view: view, includeUnreadEntry: mode == .bubbles, includeEmptyEntry: mode == .bubbles && tagMask == nil, includeChatInfoEntry: mode == .bubbles, includeSearchEntry: includeSearchEntry && tagMask != nil, reverse: reverse, groupMessages: mode == .bubbles, selectedMessages: selectedMessages, presentationData: chatPresentationData, historyAppearsCleared: historyAppearsCleared), associatedData: associatedData, id: id) + let processedView = ChatHistoryView(originalView: view, filteredEntries: chatHistoryEntriesForView(location: chatLocation, view: view, includeUnreadEntry: mode == .bubbles, includeEmptyEntry: mode == .bubbles && tagMask == nil, includeChatInfoEntry: mode == .bubbles, includeSearchEntry: includeSearchEntry && tagMask != nil, reverse: reverse, groupMessages: mode == .bubbles, selectedMessages: selectedMessages, presentationData: chatPresentationData, historyAppearsCleared: historyAppearsCleared, associatedData: associatedData), associatedData: associatedData, id: id) let previousValueAndVersion = previousView.swap((processedView, update.1)) let previous = previousValueAndVersion?.0 diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index 37c42a991c..efd89e9c7c 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -27,7 +27,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { private var shareButtonNode: HighlightableButtonNode? var telegramFile: TelegramMediaFile? - var emojiResource: LocalBundleResource? + var emojiFile: TelegramMediaFile? private let disposable = MetaDisposable() private var viaBotNode: TextNode? @@ -137,12 +137,11 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } if self.telegramFile == nil { - self.emojiResource = animatedEmojiResource(emoji: item.message.text)?.0 + self.emojiFile = item.associatedData.animatedEmojiStickers[item.message.text.trimmedEmoji]?.file - if let emojiResource = self.emojiResource { - let dummyFile = TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: emojiResource, previewRepresentations: [], immediateThumbnailData: nil, mimeType: "", size: 0, attributes: []) - self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, file: dummyFile, small: false, size: CGSize(width: 384.0, height: 384.0), thumbnail: false)) - self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, fileReference: .message(message: MessageReference(item.message), media: dummyFile)).start()) + if let emojiFile = self.emojiFile { + self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, file: emojiFile, small: false, size: CGSize(width: 384.0, height: 384.0), thumbnail: false)) + self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, fileReference: .message(message: MessageReference(item.message), media: emojiFile)).start()) } self.updateVisibility() @@ -160,28 +159,26 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { self.animationNode.visibility = isPlaying if self.isPlaying && !self.didSetUpAnimationNode { self.didSetUpAnimationNode = true - var telegramFile: TelegramMediaFile? - for media in item.message.media { - if let file = media as? TelegramMediaFile { - telegramFile = file - break - } - } - - if let telegramFile = telegramFile { - var playbackMode: AnimatedStickerPlaybackMode = .loop + + var file: TelegramMediaFile? + var playbackMode: AnimatedStickerPlaybackMode = .loop + + if let telegramFile = self.telegramFile { + file = telegramFile if !item.controllerInteraction.stickerSettings.loopAnimatedStickers { playbackMode = .once } - let dimensions = telegramFile.dimensions ?? CGSize(width: 512.0, height: 512.0) - let fittedSize = dimensions.aspectFitted(CGSize(width: 384.0, height: 384.0)) - self.animationNode.setup(account: item.context.account, resource: telegramFile.resource, width: Int(fittedSize.width), height: Int(fittedSize.height), playbackMode: playbackMode, mode: .cached) - } else if let emojiResource = self.emojiResource { - var playbackMode: AnimatedStickerPlaybackMode = .loop + } else if let emojiFile = self.emojiFile { + file = emojiFile if item.context.sharedContext.immediateExperimentalUISettings.playAnimatedEmojiOnce { playbackMode = .once } - self.animationNode.setup(account: item.context.account, resource: emojiResource, width: 384, height: 384, playbackMode: playbackMode, mode: .cached) + } + + if let file = file { + let dimensions = file.dimensions ?? CGSize(width: 512.0, height: 512.0) + let fittedSize = dimensions.aspectFitted(CGSize(width: 384.0, height: 384.0)) + self.animationNode.setup(account: item.context.account, resource: file.resource, width: Int(fittedSize.width), height: Int(fittedSize.height), playbackMode: playbackMode, mode: .cached) } } } @@ -194,6 +191,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { override func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, Bool) -> Void) { let displaySize = CGSize(width: 184.0, height: 184.0) let telegramFile = self.telegramFile + let emojiFile = self.emojiFile let layoutConstants = self.layoutConstants let imageLayout = self.imageNode.asyncLayout() let makeDateAndStatusLayout = self.dateAndStatusNode.asyncLayout() @@ -215,10 +213,14 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } else if let thumbnailSize = telegramFile.previewRepresentations.first?.dimensions { imageSize = thumbnailSize.aspectFitted(displaySize) } - } else { - if let (_, size) = animatedEmojiResource(emoji: item.message.text) { - imageSize = CGSize(width: floor(displaySize.width * size / 512.0), height: floor(displaySize.height * size / 512.0)) - isEmoji = true + } else if let emojiFile = emojiFile { + isEmoji = true + + let displaySize = CGSize(width: floor(displaySize.width * 350.0 / 512.0), height: floor(displaySize.height * 350.0 / 512.0)) + if let dimensions = emojiFile.dimensions { + imageSize = dimensions.aspectFitted(displaySize) + } else if let thumbnailSize = emojiFile.previewRepresentations.first?.dimensions { + imageSize = thumbnailSize.aspectFitted(displaySize) } } @@ -657,12 +659,12 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if let item = self.item, self.imageNode.frame.contains(location) { if self.telegramFile != nil { let _ = item.controllerInteraction.openMessage(item.message, .default) - } else if let emoji = self.emojiResource { + } else if let _ = self.emojiFile { if item.context.sharedContext.immediateExperimentalUISettings.playAnimatedEmojiOnce { self.animationNode.playIfNeeded() } - if emoji.name == "heart" { + if self.item?.message.text == "❤️" { let hapticFeedback: HapticFeedback if let currentHapticFeedback = self.hapticFeedback { hapticFeedback = currentHapticFeedback diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift index 60348ff52f..c18041ac90 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift @@ -212,13 +212,15 @@ public final class ChatMessageItemAssociatedData: Equatable { let automaticDownloadNetworkType: MediaAutoDownloadNetworkType let isRecentActions: Bool let contactsPeerIds: Set + let animatedEmojiStickers: [String: StickerPackItem] let forcedResourceStatus: FileMediaResourceStatus? - init(automaticDownloadPeerType: MediaAutoDownloadPeerType, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, isRecentActions: Bool, contactsPeerIds: Set = Set(), forcedResourceStatus: FileMediaResourceStatus? = nil) { + init(automaticDownloadPeerType: MediaAutoDownloadPeerType, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, isRecentActions: Bool, contactsPeerIds: Set = Set(), animatedEmojiStickers: [String: StickerPackItem] = [:], forcedResourceStatus: FileMediaResourceStatus? = nil) { self.automaticDownloadPeerType = automaticDownloadPeerType self.automaticDownloadNetworkType = automaticDownloadNetworkType self.isRecentActions = isRecentActions self.contactsPeerIds = contactsPeerIds + self.animatedEmojiStickers = animatedEmojiStickers self.forcedResourceStatus = forcedResourceStatus } @@ -384,8 +386,8 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { } } - if viewClassName == ChatMessageBubbleItemNode.self && self.presentationData.largeEmoji && self.message.elligibleForLargeEmoji && messageIsElligibleForLargeEmoji(self.message) { - if let _ = animatedEmojiResource(emoji: self.message.text) { + if viewClassName == ChatMessageBubbleItemNode.self && self.presentationData.largeEmoji && messageIsElligibleForLargeEmoji(self.message) { + if let _ = self.associatedData.animatedEmojiStickers[self.message.text.trimmedEmoji] { viewClassName = ChatMessageAnimatedStickerItemNode.self } else { viewClassName = ChatMessageStickerItemNode.self diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift index 35b8a0d58e..f21455166f 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift @@ -65,7 +65,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { return .fail } - if let item = strongSelf.item, item.presentationData.largeEmoji && item.message.elligibleForLargeEmoji { + if let item = strongSelf.item, item.presentationData.largeEmoji && messageIsElligibleForLargeEmoji(item.message) { if strongSelf.imageNode.frame.contains(point) { return .waitForDoubleTap } @@ -104,7 +104,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { } } - if self.telegramFile == nil && item.presentationData.largeEmoji && item.message.elligibleForLargeEmoji { + if self.telegramFile == nil && item.presentationData.largeEmoji && messageIsElligibleForLargeEmoji(item.message) { self.imageNode.setSignal(largeEmoji(postbox: item.context.account.postbox, emoji: item.message.text)) } } @@ -137,7 +137,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { var textLayoutAndApply: (TextNodeLayout, () -> TextNode)? var isEmoji = false - if item.presentationData.largeEmoji && item.message.elligibleForLargeEmoji { + if item.presentationData.largeEmoji && messageIsElligibleForLargeEmoji(item.message) { let attributedText = NSAttributedString(string: item.message.text, font: item.presentationData.messageEmojiFont1, textColor: .black) textLayoutAndApply = textLayout(TextNodeLayoutArguments(attributedString: attributedText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: 180.0, height: 90.0), alignment: .natural)) @@ -735,7 +735,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { let incoming = item.message.effectivelyIncoming(item.context.account.peerId) var isEmoji = false - if let item = self.item, item.presentationData.largeEmoji && item.message.elligibleForLargeEmoji { + if let item = self.item, item.presentationData.largeEmoji && messageIsElligibleForLargeEmoji(item.message) { isEmoji = true } diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift index 1134668b78..85c0d4b7cc 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift @@ -116,7 +116,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.titleUpdated(title: new) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .changeAbout(prev, new): var peers = SimpleDictionary() var author: Peer? @@ -147,14 +147,14 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case .content: let peers = SimpleDictionary() let attributes: [MessageAttribute] = [] let prevMessage = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prev, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: new, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), additionalContent: !prev.isEmpty ? .eventLogPreviousDescription(prevMessage) : nil) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()), additionalContent: !prev.isEmpty ? .eventLogPreviousDescription(prevMessage) : nil) } case let .changeUsername(prev, new): var peers = SimpleDictionary() @@ -185,7 +185,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action: TelegramMediaActionType = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case .content: var previousAttributes: [MessageAttribute] = [] var attributes: [MessageAttribute] = [] @@ -204,7 +204,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let prevMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prevText, attributes: previousAttributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), additionalContent: !prev.isEmpty ? .eventLogPreviousLink(prevMessage) : nil) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()), additionalContent: !prev.isEmpty ? .eventLogPreviousLink(prevMessage) : nil) } case let .changePhoto(_, new): var peers = SimpleDictionary() @@ -222,7 +222,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.photoUpdated(image: photo) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .toggleInvites(value): var peers = SimpleDictionary() var author: Peer? @@ -249,7 +249,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .toggleSignatures(value): var peers = SimpleDictionary() var author: Peer? @@ -276,7 +276,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .updatePinned(message): switch self.id.contentIndex { case .header: @@ -300,7 +300,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case .content: if let message = message { var peers = SimpleDictionary() @@ -318,7 +318,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) } else { var peers = SimpleDictionary() var author: Peer? @@ -340,7 +340,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 0), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) } } case let .editMessage(prev, message): @@ -385,7 +385,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case .content: var peers = SimpleDictionary() var attributes: [MessageAttribute] = [] @@ -402,7 +402,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), additionalContent: !prev.text.isEmpty || !message.text.isEmpty ? .eventLogPreviousMessage(filterOriginalMessageFlags(prev)) : nil) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), additionalContent: !prev.text.isEmpty || !message.text.isEmpty ? .eventLogPreviousMessage(filterOriginalMessageFlags(prev)) : nil) } case let .deleteMessage(message): switch self.id.contentIndex { @@ -428,7 +428,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case .content: var peers = SimpleDictionary() var attributes: [MessageAttribute] = [] @@ -452,7 +452,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) } case .participantJoin, .participantLeave: var peers = SimpleDictionary() @@ -470,7 +470,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { action = TelegramMediaActionType.removedMembers(peerIds: [self.entry.event.peerId]) } let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .participantInvite(participant): var peers = SimpleDictionary() var author: Peer? @@ -487,7 +487,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action: TelegramMediaActionType action = TelegramMediaActionType.addedMembers(peerIds: [participant.peer.id]) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .participantToggleBan(prev, new): var peers = SimpleDictionary() var attributes: [MessageAttribute] = [] @@ -617,7 +617,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .participantToggleAdmin(prev, new): var peers = SimpleDictionary() var attributes: [MessageAttribute] = [] @@ -753,7 +753,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .changeStickerPack(_, new): var peers = SimpleDictionary() var author: Peer? @@ -782,7 +782,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .togglePreHistoryHidden(value): var peers = SimpleDictionary() var author: Peer? @@ -812,7 +812,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .updateDefaultBannedRights(prev, new): var peers = SimpleDictionary() var attributes: [MessageAttribute] = [] @@ -870,7 +870,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .pollStopped(message): switch self.id.contentIndex { case .header: @@ -898,7 +898,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case .content: var peers = SimpleDictionary() var attributes: [MessageAttribute] = [] @@ -915,7 +915,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.author, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), additionalContent: nil) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), additionalContent: nil) } case let .linkedPeerUpdated(previous, updated): var peers = SimpleDictionary() @@ -971,7 +971,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) case let .changeGeoLocation(_, updated): var peers = SimpleDictionary() var author: Peer? @@ -993,12 +993,12 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let mediaMap = TelegramMediaMap(latitude: updated.latitude, longitude: updated.longitude, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: [], media: [mediaMap], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) } else { let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) } case let .updateSlowmode(_, newValue): var peers = SimpleDictionary() @@ -1029,7 +1029,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) - return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false))) + return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes())) } } } diff --git a/submodules/TelegramUI/TelegramUI/EmojiResources.swift b/submodules/TelegramUI/TelegramUI/EmojiResources.swift index e908b3f2f4..fe625d7d09 100644 --- a/submodules/TelegramUI/TelegramUI/EmojiResources.swift +++ b/submodules/TelegramUI/TelegramUI/EmojiResources.swift @@ -198,25 +198,29 @@ private func matchingEmojiEntry(_ emoji: String) -> (UInt8, UInt8, UInt8)? { } func messageIsElligibleForLargeEmoji(_ message: Message) -> Bool { - var messageEntities: [MessageTextEntity]? - for attribute in message.attributes { - if let attribute = attribute as? TextEntitiesMessageAttribute { - messageEntities = attribute.entities - break + if message.media.isEmpty && !message.text.isEmpty && message.text.containsOnlyEmoji && message.text.emojis.count < 4 { + var messageEntities: [MessageTextEntity]? + for attribute in message.attributes { + if let attribute = attribute as? TextEntitiesMessageAttribute { + messageEntities = attribute.entities + break + } } - } - - if !(messageEntities?.isEmpty ?? true) { - return false - } - - for emoji in message.text.emojis { - if let _ = matchingEmojiEntry(emoji) { - } else { + + if !(messageEntities?.isEmpty ?? true) { return false } + + for emoji in message.text.emojis { + if let _ = matchingEmojiEntry(emoji) { + } else { + return false + } + } + return true + } else { + return false } - return true } func largeEmoji(postbox: Postbox, emoji: String, outline: Bool = true) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { diff --git a/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift b/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift index a4434d9d4c..3b9f33015d 100644 --- a/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift +++ b/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift @@ -150,7 +150,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode { let chatPresentationData = ChatPresentationData(theme: ChatPresentationThemeData(theme: item.theme, wallpaper: item.wallpaper), fontSize: item.fontSize, strings: item.strings, dateTimeFormat: item.dateTimeFormat, nameDisplayOrder: item.nameDisplayOrder, disableAnimations: false, largeEmoji: false) - let messageItem = ChatMessageItem(presentationData: chatPresentationData, context: item.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: forwardInfo, author: nil, text: item.strings.Privacy_Forwards_PreviewMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: true) + let messageItem = ChatMessageItem(presentationData: chatPresentationData, context: item.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: forwardInfo, author: nil, text: item.strings.Privacy_Forwards_PreviewMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), disableDate: true) var node: ListViewItemNode? if let current = currentNode { diff --git a/submodules/TelegramUI/TelegramUI/MessageUtils.swift b/submodules/TelegramUI/TelegramUI/MessageUtils.swift index 7eef9418b4..8d2bc2bd1d 100644 --- a/submodules/TelegramUI/TelegramUI/MessageUtils.swift +++ b/submodules/TelegramUI/TelegramUI/MessageUtils.swift @@ -18,12 +18,4 @@ extension Message { return false } } - - var elligibleForLargeEmoji: Bool { - if self.media.isEmpty && !self.text.isEmpty && self.text.containsOnlyEmoji && self.text.emojis.count < 4 { - return true - } else { - return false - } - } } diff --git a/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift b/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift index 830ec39c4c..83c7c2881c 100644 --- a/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift @@ -195,18 +195,18 @@ class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { let controllerInteraction = ChatControllerInteraction.default let chatPresentationData = ChatPresentationData(theme: ChatPresentationThemeData(theme: self.previewTheme, wallpaper: self.previewTheme.chat.defaultWallpaper), fontSize: self.presentationData.fontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: false, largeEmoji: false) - items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66003, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: "", attributes: [ReplyMessageAttribute(messageId: replyMessageId)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) + items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66003, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: "", attributes: [ReplyMessageAttribute(messageId: replyMessageId)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), disableDate: false)) - items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66002, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) + items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66002, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), disableDate: false)) - items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) + items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), disableDate: false)) let voiceAttributes: [TelegramMediaFileAttribute] = [.Audio(isVoice: true, duration: 14, title: nil, performer: nil, waveform: MemoryBuffer())] let voiceMedia = TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: nil, attributes: voiceAttributes) - items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false, forcedResourceStatus: FileMediaResourceStatus(mediaStatus: .playbackStatus(.playing), fetchStatus: .Local)), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) + items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false, forcedResourceStatus: FileMediaResourceStatus(mediaStatus: .playbackStatus(.playing), fetchStatus: .Local)), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), disableDate: false)) - items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) + items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), disableDate: false)) let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right) if let messageNodes = self.messageNodes { diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift index 8f0365f202..7026fd07d7 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift @@ -129,8 +129,8 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { let chatPresentationData = ChatPresentationData(theme: ChatPresentationThemeData(theme: item.componentTheme, wallpaper: item.wallpaper), fontSize: item.fontSize, strings: item.strings, dateTimeFormat: item.dateTimeFormat, nameDisplayOrder: item.nameDisplayOrder, disableAnimations: false, largeEmoji: false) - let item2: ChatMessageItem = ChatMessageItem(presentationData: chatPresentationData, context: item.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: nil, text: item.strings.Appearance_PreviewIncomingText, attributes: [ReplyMessageAttribute(messageId: replyMessageId)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: true) - let item1: ChatMessageItem = ChatMessageItem(presentationData: chatPresentationData, context: item.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: TelegramUser(id: item.context.account.peerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []), text: item.strings.Appearance_PreviewOutgoingText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: true) + let item2: ChatMessageItem = ChatMessageItem(presentationData: chatPresentationData, context: item.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: nil, text: item.strings.Appearance_PreviewIncomingText, attributes: [ReplyMessageAttribute(messageId: replyMessageId)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), disableDate: true) + let item1: ChatMessageItem = ChatMessageItem(presentationData: chatPresentationData, context: item.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: TelegramUser(id: item.context.account.peerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []), text: item.strings.Appearance_PreviewOutgoingText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), disableDate: true) var node1: ListViewItemNode? if let current = currentNode1 { diff --git a/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift b/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift index 623f529a9d..b9dbcab722 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift @@ -609,9 +609,9 @@ class WallpaperGalleryController: ViewController { bottomMessageText = presentationData.strings.WallpaperPreview_CustomColorBottomText } - items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: bottomMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) + items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: bottomMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), disableDate: false)) - items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: topMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) + items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: topMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), disableDate: false)) let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right) if let messageNodes = self.messageNodes { From 4c32f661e0cc60a4efa69ff9ed22a6443df08c8b Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 31 Jul 2019 01:41:49 +0300 Subject: [PATCH 11/41] Animated emojis fixes --- .../TelegramUI/ChatHistoryListNode.swift | 47 +++++++++++++--- .../ChatMessageAnimatedStickerItemNode.swift | 8 ++- .../TelegramUI/ChatPresentationData.swift | 6 +- .../TelegramUI/Resources/Emoji/celeb.tgs | Bin 21630 -> 0 bytes .../TelegramUI/Resources/Emoji/confused.tgs | Bin 8073 -> 0 bytes .../TelegramUI/Resources/Emoji/heart.tgs | Bin 56207 -> 0 bytes .../TelegramUI/Resources/Emoji/lol.tgs | Bin 14119 -> 0 bytes .../TelegramUI/Resources/Emoji/meh.tgs | Bin 5604 -> 0 bytes .../Resources/Emoji/thumbs_up_1.tgs | Bin 17926 -> 0 bytes .../Resources/Emoji/thumbs_up_2.tgs | Bin 17993 -> 0 bytes .../Resources/Emoji/thumbs_up_3.tgs | Bin 17970 -> 0 bytes .../Resources/Emoji/thumbs_up_4.tgs | Bin 18003 -> 0 bytes .../Resources/Emoji/thumbs_up_5.tgs | Bin 17975 -> 0 bytes .../Resources/Emoji/thumbs_up_6.tgs | Bin 17985 -> 0 bytes .../project.pbxproj | 53 ------------------ 15 files changed, 48 insertions(+), 66 deletions(-) delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/celeb.tgs delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/confused.tgs delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/heart.tgs delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/lol.tgs delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/meh.tgs delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/thumbs_up_1.tgs delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/thumbs_up_2.tgs delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/thumbs_up_3.tgs delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/thumbs_up_4.tgs delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/thumbs_up_5.tgs delete mode 100644 submodules/TelegramUI/TelegramUI/Resources/Emoji/thumbs_up_6.tgs diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift index 283150d331..55c06eeedf 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift @@ -309,6 +309,26 @@ private extension ChatHistoryLocationInput { } } +private struct ChatHistoryAnimatedEmojiConfiguration { + static var defaultValue: ChatHistoryAnimatedEmojiConfiguration { + return ChatHistoryAnimatedEmojiConfiguration(scale: 0.625) + } + + public let scale: CGFloat + + fileprivate init(scale: CGFloat) { + self.scale = scale + } + + static func with(appConfiguration: AppConfiguration) -> ChatHistoryAnimatedEmojiConfiguration { + if let data = appConfiguration.data, let scale = data["emojies_animated_zoom"] as? Double { + return ChatHistoryAnimatedEmojiConfiguration(scale: CGFloat(scale)) + } else { + return .defaultValue + } + } +} + public final class ChatHistoryListNode: ListView, ChatHistoryNode { private let context: AccountContext private let chatLocation: ChatLocation @@ -395,7 +415,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { return self.isInteractivelyScrollingPromise.get() } - private var currentPresentationData: PresentationData + private var currentPresentationData: ChatPresentationData private var chatPresentationDataPromise: Promise private var presentationDataDisposable: Disposable? @@ -428,9 +448,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { self.controllerInteraction = controllerInteraction self.mode = mode - self.currentPresentationData = context.sharedContext.currentPresentationData.with { $0 } + let presentationData = context.sharedContext.currentPresentationData.with { $0 } + self.currentPresentationData = ChatPresentationData(theme: ChatPresentationThemeData(theme: presentationData.theme, wallpaper: presentationData.chatWallpaper), fontSize: presentationData.fontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: presentationData.disableAnimations, largeEmoji: presentationData.largeEmoji, animatedEmojiScale: 1.0) - self.chatPresentationDataPromise = Promise(ChatPresentationData(theme: ChatPresentationThemeData(theme: self.currentPresentationData.theme, wallpaper: self.currentPresentationData.chatWallpaper), fontSize: self.currentPresentationData.fontSize, strings: self.currentPresentationData.strings, dateTimeFormat: self.currentPresentationData.dateTimeFormat, nameDisplayOrder: self.currentPresentationData.nameDisplayOrder, disableAnimations: self.currentPresentationData.disableAnimations, largeEmoji: self.currentPresentationData.largeEmoji)) + self.chatPresentationDataPromise = Promise(self.currentPresentationData) self.prefetchManager = InChatPrefetchManager(context: context) @@ -735,20 +756,28 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } } - self.presentationDataDisposable = (context.sharedContext.presentationData - |> deliverOnMainQueue).start(next: { [weak self] presentationData in + let appConfiguration = context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration]) + |> take(1) + |> map { view in + return view.values[PreferencesKeys.appConfiguration] as? AppConfiguration ?? .defaultValue + } + + self.presentationDataDisposable = (combineLatest(context.sharedContext.presentationData, appConfiguration) + |> deliverOnMainQueue).start(next: { [weak self] presentationData, appConfiguration in if let strongSelf = self { let previousTheme = strongSelf.currentPresentationData.theme let previousStrings = strongSelf.currentPresentationData.strings - let previousWallpaper = strongSelf.currentPresentationData.chatWallpaper + let previousWallpaper = strongSelf.currentPresentationData.theme.wallpaper let previousDisableAnimations = strongSelf.currentPresentationData.disableAnimations + let previousAnimatedEmojiScale = strongSelf.currentPresentationData.animatedEmojiScale - strongSelf.currentPresentationData = presentationData + let animatedEmojiConfig = ChatHistoryAnimatedEmojiConfiguration.with(appConfiguration: appConfiguration) - if previousTheme !== presentationData.theme || previousStrings !== presentationData.strings || previousWallpaper != presentationData.chatWallpaper || previousDisableAnimations != presentationData.disableAnimations { + if previousTheme !== presentationData.theme || previousStrings !== presentationData.strings || previousWallpaper != presentationData.chatWallpaper || previousDisableAnimations != presentationData.disableAnimations || previousAnimatedEmojiScale != animatedEmojiConfig.scale { let themeData = ChatPresentationThemeData(theme: presentationData.theme, wallpaper: presentationData.chatWallpaper) - let chatPresentationData = ChatPresentationData(theme: themeData, fontSize: presentationData.fontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: presentationData.disableAnimations, largeEmoji: presentationData.largeEmoji) + let chatPresentationData = ChatPresentationData(theme: themeData, fontSize: presentationData.fontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: presentationData.disableAnimations, largeEmoji: presentationData.largeEmoji, animatedEmojiScale: animatedEmojiConfig.scale) + strongSelf.currentPresentationData = chatPresentationData strongSelf.dynamicBounceEnabled = !presentationData.disableAnimations strongSelf.forEachItemHeaderNode { itemHeaderNode in diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index efd89e9c7c..7f0213f6bd 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -162,6 +162,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { var file: TelegramMediaFile? var playbackMode: AnimatedStickerPlaybackMode = .loop + var isEmoji = false if let telegramFile = self.telegramFile { file = telegramFile @@ -169,6 +170,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { playbackMode = .once } } else if let emojiFile = self.emojiFile { + isEmoji = true file = emojiFile if item.context.sharedContext.immediateExperimentalUISettings.playAnimatedEmojiOnce { playbackMode = .once @@ -177,7 +179,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if let file = file { let dimensions = file.dimensions ?? CGSize(width: 512.0, height: 512.0) - let fittedSize = dimensions.aspectFitted(CGSize(width: 384.0, height: 384.0)) + let fittedSize = isEmoji ? dimensions.aspectFilled(CGSize(width: 384.0, height: 384.0)) : dimensions.aspectFitted(CGSize(width: 384.0, height: 384.0)) self.animationNode.setup(account: item.context.account, resource: file.resource, width: Int(fittedSize.width), height: Int(fittedSize.height), playbackMode: playbackMode, mode: .cached) } } @@ -216,9 +218,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } else if let emojiFile = emojiFile { isEmoji = true - let displaySize = CGSize(width: floor(displaySize.width * 350.0 / 512.0), height: floor(displaySize.height * 350.0 / 512.0)) + let displaySize = CGSize(width: floor(displaySize.width * item.presentationData.animatedEmojiScale), height: floor(displaySize.height * item.presentationData.animatedEmojiScale)) if let dimensions = emojiFile.dimensions { - imageSize = dimensions.aspectFitted(displaySize) + imageSize = dimensions.aspectFilled(displaySize) } else if let thumbnailSize = emojiFile.previewRepresentations.first?.dimensions { imageSize = thumbnailSize.aspectFitted(displaySize) } diff --git a/submodules/TelegramUI/TelegramUI/ChatPresentationData.swift b/submodules/TelegramUI/TelegramUI/ChatPresentationData.swift index 22b3e1a386..1fd121b7fc 100644 --- a/submodules/TelegramUI/TelegramUI/ChatPresentationData.swift +++ b/submodules/TelegramUI/TelegramUI/ChatPresentationData.swift @@ -86,7 +86,9 @@ public final class ChatPresentationData { let messageFixedFont: UIFont let messageBlockQuoteFont: UIFont - init(theme: ChatPresentationThemeData, fontSize: PresentationFontSize, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, disableAnimations: Bool, largeEmoji: Bool) { + let animatedEmojiScale: CGFloat + + init(theme: ChatPresentationThemeData, fontSize: PresentationFontSize, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, disableAnimations: Bool, largeEmoji: Bool, animatedEmojiScale: CGFloat = 1.0) { self.theme = theme self.fontSize = fontSize self.strings = strings @@ -105,5 +107,7 @@ public final class ChatPresentationData { self.messageBoldItalicFont = Font.semiboldItalic(baseFontSize) self.messageFixedFont = UIFont(name: "Menlo-Regular", size: baseFontSize - 1.0) ?? UIFont.systemFont(ofSize: baseFontSize) self.messageBlockQuoteFont = UIFont.systemFont(ofSize: baseFontSize - 1.0) + + self.animatedEmojiScale = animatedEmojiScale } } diff --git a/submodules/TelegramUI/TelegramUI/Resources/Emoji/celeb.tgs b/submodules/TelegramUI/TelegramUI/Resources/Emoji/celeb.tgs deleted file mode 100644 index 98e16ae51234648af845b40f4f779118eca3ad41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21630 zcmYJa18^m67p|R&&51d&ZQGjI-mz_S$F^0`O?>LC^}GIo zj42cc!`xq$R+s=C2rUsDwln(W`}fnY*XOSkNABmvqC&3sh4w@F+vAD=|Hn_2hqIer zzrPWm@8W*W1xR1-kBN&Kb6grSO7y39{5}sZ1bQAE`D_gTt!y@xMIsT>mC{UlESOFf zhJ8zq_g&~xQ$xmeSB7arhM$gB=WG1=hdJaI;!X+f7qbXb^@zFP z3sg_;!3vN@B{61ND%LP&B6t=RV!-rcjKCm`WRCX)MS3 z>3)N;CV4SJC&_-% z6V;LAcm^X!*YLrQ8yFOG*)eFeoMMk&Fl_QLT{;4LHvajo`WvQt3MI3IUhvu0udJ=- ztCR7$Tzxg7&tLQEt*~vPe%+>B&iQhIbIz?#Sj>Gg?=vUMoZ`Z0+ICp^HW#Qn01@0O z6qRP?!*EhDUYd0F&^p}bk==rOD(nlPW%AS#5dh!;$-hUx1_&`A>S>`yD3j6r*Kpy| zAQZP)^SwyAG4aXyFD>O}OV+i>cmoA)1*3Mz8ub)`SQ=p2u3-^p--=hJ*4x^dfv}Bw zTFv6we!=>Dekt(WbK}A^BZ7v6-Cjf8!j*nH!&s_uL_j)Y*k%i!L%Q)*D%o_jMROy) z!!8-H7?uENc2Z5LZm>=UR2sGb8&s33L)YAX0LQB;@zw{0vY!v@6UfH&lLi->6fpxc^een&Me8>Vs3 zy%}ECvq(1u4sG-IB#}y|b@QZJr!~51<^R2YYKASajbUh}#t6)1LXa=ejk@6XXV2l9 z|LUU}RkN!1t>aS8Cv{jqJ~S^E?$^Mnvs%l>z{XthO5 zD`~X>YdFkaAX3khF%4E8Ld56@pS_Rw-Li{pKxj3)Pg8Jrg_j-%SYwtWsiD_C|}5BtIbGU3;KZ* zx*-#nkgBJ7jt~{jFw}nN)SZ|r_4<{Rid;T0753=Vt+*=ff=4z1)Ovx`dLa`xkgAt? z6QJmM+M(3CA=H(J6Lqfkw+u4%JVv2ovr1BqF;vmC(Aqd6fVoF_CA7#}~@V-g`` zhgwaTF4*g>t2d#7flKUN2N|15qAo*p%uDWzGC4<~>_|5yfcYaxVWw#$&4qE%L^G%zzNFSEl6P3S|(RB zji>NF0du#8!Z~=aNcWaio zq-Nk3rV$yUp1slX#WKjB?FQ_+ZC3iD3ASKf=xiIK$wJ@^_+_&ta{0f8f}S?}DkWb; z2}+we-_-UZ6CLP&TcP6amWe#gEQ>SZp%2mL(rs*r*wvRZ6&t3UNQJsZ`4YS>G&g0J zFWF;eTfoa=>LUs(^(qfG>?*oQ1*|nmE)L;&^j@TjL zQ4Hz&G&f9n$5G;&4mydMrtb=g>7;NJFwYFOtj65PD9KF0lzWcjeinvPml6KCbLJSx zT=rUQTdu=Qh#PfV7107JwG(07=$h+3BiH~;t(zakK<-V2+*U%zuyGxNck!h&2}&o^ zcg+%>b6qSY8|o1ilDXu!NS&wJ=b9egv*o?DtnH1HJ|N&jR7`-Nt+}~sK~pd`?`y| z6zyjTn>R9%h_dk&1bR^7z(y_M7c6|RsuuLVg9Z-+^}Y@*h#4pqtn&IXBhbmbFl#{h z8k4_7E0I%CBYRmXKS=UVCOaHzt(^9rnz*VtMUST^@bJ9~H^b(SiKT=-^Url0V^@w* zO=O9ai|nWhf{}h78<8%fpn1IU1|lR*ln9I+F0&7L7zVx5cA!EbNukJ!)-Q)Qqh0&hIlaD(&l} zo!V=yMZks`RMkVS>@3pQZy9@jROgme*o7(X$Q#$cvL;0;u=KmrVk!*nla;&E{!{?$ zmrHtQj185>D|%}s0Rt3Ct`I0Wl(xZX!a6cb2Dy~B0`V)P?`)_yh+0i@4(fkfbRJ=MyyiOWZ$DtZ$}~}JlzCy1@CY&ufKf-Ub&Y2a(p)N zYg{xVCH))~ltdYc3>`G~yp&`|onz|qHM9?ey6-}wLvNq=_+K;0Jm_CFUWa4Rq-f?V zB7v3r!AkHz`b0DW1cH5W0hW(VOX%7tE4~icMA{_&8pla~#PHxTretsO^J$yN6 z_MQpR7JI7v5k%apXDfxbXQsPsHk}=Yi?w{b=)$2z-A#^JmU@K=sn)`U7lvaZ>9MXz z>J}eS^mPoXH(WIN3=xF)yIkYPh%5iX=TOmMQ9 z0hv1?$>1p7N+xr1g_%&dv~ML~R`H&dNtZ&2XR>+l1N%h3raSdQr6%#fYNZ-^!Q+&B z!_nrJ9~pbHS=sxl(~38?#)*EVAAU#R_TOH|KYr>S#EQ!e-hH@@ypREj zX)&G&4v`Az>cQPgP4=8UpX6{5R3Sz)g7`rPa1iD9Kl6UR5F^7s0^mVee9ggeGKxz% zz>m_0er@zdv!EKE=^#i(sRf_bXHlx9NfyFv#k2Fq$!J-Ez7GaahMm7BLZhKU>Wm{6 z{rIJlqA_JaBr?jd!XJAU<08V%QY;d1Cf)wk!#+-q{8(JMG{2<8lgxRR^u}PK9-8+L=wW?@A>LlN%?IS=Hoq5? z+8@P(kRu-B>8VRunMqB;oAVxoCmq3agZY4_o<%*rYD{8omU7Unx(thn6G{^yI6VIX zYtv7JZ&{&QYgZ>9fVYsGeOB)>_|YaL3e*v~>N#8gs z?;eIkjtB)G@2gz}A5}AwpfRHsGBw(7;<>zas$cvjvhWPOPTfrnV>JYRH&J5k(HO-g>R7*v#-+Ak>L5v-XFgYS zgVo3-0F#Qf#bwXNTwuXlH!=-pK6;nMwsFV*={lM_mVlZu<1vC0ua0)We=KsM5T%>9 z-?3Zv(Cdf5P1IAzpNZ(0$oO-msHC5`wg|t4S%oD(M``w)x8k#oV-7hTNN>^uM>0HxiN;XnPxb@H>6J|@cE&?FNvd( zW7%k!6sphOW4nAIc^jjVkEL)iqDqRowP^;vfuTS5~OCy0*0$k`ScgNm@T4uZIT%?AyAf`gGQ>tSaXWqs@IGAe3*| z6w03uu5(Bpk)cA}pL9DsO}2P*f&-gurdyz|G`C(~^9|UxN60jN97o|whb{x2Nj_O> zEBH(})|wfakYnr9gCd=6yX&|5;x=^p47#6^qS}o>{0?#;?OWuDM5o}Dmg~y@5?3vY z*Gv~k)wnqBWcS73`pE{Hl2M_C(j_Yk_AlLG!cCN-jNF~ByyqGs2qCKq?*}(z{NXFl#U*L9tAc|1}|T*o6vm4LzoCi&Q`?l@^xnZt>Y$ zz=3q}n7#ul-B?RFgtVOuW5-1L4OVcfyJ@({|CD31X)`etHLrP{1>@#!>Hp2hFKd&^PCV z{AyqP?}(zM0E%m{|3!HNRD#y9qohmaMjj{#F>MGR5$Sdtj*aNPW2tI;*Yh|OsRlWe ze}QMz@ zS3@Q0qg!$TmygOV_BwA|+1)8~=`>pLK}t<%anh0?0@S`~i>}7KzCHxrc*+;+xH*x` z*%x|Vh>^?QJ{QRk9^1M6{OAnQ_WXQcd9cjpf-GPfXNOQy{Nff?LMc4(ihHUF3soVS0?3!zb{~E_N6aak5$#Mjta-lc_%1GZ8P{xV*p|^j&%MSxq zO%V3V|J!+C{rGoU0RTuGHB7AkPJ?}?`&Uh>e)0bAG>F(WMcmH=s;ut~teKaPb3CbO zGQFuYyPDyZ`I3@V)zsc3)jaH`>tmgmMJ~X4BOkN={f;d;U|;Ma*N!QfJ$(xnH~E;C z9gHV@F+U$e@17KDg3(R!5Uu<)KW|WRy)xhaZBm;v;Yoc_?%h|eLrJY^HMfN0+zh$( z!FJkXeZvmqw;l0J%x+0>pg#|XESiV1)6efOQ;wx3sE`|CBE1}(*EOeO`S^sQqwL6A zkOcyBSj(tjq-8-ZmUKX}BRq;N>wftfMoj&c#F|Lr=0PUo=3P4^V>fyO*}PM=cb&L3QO?+7?D z^ZDG&h|2)ShHyp$IWh-Py!IlepB6xL;RBcsA#VwzdfJ#fg6>UBY7-i`HUylMl(LE@ z7P`@}#LCI+GKT(pdBua}A*N3>e_5E=c1t{TfnAm?D$>FR^nwZl;m zDRR4PGQ!^2J0Ju)up@W##9&z)&#>HxML170rgeq-tWyiK&n{#D^u)Xj;N4=>mum#$ zo&!NTYfP59!)-;)NZ=rv_}8oY;@kp%p+t`(reVpM=Ex(rO%-kHg6<+t&K6x>e1Jen z3}lA{4-lhr=Z`|aMlW(?mXQN*i(pHRV|pm$RG2pq#W8e)^n>OWE#~AP*#;`f{&usU zX5~bCu!QfSFEbJP;!}ha#jGnOU zp})#<^5;g>_L=S9y~%n*@F&L1nk~@WrblF^2~O16_90z$gur9RBRk-W?~pG8j4s@v zB-dW7>t*T6HS8dq_BnWH(>y5{^D8@lq-pkVH{hn35;7W_S2K$+Do+wr`{ZTS+aeH2 zMYdc+5}h&f&{&<(U2Ng7gVc|w;qAbeY(U5g0#={5=}KB!*e(qO)p?xM+m?SWGrjz> z#59~@v7tp=jjlsA!J*G#snSE&7Pri1mI?jSmC84X5{j>E3oYIgKGL*AXW zy;PL`;I-zs*W|9w!k*=$yd&iAgf^2h#V^?g|A9U<`aZM_v!@cy%U7KZ6HSqGeXokP zEw_z0P-5mqK<_?7cxB$+-zX^>^o6Et5ZlGR9`;ifp1-c{q@my;pYE>`!Orw62-4QW zyB%zUE7&G<=mBw7Rw>(kzEsLIsS|erTZjWzT<6Fjn_Ua%E|IvGtW1|2G?Xxgcjh4V zQVC0D#HSXqdN~{l)VM==;mZb|eL6HI@o%l)k?qd~r?tQ! zFl^HOU!;8?5v`uvB@fzK@wEFgI>lTWk zvbSu*bcVfORkJv^V%mVpsT(NjO!&U&rHHLyHTy$*u4AfEVfw@N-q)xxv$_L!?J}JF zZV{s=^mnhDWCXdLMF&o)&feF|ZVh4zIGVQ2hl~d3y5klaPU;B@HFQ);6>@sK*yYVd zWB`rd2cP^cBEscvfy^x!H9G{-1K1Lh9cW3%ut|L^?Aq8?Y6ohD)Z=ryYhwOQNa(A^ zHZJRHgP~Q8;%*cmEgm*|b>gtE)NxJyFy*v8%?&B+EhGQPp-3&RE)6n;Va$>ZSNxbS zOrfiM5AC&!ho8fd4Y2Ef3yk!e>Lh9>+JPn8u%{ms2bm>cE8`Zd#wR`FzFR49XvlS0 z%{DK~@mVRfsK|dWn-^xXtQ6RP&w5++F>x0(g?UdI+)-4OlGRtr1BCBHe~t&ZJv>Ts zI!6~4US9?ISjD)clJZAK_%TQQvJkbtJ37Utd8Ga|+QSbuP_;`kLnhMg^+h!bA=r>(wtj>%I0V|fcBwl_y2+_X zj~RVS%O3_aPp-bbHczvVOL@5fkaP%_f!?-#se#}Yz)p&6gHV>QqOEPh)6)<>Ow8n(Yz7z-5{-DLs^|Psxm^^#T78vn z6RJu&Mn~o5SWS{<{%g6N9R}`~6swX6mkh=99X=KezqNw32u_c21k+Iszfd?{Lh|w~ z|0^L>1Qs4+W#qi89be`5~Cx06a9zM<-Z8|B9QdKZCmaQtv{EA za&DJ$oMeZq>^)1B*QJu-(1QUfMH;J#2119-e7^(+B-|RZx`xl#_DkXDt|%AkvhoZaGEkDMM{JUHPyeZ7JJif3GJZbSqp-$dogbvg8150erH^gcuC;r9)lvk zZD-4hk9bWDw@12Cv(O-IAdDN5Mn%-V?B`HIi$m(7f|_amEn_XFCI!57B#N|E)q1(J zn(2}nN=}rOqYalt8Z$@C{BVZ8fl1&bkiK_~YJtiA_g2tIY)=N4v^I8mKp_vRD>6FG z&s_i}nK=5!#_V*DQ3SUg>#}eZVHLXCc}`LwBnY!kmwGoFbgf0o$ znb2~5DqkBObtK%u#`HrgA??zY0iVUjnpXfqk9;>*c@L-pkm7fO4vh+d?Kq4Ft5Vku zHY8^zl3QQEFgIO?=}Lt@_tc0q9FPE?x0eEsVY<%&llk6!+)o8-cb5w@e(piCQ5gb!>UMYTko3uwT6}J9n=yeP`nl;F(lCBa zCy`IwBHq)1V$he7GZFe3Sykc=5M-E-@YDN#zA3I$tX>2y(C}r6F=guiQ65=&Aw zBoUtSMYO?E;_|yPzBfNPafl{7b(p~`;HG$ZQ%rmW?AK>||iA!^~g~`5{MSdrJHujC%YuIi;%3#Pcoum@P zCUNiLj7x?_KRcVLz)T@Qg?L1WEOyMyBZm7vo%0o5%gYx1sRx)ZYXm6-II518NXr$#9gd5|! z(SW_vAb{ZNBb@)|_^Ar4$%X_NeYToc)=t`V(vY?$z^QtT-4hlWLP>aIU*6NU@;K~4 zzXDR&=A!9+4r~L>U-b;+Yc&Qk&W!Hkjp3n$9YSJt zGN418f8T1Q&J;V-rv=o|^8&-XEEK3bWY!9%Tnf1$yuFt3%mdk!pyDnLL`Z|MexUpX z2IZV0G6>Sz2qQQqVUstDk50>4i62>tCcZ9=FBOmjXZ~uTTqRiOAJQmzVHbh7>C;VN znbIJG*##V^739To$e7!uRNxfv&oG3KXe&+=m^Qb$e zM?kqZb*gpLVhH1!fkJs}R@*FI@VT1%*CJzR;!&i_86tUJf|5CJ)`DSZH>M=d9JIt;shF1smQ;TP_(R!6l zHc(y$Ha6~9?v|#fx^DaPi%c~*Sio$OS5-u)^>X{zC5W{R8P>U9s`$1kKgsQ{9`r&XM zB8tHh8}L@A0i|5hz3NG>@{=svIIxu z(2+3$H9ZzCYjc2+P2dJ8Nj;qmzVxlj2Uf(uF%S)&csRKTSTdXEq6<>m? zGZ%zpH%pV}uL@g6;LWmyBqssZAF;k>)K)SOoz$~vj8t*tscs4U)JZ8J?E_n;@mn?o*=YqF!FCm&`X(_vI*`mD#g z(=1&6>`lHd;GO^Ud{^2g_ptN%(x#&*<-d)di#B+d&iMI5z?*Dv^t`(EC;uk-5mKwv zjCYfq6zf(wpzZ@ONTw5C(DY;Cuf6^zK{lzWF~rBZCN=PT5UeEt}3i zIV&F9&Mx1nl^`vteFQby-c0?ZWHj#kAt-jF%1HOmisPhnpbGjSZ=#sgQ7M37O>#<1 z<80XMXfxsPg_1Os)q(gBSe z=zM52R%YTyX{%T^PCEWa*?LSXkPunW znnVcm{U!oV#S$iW1GY0x3PR0NV?~FdWUMwvtl3FJS{Kk%s5sF7>a;xF*7p(1J6X&B z^raq>=)S|S0)@9NmhWjKI}J?s8L;)5Q>fvUyz!3Mq63=wQ`ieM>{Yf@Mrwt)5#pY8 z4jbX%psUA0mZUFX7B&pPa?y>UtDn>TFy8}Fc%=*@SIPFdg_rTP7%nLvHU{erx-^4a z)}J=Co&loTj>urdF6Jk1ATrnHH?$^dO!w3d@@pH1Nu1$nMIrgLZ~MMtJXQ(?uuHo^g5lMoL=5Wn3vow#<%h|ouY zzZSS+VQ;(!Y?JikEXj2u1oHm|$1XHvR66E02NFd zDVY}$=^w~SW5Nd|g?CL;_Bz(DF(87H4X_|upfaVG&gwu|FJKL5&;MNxs3@1gJD2(k zTpY14#xu$mbr4i5&<;fxS}prR&BAR)@1vA~!Fvm}eF}|~J_M(>gfFTHE>Kvkfa&~4 zAtflPi%hpvJTC|ip+!6C%*uB~*9xm4j^pW~;wC5r>*Omy3cdJT;EBMK5G`e(_dbxL zzsfnLmxW-{xI?pSr`4A(hOd&zBv#Ro(Y>+XPcDvuhle@ z$#6Fi7-9c@=H&LkfXI6X5y<~f@4or&oBz`@GO=)NpL&U%3a{?^hnK)w7<9$K%+^Uq zw)KA3`970QPq&qr?bV>(1-|W7k)8!%^;wuS^T;zC6&Os$HK`LVHyG*1m4;JrZh>DI z%|L8vIV-^Kult%HW*#Wx)F+EZh7?44FI{2kw-(4^^GJL?M^N0s4-l z)j}E4GSrhB6!VO7Q6!N-pV6#kU~(O36~(yqa-C|}VLZTp-kA)`P3F^Ez>TE4fZM4Ez3(&`os4*j8C~L$}`iH#`L}(z>j~ zcs*~y%?L@VNFuNvf~@KS>(3)cGQ!?K54lZh67MQ~|iucRrk#w{{&u z`H0Z@c!R{*em1u4f=GcG_BKi{AK_KYTVKeXwV?H8m$n8sw31eb(<@VE5wYVdwzNu1 zTYjI{B#=L(UlPpK{J4YgbtTp3^^e?S=GdLlQ5Rc-7g92yGMQi73! zQwHAy>x_rz1qQw#0Psyb5&cK2VAb=#vzs-iw+a>cDWsEX4A70!RX(Y}%4W!h1C+|b zU2ey6;Fe@(mLi!0R~#7}kR3Y^xzLQY&%;$>vwnaB*{jFAUpbSZ6+UJQ^UU*I!>L95 z@gh^}(Fa3ChvsV@#5}5w>4go6UIecjl-3!Nng1ethl2gs^A)ick0e+1J@BFOnQcXW zhUJ#{8N9-adL)~75wW=+=qLL3Ri=jf55Nhqq|02WD)Fa5Q`d!67uK}vTq?7Baf2pD z0C6_8@rEWw0B_W3`0ixCjRk!)H}YU{9~OO-Fy^3q|JBK1^8$D7xK1p=oRr~(~72GGEoW4#=#lRE0zK70A zVO1T%eb3{h$Nmb5=H>9qluvk<{u{m95XOOyD2|0woWs{}Jwa%yN1ew=WQ%;aiN}8; zVoP1hY0=dAV|b<3?c^(uKcilY=Q>-r5n!XIcL|Uvo1DZO{~Sjo z=EEqQWhw6f2}pbYPC}Lq<@u_N&CW(iV43r2!5P&v7Zd6Y{+Yz}lV-#;|D0k0r5+Wn zTpjH}x%EZPuihlRj!*SpA(ED2%Ta2e^zL=lFz>+UNDSnB2O*LTG2-|=E&46qc~1EHw9S6HgUj!UvG~- ze7I+RkfhNQH_3FVgOcEM<`1Mb<@#V2@w+^I&M7D|jlBK#${?Fs9;?|6bQT{b=*I5f z{71z3oav4xQU)>pHc`eh+dPxFDfc?s{c#I!#nLJ?KT<%CA1m5)dl*0V(#4*m9l6~U zae*M#>}HrlW1_u$<5JIS??I#5!Q73QuwflXUD9m`PvjwjOWME0sl7`FLpV(SIDche~Rq*P^ zHEjynFnqkBQ{l6%3#*Ply|^GTlNGpDAA{8KJce-hz#U#|Cw@ntL|4?u%i$azl;6&Rt#)FD)(xd!g+iNYVU8St%XL}H26{kac z{sT>iBtk#opM(}fKubbAY_bqe$06}&J6Tv%9=l0F)>JWoc8(mNjo3!JvVZsa?6c<{ zl#DxRwyw2qRUn%Y>-^ZiF-h?^x3GQ=2j^c1f$iz6-)-(>+UrFr75QF-K0|Wj+Z4_h zCI;-}NkHFgI@!qe2E#!EdteqOK`}+_JS7dAr>wf{p&ZiL6iQ=Q@aHlD(l{nTpl@sB zY#M_!LHD$x@E#!JhSl{*eLK#L%>UY@f`;z&G!a&24pOmls_|WvBDKh3#YG^yNfn=+ z9P;6*{wDLB=slh>K~67$Z@TD5HzH|f{Gpi?YZI*qnU%R->*~}CuN^7uAx;606tot( z1^prt$%}5!s>X8K_#>ofOqpeAeEwa7_~3RMzaO~=Wxl5K?o1B|r39FNgO&w`%}9L^ zMZ$6$$**o-)cN(f!|`((2D=EhqCbuj4j_s1N*sTaQ#wqoy^0{*+;0?}2`F9Z*@v91 zwbF5m2)o;yN{lzVIe!D1UfKC;Wd+o@%(ZUbx)C@C$srnOtA%5tLOr`O(;-$ z*l_XUj3Zy+Q0sIqsLs$gi`=!dZnjF4A{7XSL4zA$jE&k~h0HEE@L&s|qCX=e`Sq48 zb6!vp_{X@ea6gZAT4JECVkYz8BsFs16XY&VcW6U^3K{p4v+Yl1NrO5BkR48+#&Q>< zzzh{_&?5twd2Je^bx~Xq+~XCZqCz;YAHTt)8`Bga5}VnMHZy<0kLnM3KZ<4jtmND$ zmZwI*b3j?#!*obE@#+)HBDExNL^+tpWWvj>4<2MmvG*Q9MV!^xzr&W{H=li&cp}U)%iSoKUV3pxxI|U9AQt@A ztD@UKTB#8=o|j~_0=Wd-{BmC0_go@(o6*Ru+3<4oHcM2Ozp=cZeCxK(X58zoOvjYt zENOZ2pTl*hW8t}(+Zb$R($CCIBmR|Tq@4M?$(5XS``}iu*?DV-3_3H%CcPIq=H6UF z)W))*aPZvYlS<2WwH*d65PX4?OTp?;B#|*qO3g{sin&q2PVgGXZdJLvUkH${u-J6j z0=_qw&-KP0rdokNZ$-(LGNuYFWLIH;)A1C0TBZ~NEI5;xh_W8O(N91Ct zu`jqLx&s@Lc(u!TZ4QU%ngxa$@eTI4o9L&QRs)sIv%>t;ym+Xfk?d)i#2~1)b0w;= zNjW3|^9|Nhcd-Z&vvZ3@qn~99ILaQY_s@azwL&=-slU!^Q>%6n+wD^X%x0H^yec3| zP>^dp%7Vw{A}1@ZbR@Kt(u7PAvx6u=RK4WHtu2|OMsVg3Ebs|`b5c+vRdnJ|c_j)9 zQSrc-Q??-Tw`6c9fZMY&zAM$kU8>`LHTSvF46mAm&cq|C4A+A;zC9I1PURpyfcH}= zbj5&Y4`Nl`9iatH&;M%Z8}Gi+8=)m}JN0VwV#PD;$UD<6k}kC)sOiu`vk{V->P#z( zeSExNK$Frp=~ZxL8BI|4-g=A4##%L|&_YTs+S6g(rFZ!%QH0CYm9w2G_|kUp@cAkc zH^g^qa81hWMZ5}f5#!GVKV94Ls!&!o78NHUQx(orbKwI8JsHX9*g-K%>|ry=a)iRg z8+*e0jCetW#6>$sLpjIA_;UaEvOHxzUF2fibT3^1j#J!h?57=b)n#a7_|^G*WCZdS zJ7Th(yQfjd2wRL~ZY$EW8Q*rCA656?`IyM_IZvrD43xSgEC}?}WWxYtu%;6SbS`KZ zS|(a`*{>tH*{oZY@b7Tw{Grguu*u)e@(?*XpROMqNOX= z&*p%XmI%jo4NLtyF48gGuKSr7z4%X2Jv#6}EYwAkx@FrJ^Z$8va8(3JioOoqrZn2OLm zcS(9fz?=$e&`YrTF5e!TyMjB!w_g|ZGW3mi-{@(!{Qz0I+_>^UCr<}D z!|jUSrjsz)B^FI(qi*vu61Pm9A8gbw>R{lCk-x6z8K-}tIX9!L?KUgx>3YYQT%IjH zoG@IzvZ?(7Y7pI0g~Cp#qhLl|GL@nR+vw&pCcG4c%)WB?sf1WYFrGVU zi#}pRX-xl~Bs%(}bWU9K+lRa8hZ$;;dM55c zm!(yii-$f5x3A@18;~^-bgVs+el+-Y;xL&6Dv5*s=fr6s0)>-eUhpyu?e3gVI_2>& z61$RyDFPaWKlwebos*VD0$HiU8Yd)V zN=8nmo4hTRg6=rW6skO zK$!cxUe{ZCQC9hV7qgx8)CAQW)4E;6Ri^8iu$i4{OXy6u_kL%wzq8+soB6k}I+R_o zn6R~dA>WOg`LEyD1B)qrGZnJE`{wxx?3sQcJ2NZNfL!@On@r~%uD;A}b!Xu&|7wsM z8sDN^M9)9<@x#Zd(=9BqB(t#nR?Rx(hdl9Wm7m$lhmhu;Hnd4Ce<#1F?`!;xvd>IEw- zm!Ft2nEcyozdsCW&!9-i;{-dQ$#e`2>r@MW)wK@{63^@G8_u69fhO-tnuBzVBZ)ue zJS5G}WuV+2 z29RrzgxGc8P>%~G|Gr4}u zIApq@n8-k#h?Ak>QyO9K9I69ly2T*k&|`ioR`b_Yz&gf?s_|hA9rGnj_@rP!EAWj|D~#9`u}Z|{B=olc4@7#{jF_rUY$ z>9YOPabIsEJeu+&FnMF!4z2;5#c9+#?j%;+C{s<<5}YpnR<2b3;RduESyVtUj(%kR zY8Q*;G!Ndq*oZ}K(y7<9RSyPh2{S@GnD`Clk^G!|GzRMC6io!9M{#+q1+ouI@z2(3 z8zS+3KJ#BH_aF0SKlN{!uC9=I4ylg|Yxn=4xDKg0f8JK6#qu3H#H7ZJ{HR1kmHHY;uHp1x#>0cuPlK+kcrVD0wiD9c+{|ufPMbf zG@A`{y>{yKGA%j@_XuQK+0$y6ivw$3+Ht*kTz;AE&$eMI*Y`xlkN@m2=S2xpAGX zcM&{;TwFuqZqVT}8C6_m51_s$^7bMQ>z%T^CN)=L z7$f=Vrp%bnBu%8qO95oMTMx|kD>KtQih0ZI20PNR%`1mWaFp);+HV;+Bd^gF8D4*X zRQUT{Zg>5J2Zf$%DQB0fT)vrudntuz8PR4#2~Db`03sJmpm#6lC5`Kxp9Sb=m_?rp z_4=tsh<~P{UlITXf0eq$v`=n!F3NZI0x=I}9u~fe zNbK|dEwLIRh|jy1AI5cwM>g1i=k@j2Pgou6T#u28WqhY#g8e>ZJ0;!@j{?^9O=cu1 zYxSq~DqHXOxGIJJe7FI|b^woI-5!+#SSvW{*kGqoA77?r8x{Rsc;6*-P}KP3Xjrm8tqt$ z0Ejh@iYDlv-oM3dD(p)LvTO_p0pc;qy{rRw6l;nxks-cBy^u0#69%-@hB)XWWnc zVQaxf`{~yG=+Ar1z3r)C7YufJp09tie%>EYu5jVh+?jPxknl0Ko$*h9@-pWR{4*@u37Zs`sajl=-fD)@4 zv4WWEW}0;zc6I^R5lK&Az+Ok+=rkB zE6;-)x%K5YXmY3Iv*E^(V$VT<27m~zH!&$*YIAl`8=9R|a+64v2=X)n2dT&@N%nH9 z=yV`+Hb|=wbeWR@@oILzh$NnJK~5xx(Eys<+u?u-tsBRu-{53%ItLY#i`iseEx1*T zvYv3DrYfzYCPE$r*F9lsWa+rgIFj2#v*0moQqIA>IOm; z7nK#soGXXfe!$9rlWWZmQ`=_EHw0QBv3lk>8VKn7S_Zr>1A6!j6upfSSYo^!BWo*) zKOe=TV+%OjsDUDy)lx#8z-jSW3)O@Rwlz{ef+(DqO6uoi7letyv)oD_Uiz|RnM>j* zvURzRgQR>1zLSxv4Jg7c4VXH_R5_uLsUQ_%p6H(F3Q;@>jt7EGb#%6LoeabKVOgyR z^?ZbKl8Kdi7AuKSAr$h&bWEkf|Ags!D_;uENqB=o_#oOl#*%vML`;z9SQHIlN6LuX zD~`7*;-jDn%s(o1R8(`paVfuz37c*@WQG&%irnK`zQiwMX*8L+T(TL711YQk81YENMKShH4DIeh|Mdo2 zKBKyjM?gf8SIb0{qk3A2+eIf>Cfyz71%WR@MaZZv?aqNwV*z_C`0}ykD6pn%7^7QVUrm4Y; zkaimT<2Dnnr_%R8bhc7B0zyjSD*iFWg)@d2LE;7mGcrc)ux0;mKZEg*VGLJRPGo~1vo zPC9ktP?g{Y$9+lqBE4KJhVV&?{GSboPN@hlfe@xknLrMH93Oo-$yPw(yzc&^u|)%S z@={r<%Kuj>DulpEkLL4?$E2?kqm2X&i;Q##L*ZY(oDIf$n*`|{!J&x<#!hjL$P@SI zS5OWfR0N02^&}_L;Bn|o!o;OqD`e$+xd92{s9biZ2#AxD5Q^x$Cas87Do?X3dM^|b z`0xkkR#%@@3{qr#8$P^C#Dc7%|?=8!yJ~2 zNc^7O&>;UxVG<=ml9KvQaXusF0;M+t0fVc45g95OFsBS^iX4oh2BRV#_cLm(ybu>L z!}mh|yYFKw?4kS~2Hq;6Kb@7s^cFx#g!dUG_0NC+o_RTnM4b?=R~VLN{x`62XjWnw zx7bKbLK@d$6XO`f0!@dH_`0C9CbE{%Ua1t96Rct+01o)j<49l}VZH8TNe&?7C!~|s zZwVqW3BQ>Hw<-@F0EswT!k6R;mu1ehs#6yW_ieGMvRQcW{Yc3Zm8nWM-Ycb($G*C8c8N2QRp<1g-%Pt&}k$MoyOwO zX(SJwMgq}j*10&8J$kqF!cbOR@T!xA9Or@cq7YFXA51R^b>9|2sQk9dLGNLy9E(9y zDd;p2gHB6w&}k|NoyL;TL=ak(gECtvdO3(O#Gb_5Cj^CKvN0m zG!=nP%QDbuDg>RzQqWikT9kp15>JDj2;_iK<}3jLg@^|i0SFjG_*Mm=CkjC3x&X9$ z-l^X)v(xUIb=ntK9tavJvC#pH+olFGI0EQQfINp~1KISBony14;i(g64hx;I26tnp zZt$E}H~XqtddS(xq7w&*$P0*wf*0~gd@2R{ExS>scW`U-d)dL{AS+`f>B<;k2aZp6 z$X36?!FKQF>j%fSS;C{}Z`tl{?9>gO(PQ>iv-FSwdKm6EJVTGr6(r|E9khuv^ni!e zR`hsh^bm32Y#Nab??+Gl@EJuGzHF8sH89meJDK4?u%!j&Nh5P$PD6}sqYD*D-Wy3Q zT7qzuAMOoOkfa+u^}_=snSa?VKWcy^ii@btumqhb1mD1Q%p6U?qjF_6?~W$Ov6ntn z_|TzAH+t%a2WT??vRQuA*|O@n8qX95B562cLO~@m^kbPK328i5S0s6FB;o!_qBEk= zQbCe#^wbXzkYxU4v;3$tk|0gr&XFXwUSbJ#;1KND9jPn)Sdru%k;LdWOEfxvC>!37 zp8DZ4k}Q1LEI+D8l7up9VU7ZpxQV!Sg6BR0Guf46XDgDtGm^O0Tec+ehYm@)(NjM> zK$7{F&GMtpNTRuN%?wFm*Iz^)4;?miqo;m&fEDvEo8?EHvBb1<6_>+F zi_7=b z=>74H-iT@+S+omkbS7`)(vEE61vRR{`-d@jYnw;rY{7uu+|BLnrr%au_m5-iMyAZj zkX;a@vvg-SwuH;q)y)0ln7Pqbdt}8H6zHtnDUXfd1wpEb`-d@cqwV|1fL#!zvv4Oj zwt&mm)x7<~n76ghW8-zffX=!d^Vs@bq||EK{!vWZI=Hdnx*$kr*^Yi}`IfJ%S^J}y zwKa*GBcru!aBtO)YHal``(I7kKa5FR&)G+B&kmuTsj$_Y{Z8g=H#cY7i8=d^)kL(- z?H1I{Z69Wj(4}alr2M8^o-}=w?TbdY#^<*@sq5c;vTe-fEln-rJxes}Y7usLh}H#^ z6Il8idTeN0ninA5NB0hbq*i0&NzmjDu&LEOk{bLg}yGpS%PxcS5z3ujVv8xrSdzY7Ka(Z}q=;9FLnasoMH0x)+TX$}s^KRKZ z^WC(z*N}3*gKg8|al==^zac~UjUBg8kr6q6#1vy%?c$0uXRtyV()4oC5fzUhI#OTn zdbQLri5GKgC#3L^8zH@63pK63)FW1d0w<)wCq_pR|W6Vqlek!}v{W zQ4Dk89?RtF?j&JRCAD@6m#%1*-np01Ec5%NmU9_EBw#25Zjp@?>_o!3&@6nvNl{fazqSqfhh?cpjBeL9#|CACT~`?~7yNlc zj=9vfAWEE2+rmhWIdRQem*8sXg=?*rs+jz#55DNePvEH>eH?S9^=e zoXH0|Wd|>XoHCcipWQ;3g9_)@4Oz?WB6AQ+mPs&N5q4^g7LmX`pbNLmj^3h^$2QKI z3TM^AS?SNOzu?Z59lC_PL7)lVWG=H&jBFMKdn*23#oxsC51<==>hZT5Kb^lA;_t%O z&7}vPJGvY0VQc&tISs5OC22OJ+*Fv|!YK*n-dHmzIIn>VPc^annTge0sus4;^7KM$ z&0%NF&Q_-_YD=S56YaDKNm^?D*6W_<{+e4GcrLY6rKh{rpjVGpnN)?a?=+oZ_M{!r zSgw6;P)X6>FiqF?bZs7I-o9#=<{3@o`xmmLU2~atOVl*%Jx@?idZCb?^FrxaFOi+ zUgRzk${5-7oX%^m-g?pq6fEt;&cfG7x)4OE#;m(ghn?J#BrWB0|L8Str~vdR`tXp@t&*_arS)rD|aHk)M= zLnS~P@Mc6p1be0|Xh?vDglUndjj7KP1zDmrOI&M_yXlUT$yi09!wAI-V#-(~?nIqs zOvz~GXhitUdRa!fAj`0jjNgioT(P1$)9=D#%dH;sxe+QCAW*Ie?I1RXd!RS5zaPUA1j(;g`v@87Q10=~-n6ftR>Vp;cqS^i*i4$*tCRXQPXrXJbM_ z0i6?3?Tqwp4N|N<6P%USZPVgVf8CWX;2poz=(_CfP>airZ9^DRM{Wg>=O~h-=q@ui zQ$(dq5)z{glGAOWa;8Y$9+`pVKD0Y6yfnCqBgfF`NWK9p^k&*mzVBbp!7Rfr5U^*H z$fXy5K|kQ|vNXjVqg&trUF%;+G{nVSNO?HLKp3uEPZT9@CV zPg1Bjb`V~LZE{0nzzD}^&mgPkH0(_r&?wk0{($ahoK04z$i*n`l12oOM=+2I+A=yN>2u?(QmLZT26Q6%R+_B4vmkUr$8R)cAK(zt z5D3&~=I7g>AyAvNBv4CttUy%eMrnzdq);BBT1izZ^KNJ%y@dw00ODlPG++#8tO!uY z>=1W69dTxQX_G5t300;ju$L>Ol8$|Ggmw&G&)AxwyNskB?$2%qVvQ!O@My$t+yGG! z#$>GYP#a^41A?#x+xG>=H)`bGwVAao?};>3`te>;3L+*Y|G*996kbhj=T>W0xAefH z8b#W*MbO#qIa@-WDONnvb5_aBBTUy@{yiaN0t+5SLy&Hbo!Yd2o6m3>NWmALuSISi zXms3DR1GQHVz?Kg=g|_B@Xz;F@&sv^qe~WqBy*GCbc?#@vgsmNZZtEXZ7YwFbnll< z4}9DR1b3#@_njgow*I8N>|jYViZ+Nff-jAQHd2q#J;!K9b(c@Y5;ogBtT$gyA{fqw(1{O*1Q9j0MlM+>cd&8SJwKEJK%{~NbT!pO#Yn#X$UXH0pxSt3 zYNpt&IqX$$Lb=5p(Ohh9tYQ8EU#w}=M7U_?ws894cp)ixUM zvx>U*PM@cP1|bG&P;rld{QB2_p)WuE`)|Mg{;%rOBt3NU%2;;eC#_NbiA+O7kd?mx z3PrsDl}`c`t}j3puR^8wf{IuJL&b%%zRUFmsM1xa%x+Mn0#ztbrHfGIt5Dg!pmJKE zie;^wz66z3SD|vdK@|&Bxj+>!LZz=l<@bULW!@O7C{W@00#xQIRAD!$@&u}jXVBW` zok5&ErdO)at6(mI<(`M`A$4Hc0@lS-X#G{N;$C3Iatc$Sqw(@7yiVQIrwhsd1u7yy z%bafe@$6R7yK+7+uVTC%-n+R`IiK1TvSBVC(DXdA0fx+A*+OG6Z~?6RJi1}K6KV_6 z*^4LCsoRgj?nq}kcugm4T!vRa@8}|HUd}=xbQrh*mN~%LwYuB(!Y}MaTI1~V&aUs| zTVKQ@e^J17?sfrp_hk$ntqFzJgp0Js`R57bzN0mr?CUSm8W(PteRp3*-Ek6AIElW< zNnCuMtR9L6p}G3)cNw?ikqeOcuu>CM|We*WKIxcEt{RB6@kpTBLMtu?3OW2!>M&T7lO`6QZFD(W1)_>CV$dib$Cpw06N z_^;(k@K>rx%Pv@-Dw4L7kt)-jxuCkE{n4Q_My^rKNxd?17``@8U2g3T+0Z#HudLyu zzBrX@aSc_payPuYuJDt3;6oSt$#2aTvmu4-oDWx4G4G5lZzR9rs?2p{dAuXa-GJz2 zk6fx^i%uAOW$~x=!o&f*8}!1G}%0OuSH?gr6}BHC6Z#>rRc=+*IkRu zd@TystVQyarKliVtTbz7((($S`_EK&IaBtms=V%~>E=D%!d6FqWd-IqX2{g`zRv6=e)X%X3sVT3Y8tt5K^>nM!G| zXJX?KvEj18K23!1L*Ze4l5j)m=M0P1CloH-Wldj1%6K~EAj?Y?P9o+oA&JY$+0Dq= z+>D&pCgwsGYHeCBCAVi4eF`m`VeVHZWhbs#n~xK65n47N<95ND+&6EOj`!r1|hjdu)8H z)Cb!%ElFiF&?;_{Yrc=`8Iw5#-1zvIc{`T_Sx3B;F zf*JpTX7lf#e}4PIFv6Vv{pT0XQKNZm%wERRB8;q?rQ7AzLlZ;U~booLGKsv3> zyqYi7^bN3@_|6ler)U+6zI3W2dD5G*@(;56QhVNhnq_E09l6(_`c=!rRU+ z5J?otNyagEpdI+a+iPK%-9oc}-#= zHP}!c&IBjqUjd-6XDWZ;#>yYDEQ0*i${&hxR;{7^K>(uV`#!Y41pVukzXRiQiT2lG zVVO(AX&%?p{(>Ujr#IIA`bwPJQu_-!cV$cMuZ-8W+F$Ie*;Mcdz$R zbvndd?fWPxx*dzrZ7oN)GeLSRM^D7)B`JC=L{DYtsR-RpWaxGzM7N7lGy}-gY9E8l z)mmRdqNwJ#7V{47i5c?5+SNL|Qt^`%rg~aPTb|H?SstZ)H1=G~(9-wMe zrR+JZ52n`k2&q=eUD>;>vKQY~_9opXbivdr38YHP#W9#?xmx16bX#-QBr^5Ek=i*K zl9fDxTSd#J7Z{5LUZkI01YC*p=_J#z9fB6=^hmhU$)JXefLY21DNMUkP9e)WKg&ka z$x>JK5h`>Bxw(<;q?H1H1`)>%97=+y9F z>|52@1>hm2R|#NBN^>DfB%Vco`B0UD6l-l&(eM>IUKLFAZxU}xHRtDw)-T)YIh|%h zLU0mTHM305(wymRJ;^dV4JeP}yjJquFvr521(V$qfx1h)RQ4=;afVB7P5e>OVy%ZM zE+3(Mh0HQLRO0VIwcO zktByiZc6m7I|yTxAY!6OLw}K|A=q|<1X7ZymZ1!!Bq+E-*y*E4zq}iY4S~=-R2w2! za^)oVTl0rWw%tIQpJ1vgBe75!SB=T_F#JIGs$^C~OaMW+vvE`AJ@o14Xi8*JSo z|1Q}E;_|*CTbc-`M`TOAO^(~?(?4kJi1yq~!_R9OKyP-Iv)%a++5za@dO=`%JDq*U0{JvQrS zkddlBm?W%ggaHe-qdr4+sFv<|hPKWz8R2(wHwWu0IyAVfO1wI4;Osg4kOJm2XHcU<0~ z`eyJY$z>!NRw)In5I)RuN-ccE3cmewL2LiTBw>Avz|JT(VH68``HtyLFukNI@1Q;x z)R!o%JD^Vk^nwn#i@!(3-`9O}%&yB_24?K-0jiQ4E_6bL{)r@EWfC(?=Dw1kvau}Z z$2J+3adT7^pRN`qU|gcU2`O=;SEH@@Dq(5iwHF z+h23B<=GH58#R1To>P(Q>TWm_Bjr6QZ=_F=0!M>n()k-gpK&&)r0uz(^8jp$Jy)lQ z*c)`yM^SbmS?eUNNea)AsfgXuIWzvwMLoCr*5j9SRx50c-yx+(t2AXBLXTe}|5$%T z{J=3k=mFe67r^#k^a;7p=U3mJf>S(z^7bT%egx(1-XZ-As@uK7`QBBxdysZt&)Odz zf>YjD>1@D;0cS-dK}9NTj@!3~Pw!8b(`wS31-PcdZ`YvNtar(&DQ)g&iD>n8no>! zs~zc&%x+3*TapJ3w(zo9E~>;UP&nx*d*tz<7s8@%tbiE6Ov&PeVw`7bJ-k)Nc2=Eo zzIEDfG3~K9&{;9-r#QWb8XG8Ztms%5v7wl_`%x>cI{9GrgZA*0D2Vg@=+6q?LubIB zs^_OnIpi}h?E^x)KJNbL)3z+>kp#13mUk@ZdFLYJJe!R2^nc{#(?lVolP*B`J|y@3 zdz9uV<>$Zgiud#X@$FE%!Ty@nK5YQRT#vMfL0uCRSjYs<-MM|OV&pIY>dkM zhQ83l7jU6z-ET&$s;H`FxK7c^VFLig?&QpNr{1^SMUEfC zJ7W%+?ot*#S zMocUm0q|+7UKFNx^!KT4Nv=+B&tEpnMHNbSflqoTxiJg>kR*LR72M(|f?deaYJ<3S zM^wziU0=94bs?6JWCcZu&iek;v+i^XKf2KQ;a%*?hDt;~7QAm}x$Cs-C|u&pJ2gpe zB#x-~SKoC*olr$FLYPtx-QNXsuBl?7({6syKX^Vo@3RLUeNZ{N!&0Y*cdm1xA0~tl zWIc1a)57wHqbV*XM`G7|-B}zf(tvS@; z@=jM24xE|8(4~5PA58>|NQVZWSI{MS+;=vZoWmg?7g4m3t99MasaA08Ptc&TWk*&p z>JXnU?+`uK4SVBE3Z1b`wFaBxTqasvd`b18UxjETWiTe@o(D^hTApjVU+QsqCgyyZ zQU2jq;|tB_Pb`I;sqIWL>(9}%qQoM|LoJSu5j2yiPLecU(A&J6Er zW_V|T^u1lP{{2m}qbzr`byG!V8607p{^+%dKD8~$l{zth*(?`Ts6ji9f|`OdsbQy( z<|z2-=oyhPZjYE|X}#&RjTsg`uzP$AWJ-^OIe&@(u7Catv*3J<TQ^1!(s4kU!w!>q7Pi8zyr9cY@W?j03<7LS|Zu&>}kn zwcgZD@RY;w5F*2kh~Vx7hV}b>skrb&*uM*TVU?NvD+Tz9x816s&yDXDEUu_Ox>I2( z%O2fpkM6a(nNwQguhvvH%nZe1<|MwPqMc`W41dyM|DwUAJ6We(>K|u#1aH!Y-MeF7 z(#=78C!VA&`+Yxtq}4I~fnKDQXKWAVwFmRsENICXtGrd*L^kJ^fFwOOOUx2JgIr}` zG}lFp(ENyDycR|UDSannCRrDm{dn)wC}^LwPA%nuVJQsj5d(OA?5I3V=&m~?xrYqe z^|9l4-{HDGf>a+SP}j|Yvxn%q*8FB><~Mz!`R!nYuFCqh2k6=Zblp{eE-7#;n61M7 z;I^6Q-8}{9;wIr(Ea{uvLhN6VO`rytdx+0@32NlA01PV1$0@3YhCX=EEjhTmw*#Ud*#)J zA?68pEj9?&6vnTEdW4uNucb#YJ#)UF|D;G<56g+~I1JZ@%kDi#;rbA1<0FD_ZN#syiNN(>Wc-2Q zx7J1J9)0UpHg!9XzNI(V)B4wnz9n_cYCs?FC67o634=dy-^(<^W5nKq?+oq|9M@A` zjogSSfDiF6?q3PtGi12`$XgqB?~dbc-5j)c5_N0Ke&0{bt<^F8ff2V>p0Nw!Z3&vN zD!|s_<9^n5KOOO4rz0}CAKq%6Gd$?&h;_QRpN`m1N8Hcph-)zY?58942wRU3F2jh$ zbJa#1IafV=vryE4F+it^vC>P4eHa$$yNDoe(+pdL*TQjkkH*+8NTp6MXSE-0H!hCwed4H>)OO%+!sxHL@bhst=mF}OZX#?zqx zyf7J$*zJp>WIPG%-w%=TAhWv1)7k}u5vsK zIKgPaZ66`PT=^2qo+LM-PTm zXs4GVOFv6flp2@A3+B*AWSicJCgIqVjUx#)nB_asW?8P@m61x$)USxh5R zf0OS~jKtA1z%6I02zI%z_T zYS^=$Z_C6kWYri_xTD#j^pQ{^;Q=86Ani!r!HLb@*dVSFEYkb(y3Oy~l%as>c(&$v zH3d!)7sqR`A(!ktQtQrX)dXT|`GQ$PY{=QhgihvL!>BAv>`W668{hH1qv_UY@+|7N zBv^Xhh|89iJFs|VTsj!Qp{%PGxu%qzZ|Wv28IQHkWJX8=lOkRRXc?Ee7&THONpqYb zBn7zViLpgObxI*&Oi|-WrdKMZQ1(c9;L$LC2j_=^lhiZIx4!UQ@>+GIViOB;;7A$> zBFy+HIEkx}F4m@ZfCS}-Svx-M_X{@-X!xo1wEy0$WnNQgSgZNw6z#212 z2;#)lc~W%Mj^mHTG3JKPDe<&x1{@)jHyVS-60bQG(O7^fQ#RdF!I}XbCxF%r=!EBF z1mVNyXP_Irnwhds_E3-Q(!SG7d$jC3oQ*Y=U}@1kLU-&`Mkx`4wpdPx$;#CM9|(Ya zVM7*MBTgiz3#P;_qkb&lU5DU$G$CNAS|XZ`O#BsR18^EqUWt8#8%v+U%&&lA&NZR} zQ&9oORB)?N1i_3$4tA^|kti$E?gEGJjAHsADydX>gL9g`i3nPlAk2pgAZj4^!$**e zBw}^+73q6E(GZQHU?ZsuI}Lp-4H5M~DwavUAR=OiU$SHqpCh2EP3Q>$J{#RjLpUSN zv}Kk^D^rkU;!^qslm>Z=%j8i}ng@y0RHh6As~Nf)E4tH3Ss-YujCxWruu@2a(?0h~ ziV_zRSzgava&AT_vHz}tzRu$?#~ z$6m%|SLCrg%{w&=Fd~u+X7EH}MRT;;7DuGyB{B|vNQoUhBungW$UA`1)Ir!z9FY?T z`;Pns;jGK@^Co5O3)nkZ@#&7zY0%?&*%v4DQFY4(`s!d%)1dE!a-ok7Kvu0q5h< zOwD_h^f>Y`e(J&Z$d2p~2G=7^cBf(-Jda69i@W3T9*~rFFq>phrgg`$EkGv=1a={_ zjGZ<)hwK-u{fU)du<5;x*=tw~6*!DUI(8NQq*I}hS>_%)JKIH9XxqP*#L^n*?}J2S@k9(~`}yyDn3;3KWo>n>z)3Bn3dY^Xv-b5SG2A)?7;un%S-HOr{Mcjbu?CdmH;h zEZ)I(ZL7ecr_%*&$S_W4B9RWUg!3-Sv9C7W69o^etmuN4EyAZ_3-N?5HYF6vtCLPf zX)c&_b}SCX>lzWCO7C9Kdmt5f1^Xk#=|obd4QydykH%&cq*Kjlt4t1;TNWH%3?@Fx zdVvwikCb-wtw?BSwCX~YRT9=9kEJzl>@~L7?ZaMOT~VIJy=Vxao2Y1b_UZY4C{q%r zR6!@7k|`;^PBFMePY*s}D8b-2yZ`kLs27vXYN$$^6f3{u2a~d9DKvXrLDy-uOcxuD zeW3knnS8otpuL+BIlPtdR?AHBMzJ3|Z9bnkxh;LCu0KeV@YUy z@JI6^u9Hq!T-Jy|(VJ&?&+i9#e#6Z3YbTE1uNyml&nct#{K7GGO*uL@2Hqia#a&o7 zhsAI0Ijxyps1?p08Y2&SqKOylS#xxVrw_8}M;X`I7O%FC#}C=!;@5_El1Ovtlx@mW z<+z^CyGGL2PsV z>`11~5}8l(6t)6}h3mnGDA~k;V1N&}@hK)(jn|xl<2>X0DA&G>GNrlwe#6BnB!vQ} zq-co~uDV;)k|YlB*~wID!=98Na8Q8c%g9^xN&M!GANxFh#5}ehM8r|`uoX6B`YWkz zNghaa;bpU2R3TzgTQtJpT5O>8`S2d(3+%~AIvX~zO0$qf@-=7iB87v4-6W+#lDLCM zlXVP>^TvDRyQ90m)81dw00q06BKCa4RA!XzuNLM#&4OJyZGPXT48uYXNsLsT3^<$1`{I z9A_?4n0(1t{;R*WtE9KXi|XF4rPs}&0tXX~$30nmy_d?7OqhefuF~HF7UB60^E|B* z;-qbcON$T|v}D&%0cH%7Vr>$q5eYCR3K_lCQJ=b0g}hYBv{ccrUw%&E77xzR9{F<< z1jFwqvw@8MDhTe=+u=ox;Dy)Cp#lqnBldPE9Dxa{!fzx2DX~16&lgT|P&!V-TxgVo Xa_|^P*wWng`se=xD$C*@6h{F7a|p-) diff --git a/submodules/TelegramUI/TelegramUI/Resources/Emoji/heart.tgs b/submodules/TelegramUI/TelegramUI/Resources/Emoji/heart.tgs deleted file mode 100644 index f8fd248599b40a2d94f9dabe0661902a43f55677..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56207 zcmV(?K-a$?iwFP!000021MIzNlO)S=B=}cW`g3)P-v|E669@%61c%rG2@2lZIfTOh zzOJg~k#S{JR#yf=E}J8R*X>=E8E$6bZikxMzkd7ezyJE}cmD0$|NQp5Z~2yQ;oIA{ zfB5US-xc@v?N9&m?RVope;NPrZT#VXefwR^=^$feEV;I`KN#R zJN&?(|L}kQ_*ebI{MkSK^WXE4e)~V)ewW_9{rXq_?SG6P`qyuN#sB<43;HxH{O|Ec zcPpj-{_WfNrC{a<2?_Ad_q@*BVASNrP^e}*sm5Pz$wf8~Q>(g&4W%JC~7 zl!89!yT8R!zVb=g9x2_rYx@ss_aEn8ZwIHR%O+%f0=cR^^|5V!!;0 z{;V%*rq-BmHK#A>)|mi8yZP`XrTAnYHU2Tr-TQX8K>XalJhE#_m>`^FG`{u5WHU({F#l*S$IYMz^eJWt0JbZZ{69OvOUZ?5{fX(_4PYOLey+&IWD+uc0mV+yyDhw5Cv<$9U!(%fAv zx16}SS}yyxdGEyN>?I$!>xBo{l;yaEN>4n&E;P(CWjX9WHk~Oxe=N+^bs1f}l^Upr zd9v?s&QCtoyoy5WH(zyWTqyJ9YK`Ln=l8jCZ{GJY4S9xf zExLT`**~M@#Vt5q;B*uIU~Ynwo8W!sPkr}k9H=Sc$M92skt6VrfB2U_%C&|o{q4X1 zb@mTv(|M>UwFK_mkzy9`(KeE~R z8~@+pd@cXto%=UNDi6biyZ8EzQ@ITj%I7@b*dj0pWwyplUGkfR8al(K3>*inFgBRh~|8e-SU;nUM`nTV|^Tb~`BmB*c zQ|~+cg|wUzV{t?ZL;QJvRD^g7;|d<(B z@t^03e}Bwv{;F4)KZ+e~l9Ay&8M)hQ$RlL${Vj|r*Y|R|^WiZ$=ilo62X;dEZc>mW zo^$5jIhVhhPwHm7+mk(wAgSY6F1MD_-v1lF{g!Se*5zyu!x7G9{6cHDmizdjKHOS- zM5yB?D4T=*E53KHXOD}peB2_n-crqnr_H|Naa~>>H;u&+_I~#z4TYxhQ}|VUMDe#4 z^6MVAojq>7If$k-e)-{XM-Yj}^~>YNVNDg%Eh9p2eB9w#^CQO2-3z7L&mT9s@$ChY z42Q=p<2lkT_i}&S@$@C)amR1+p0DHP$488qCyyB6Rga6e==6Cr+>AWl#ORODTlu&v z>3aRVANm-9Hy(HRFj%R>J5luWqQ^~VkBelIJ#RZaFP;Q1TdJ#<4W|$vxZf%tc$`Q4 zi1GIMS3a;mm9K9&6yClg8`h2wTw@v!99>#@ekNhXyyK^!8?KDVd7Lz_d*X2Z#N)kr z`yP>L+C6T#c|5K6ck$-&b{3rtVYsAkC^n4WMkxNegTcqs2ko~K@Ll7D564FhHI8R> z>3)z!6qLr#=V2i{7{ZWz#V3SeP4$J(n;tx`=ku2H=WQ9!8{6`{h!w^WK0<(TEjZj0 zL#o>Hs~@7XN7FE4o^cnKK9z1{aZZ3?@xoi-~Q>_-i?AQ_{S5E@h^v;`X~BG&qb2s zSzT?z5r{S9jJ(~=wGwK|uD5Y|e=){hhCrfFuQizD?ZH66!&XB?H;Z^sGI(m z$h-Uv9scj*R*MBMHZTr6k5h|C{5qd>#7E?vZ!X_mRlL<1Y3V#}&Y^Xn2#^Ct799T5 z&DDgwkV|(rE3|Qc;fHFtb$-=%I5J!r*GEnC&Qe3z(co&@(eT?}|KHboiQn;UkvooA zJ7&5Xu0S`3tYE`Ft~NYwGuQb`_?;o7!ryRs>~?dZaKHEM!sYPDY}Ik)CFI4w$38?& zHz@Y}BvY&yHJ+V%L*dbVkgx8lC(SlfNm zMf7vuNozxjVeVVbeMWX79rk_VT#h}!p?G%_HArzx1dX~mv))MGtTymuSSAGmBw+Z%frcb%z65N zu5NZ-d6s)rCAov)8#cVJu5jn$2e8L+G^D%FGwh;QuRAW&G`1cNSCG1uc=GT+>Sa#P zPy_sqGThZHPp|Z-%p88L;NeRQ8_zZcBs*`ROrI3VM5b_t1Bg3j=wE3?ouq;1m+rjW z`oX!0I$XzVgYO#-%J@UQ%-;!p=%_-Mjk!gry3<;zGu$9ZI1E9AtwUccr4eW#aQhg1 zICuftdxzgT{HMOkXC&r?b!9k~4t73{j*9V6bf^G}aj{?K_n`0+<7)HBuB7|sQH}R! zn@>5dH($mz+g6*$p%xFDAA8Ov+vfR$cW0+4(;D&ihu3d>@BA=b*m(NVy~f7jw}fnB zaE(e&Yqz1_^ef{in7b}K6e4R@fkiF+R_kH4Yj_uUb%*X7BcGkCQ|8Vck6XZ=N`K1z z8N0}#Y<7`*|9BfEZnu$LeP$bt;r4DD?GxMhiUWicTI}OVTjgK<`1j$iqoDfJ0lL@$ zLVOo#!pQCzFo#EFQ{sXzbG{)Q8s{F3Z>-|N!hiNf9^Q}%2LU1+9rq&wONn{ zisMG@a;xa@jq5J*W^p?)hJzT#gYzOC?n2_`hM*ddtGB3IbSK8KKin!P9N#_8fWuuy zpw3HRtR$vf#!5@=kt>$ROPI`4Rn{UmlXh_|g?hnkxdU9S@7Y%-0)wuF&%cIry|zcXMl(uOUo^7o1FjO3b==kl>IAjRx3=Wa-)D zyZ&`2J)}yy9OYHz6fZ{i=Jhm}>|<;9S{lLb179&9ufn<@Viw(M0j18U-|Q}3=0C>a z-6BOcd>vLK7hB8`4n>SjC#CN!TWt;TC`M$4Dn4zvmz1KVL~-Sn6H)f@?TWTaTiw<` z-q>ZGWO!Who24_)GY$#zkVBA=mf^vz9ouF2R(O!yMacYX z3>L;`i|b3vABoYk?*#?ynoNu-QH;774pQ{I*oUzFI@vqEE6{}S>ob&B4g9`z<`&~$ z;f?xnZ#%yTGjRu4bM-k_dF-IX6Vbqh|54FopSPlMy?t6V!WxjSoj|Tvv^&_*l;?6izojXI!6QRiSHk&yV-lvu?wcWGl&^I^81}H}ehCqaN7ya-*6b*bk3#0~J$ zO}9kFK(0hvv2yXzwJw2aL#DovdcDk#M)3(>Gs1{|CM;&X;Q~ii@nV+KhQDuw71zQ_ zs&T1!^+s>KxXjQF#t||xpRhl_s{D@S%5)#iDeDL8(i*0O!_j$es5xT`VOZ&fu5v}o zi7Eg!Ek4}hh2>jM<};7ChS{Dt@n{Dz1wH%QArS;WZwt`A) zLDgYT#Cnd{p8nUkNqgo!TOx1Pc%x%Gta;_Q(KEJ90}U++M{gZO#rsDta8mt`a?AO; z^QT{WwO@*27T_05&)E~`}w-3vx zm|W+D0!~zT#(JV4EwdKLM+5J(2>|C=3WN(&4uTmM6LB_$#bTYuxv=)ZjAR53vC@y~ ze&wH|ZKdket`O*U;Zb27fIBZAKDmCG$BF7tQ-=cjHdc~B*^v>9pj50#c|Q6{W+!=| zv!dZe@u|q5J35qaz)*y$yAodFs!=EKyN4h=6P{d2bLByLwgLRnlN z3Jqt1kuzt>*ecY=ID?Po0(2tr0ppdle4kv&;X)G7H_RmVbtgq^xfO$0fdim0?@V zcy-uhnAcq<~d$dj3~#|AJ^RMGXLFY}+ z@uwenJwDPazCiB7Z}XFuNDPf}l@C^zCBz3mt#il2SjF{m2w1Y^+8ZvXVV@*hU^%Nm z(;*0enKFZ<$`U#<0?n_;LoyIdU2SA3(kU%g_QpzXr|x1dhBgF~S_#HkBBcKCzOF+G z49}&Th+4`=fo8QP%y+!0tdH_(u2y=Dei;6cPJ2hFk+^*3Q-sD!zz-o+SLuTkR5s|i zQ|55Rd6W#d;NG2^kfSm|dZrw(LbxneR2n()IIGo7*%KLN0=mj^P7F5prMUnJbhx*#Bt6Vy4j@dgZBeMh+C4hf8FLX&L8B;eR$O_YbqlQCPEQw?3Y zc3I)P*_qn-s9doH11cOm);_M_V82zHqI9_T#TsX?%##A0S}eJ{Nom<@=|m0q3vh>t zUTJ0=@Lj2Rz$8wSThoeqSEjEixrOY56UHEs;0!Hgy19VOud11}dkUinf$QUhVFTbA zw4iRRGq*P(XU+2cf)DY8N8453%5|Rbi28UG;G!)i()>1M!m=hi0*X@fK%57df=;j@ zjUm*&M(pYXR#NS{<8kPyia3nKCuaUTdzL^LAhdHgx3JQ!Y@lUW!8gV$!Qx9m$*5a+ zpX7s&C55qPZgUCNZ$4b-N~4OJ9t$|J3b6<{m%bG+K*}FWSa7$y zghkD{NH__Bwn!MLg%bg1TwW$kx$IcV!Ituw+g*w(BrDN^J|XAVi}v7(k83E%FX*mp zjsp{|Ish~A{%5kSIuhDDXF_J{7HU{R5~grdF|_-0$u?vf@ZR*cX~A;@D2%(c=@P|K zoJ;D#JM-Kh$d^$vo+_5-oO#@;?};kK{B=>en0K;rJ^YBUI!l2YVNozUS+%dp>I(ru zw7*v6%%a-zhdGX$|7SpOZ9o8*#BOCELbEF8N~9nh7Hu`|eBu_WKvH)fcU9jSeo=3h z0E_b4vV9Z->kYne<$b|l8n4s1s#3al+8$ke+&tc{e}ifb6SZc=%CkA+BH|GXOrI81 zA4Fx_Uj}ACR@22PMR=ri>!a0c^0;?A0IxG!oLC@>HEulGl`K*HwE{D0U)8Td1~B5| z)eKDkzMcBBX?4rxskUxMj$fs$&fI#` zKa1`oi_+MGPE63S-pnlM-G{}?(pQa;T)8d_4zu80#)N*Bw&9iZVB|?d)@7WJ#bWoS zga%xNjUT&~>@Yc2$qc-OO%mQIZiT3D0v1@}at^G0*??S|O2e+MO2emaJ)@;@Ds`2j zhQyPqS|B!ed`k8cb`dyrT@hI!E*8RNDfCczLoC8Y&U7Q(I2P{06{-DJxCgUM-O@IT zaBB!F;WiLlZ~8`y)}c9}(3!WE7*`MU{m- zJQLMdoc==mM|X*FB@xTsw~U6WpHBb9PJaPTc$TUoip#+(Cjq2C%dR?2S8hG`Meig?m3y-n!u{Al3fl`mwp2`0ws?-7Gpeb=kT-mMVX zgY`IIfb*XW{N?llfu~eyjt=zkTvCd;%{E(SHPgh54SXeUTOB_mG$L2Lt-R0&J_Z)i z#L&n2lNDIxX!NoEeu1rk(0L~4$A#|6Cn{g77}rCo50r(dL&G$vEX>y!5?qw!m+Uah z4D##*LW>+41->YqEqj%DBWXbQSIO_jB;!wvpa4HpsiT!~x^-QcNh#fyjd*q}Wy9ox z#mTE}M|#XaMaH|1v;qPFu3Sb*fm(`*v8g|sonexC;(2XyIw%bU<>3v`z}cn}m7*7X zX1Q?JN(*$mr_vnWut0x(rLs_4FKeJgURcT7g+|FQ6^|se zMW9oPrZRb8=c$MYiu7~ zEaPFYe$=HXtzyj#dWN;i5HJ-&2vVuRrhDH9aK11jdt=VEwh6%MyG?KF-C+iYffLj>ulw|yvB z?e8m{RkRO=jn1%y@Mop76b!<%=T3qdQm8GPIW7k2SxdK6R2g1YFrn z#!Z)|T9vw!zLC=#!&4z?WG(0=x`3~h!iTy@%n)9uix|rTU9{_Tfxwnw!d(}Pbss6? zD?u-V+*(ts>;xHa*NB2guz|biXV80X&KkwK ziQ{-=c=$^aA*hkTZRNirDMLeRp05ki)ffsQk_Kops)Mmu|0ikX@{nUcQvi5o@V)^z znLmm-gSRkb2{19h25p+~wVR>NBH>_Y&g0<@#FXhE@#4V(%OqHd<+Av)E@V9zq?u`E z-CN|H#4J4YkS0apxIV`=O0mp)Cc+B&*=;^KZSLplmtwH}6Vq7Au#4NfU$sQW+_ zEaC?skNc@EvXP09A@=ie+?hUHHJIx}xsvvfmrOM-Rd5&vTS`wgiN|CF%RemM3Ig>H z1$>Ouz9?Y4qV<7*+iL`j0oZvf;H+7Frvm;$9Hua=WEH=I2$OOGVf)W8?AkC4#SyC@ z9>Op{%h`P%SG->aXiD7Rf4Cto-CA+Ofa|4D{R8HIdlZYNI<28bT5a zjW_6kjpegJTL-ELzH6RYBdh>+#g)k~+Et{&tZRJI&~`8tH9iH%Kgj}wm2_Pohr-N* zK(2c=md_VEJWIJu>ae{J}Cdj`4FP!FAeWqd$O_xAFpWGJ|r8Mq_nX`&=( zIqf3v*`88y8jttdtxNPz27E}NjU|kPDEB3JDqNBq;Ktd;Y#Lxu;yG^Sir~eeqOd~5 zCaT5mvTiM~e0G?Ao5}NS5Ew=6?0JD~UMN7eAjUL{z0pfuI;~IDb&LfO@Q_sZ{b=w!?`Eb|Xc0Nnxd! z(qd?r1&WPx)mBQ|de70uxEz%>PV|+|f)1qjb#@FFkqbNMtfaiw8ES#=s;mlOw^!K{ zQ6pc#xK-DBsV!p}#8tDX3m=g->T((?{c3g9L!t%zfuN=?pHmm8u{?5AWkL|?T%q3Y z-_h4TsC-Ug-3#o|T|U)VwB*9Ey!%XS`Lxy?zNBMvpqc|M_3AK*qt2CLEA=TVU9hNx z{1OE))$xG>jzQ>seAeUvXkT7%~^QwK!pWxDc-jB@^<8=aHl))|J@+ zkIsj2?_@T(8%#~dE^1PbRe<)dFjW9RW#^g6s$drtp=MH{Q7o|vtUj^53WkxeDyu=o zpAR27->SJet1h8$I|;0+EfFZ3C~-A+7@aEr9TEX*R?fc`2g9BkpTa$rK$6)4iKvgAGzEY=X)L9{wk@Z;JB z{MD+nL?epv*XM`oI0k`z_>Z1bLnv`L>0yp+j4lJg1#!>@5ufTzd`cT> zoUg##7_D_gMwqvHcj4iMafshOR)=o#ZWA!~_XfD~cu|3ZrF}kdJJm^sH_*}NXS>Ic zI~;X_=yM_3!c%l2=sO?@;E&5UaOU+#;@wAQFA%S2@z2EDUL)RN`)w`Vrq=p1>3${r zG77?yk@f~YwU4FhL8&>daI>2*2R7(B)WK2FaimCuRv8sIwuCd>3A9a3Lb{-TL4Y+^ zPTtqg26NZ}yx8#>_V*R)tuN1w$)mTr|vfVEY@evZxbIT5U9w0^L~_dOsa}wLelXC^vGL>J1oz zgqib`dZlY>O1NL=$!2H+ccb3wW<8EMXbi18EkqXG*MP5wABhw*{O<}hM70(2@zi8J zRahx3dx4Q`b_{7y9J0wob`+E~8dX}PV=PoH)XTV95}N$7h4d40>#Z>p+a|2pFQ8k5 z|L8-qCW3MCAVuGezjv7QTP6O}=(3%ligRSqnU*zl!`T&_3NE%>=e?zNoz`a40^1%n zrmovGjmpRhBt|$x`fPvSYZ)05A(B)3kzh2URy`sCvvBr8Ru#^iB^e#AdW>X7Z9N*N zg*Z_G#N}Bt?p7je@w(?W7rYi~zAR?#OOqrncVip2$40%}c$`d6%sr=~pdO?}z_6K; zG0_U;$uM2SuA@Kh7^Zd!=ICc(x`9<`SX-TMqt0qSM+SBvs{u4-KeHB5438`sx5B3ZuxMKC8rfBCkjGfcfcTM6q0I3$5l=y^p$={5^t!NC>ZeIE5Qx@- zzy;~PT~{E@Y#~LvK5g(27V`}d%anlCNMMrpPP3zsTY1Z~@t%p(5i@6wS~8@+5iPd% zblnu)4dYYLlscVvca5z8nMcabY7Bpd18;JI=91;_=wMk)EKv&*vBjU zKNvPVGx{|c#0{!bC97G7EjELwu>%rpq~NA*o6zpmT#bdEFAKUs<m)!6 zD@9|T9t+cpqMMB`St&Ycgxyp$iudsR7DaO*yq(GXX!UZjw6T*cP%Z%4hGv92qXiSM&L)dM;*d zFjsJu?&v9Pbmu>;@?Nhyab}$9uKj!Ij*O>k-DMSr&vf^NOvDHbQ3@Urao}7f`^S!| z^UqAgwV4PuhP6ixqPeJA>y08FQArdXZ?arN(adg)SbdmlSQUi#xdz{K_tAefUj?AW zdT-wLGbrx*$@;Y{f;S>%PC&;Bd#DS4K#c-i=vt`$stiF!S6e$R2%`~9tVf#43c+Kb zLb|otf+0Hc@!xkc0824gT?YiPSw@G~P*f)%$MP}*KrL^j9<%6{+6#hvR?&d=q(FP3ztz9WlTdYXJud{*Sew=JJ(ZV|1jgc*>qFc-Ub4}23#GI`3^(YmVgetqAZYAb(RN8*wmbsvpp}NaxUV(>5 zWu=G@eB1d-Y*fJv{rjr;ILstAcxu81*S)8UqbhzRhJ8 z$3vFzILNt^dnn<*P)PMN2z)LG?3pk(9Qt=ayjx>>Q_)11X~&x%S%#9TZ8?(Cic!IE za*+HVUVY=$G~6b(TVc*hd)Zk&?(zRW?Phy10Zl7Fz9E{=_Jf>SB3Ly(*be4EC5>U4 zH9f=wl@UT=>;>#Jw}S@%m*JqtvANj}D)v@NJj#A4Ylh*kf?qQ{*iN-iLC0*IW4l0A z{=GQEQPv{nrxJmadtDU2H8xO$T8*v0v!C&xZwQh5`F;T6XjanB?R-DO+K`NE?zR2U z<$~?xKpq~=OnS5(M~bm=@AVgMC$tN;Gv04$2d;>=Gvc_AwVf=!-ooKOt-e${dApsW za(5iwlYe*;kj@wpUHI|c1aa`bcsDzjyNF$bGkzbc#*wWTZsU*d#_7dLr)*;DJq_%a`;PQ4?8N53@Z0cFeSXx#57D0=eh~k> zOXF%cTLa?S@Bb6y5({T!Bmeg3oh4kmv5yJIXAZAjostlYb)*LTY*nUj7PT1RYB*+b?spnoshO?>%o(gdl5`QGF#!n2Olsuf@v z0``0*p7I5IL1|2LPwI59j+-&+-~L)NOFN%@IF|tKYDVM9R@kw|F)@#vMbeLp4a+7y z9{1wqkhhz^tR|E>FIZur4>o;nBh^cB`>}A?9lZ|5roF8d+dL9^$@x{+~qqKV!cCgfZXWFbG7;R^(s+ zm8d}VL3$@L5oqdTBKc}w72&{M4Ig!~t0vJm+6=EM))1g1@AOZYioxEn3L?8cNqB<5 zE#5{*CW2N7@w&>7hr3Y;fvT(!qLRx#k9ms${=*4mt3ob-)S8}5tO{ZP<=t$sU(lG3 z`*s01Bl4$`?{;ExSi!B}JXnTVE#RtDuX6UsmYY5O?0P5Xirq8cNuQ;;XnF|SG&+`O z8?k9t7jXeh*lQRv2V1%oCuK5_M?s%!vm?=SMpgAT^m7Ypx-29B!*Jr$muj8;>~6!r zgt_Zd#Q@w^gOr$CRFj+&L3n19uwm@kuj|;!wA=(3zNm0J3vmmjml^0S6OpSL1J&$z zk-Po9>1z_^PGi^LDrJtiq&a>d7B!UARqyn~T1^yU71k4+92$pcrRKP*V>s(L%4kuV zgTcGSPy(54u~RSP^xnC%-_hrZ#}$z{rnGU>efDuXPx}sOHS8x0w=d^A@#-*3C=DGp zYMXPNdtSpKbHz)qRB!0ZkZy`0&QNO$Q}S2Ai8u^?v+3-@YS)fU^T$mS|8?JVsK|o<0E3(~Y<4dSEJOFxgEoj*4O}$$PXuI_8RbL@&Gu z_THWE?2RT*G#`klUf}<_*|}(=(TzVzep>5qlLKgc zDk+gNN$VE}7nB5EcU%_o?g&;dML+&c4aOWDczucfDAd&H(X{I5Yow zJWQ#V`FWgiM{a`_jO?&?zNNHP+?;@z4nc%%_(nSQY)bpF6zRTs%y;%@o9A@t`{oOn*jJlRA`skd zK6_0v= z>j5B}Ng*xOeb?}+IB047LoP=buPkJ`yk=6KugiySAD9?I+3W)CCLeC2#O*e+$UZ*W zMq_eiw~h9RZG6S?bA8;4eLN|72eb3z-$$6z`_K6^mpgulYolg`r4=d`u8q=ERnxoK z1~lv{EHjqAZyD8$EE}EyA@_*vq74Q^7bURf=Y}bF zt9(w@XvY=#*trl<{u8%YG!7GQG_kA6r7IzVX|xKP9`6R($J>zvGzduv(iRMPAXd*a z_jvpkjTohZZVkktSdz(?%i2*f7(+3fS{kP;!kTf^|IA)rAH*bJE;R?U?}xjS79 z@K$`Wr1l{I5%ZBzed?RH&m`3YN%dQrRZ-DxNB7bwZtFz6APJW!MZ>N4g#6_z8@woKc!r6Gs-wpwP`|FVihAjCi~eNA8kf$tKGQj*bsS$;Q$5 z){ra7#l}U<-ps&nPMEP35T`0*c@?(yznCmtx4*mbVM zz<^Ve_lxkjCYQF*P684l+}XIBj;|5$(UNN_mNS-%JzQ%-ia~GE*S(0H8;yXM_c@0l z+Dd-pVK>IkbcE^)(Xj^)JImk0o3Y{q0l6#@n5i02gp7Z{0{40lNi!D_JC9a`wIKwR zp??HtM&ZDdydE4eJ}0_@K&B2FG1`7uBK;4L@d3sWo zE#~`zBcPwv!=fxFEK^WYXK+zj${4%sJcC4ucMmVdYpAF=Fi?22rDRJFaX1hT(+R%K z`~PE?+4_!l8+B}Fe|DpOyHB|M?TLLN9?Pc5oCp{M z0Z*C1VEoqvku_1h9d(WYfmtc;Ub%7(#nTsF9sP%rglW3I6q-IdP#=s*z-&Htz}{ z3XhWE7Tg(hQ?ZF1$fM97!wLcWSTSnv6ZUnhy|e8&%pyjm3zB)UUza;~M34bDUBf2V zki{dGqK(Cn-xZXmo@T*ecKr=-)cTHe$0ZUN@C6%00K205UL;(?c8Vn!Fyq63&S8bo zhWBQNYU8tV#TE=Rba3W5nktH%A?e@+6*d#QsZLbwHRzsf(J4V9K$lD}{@INnW%TFxoLbmT}}IztqC?5FefJkOK~o#%la%bdLUnBA$*=)`yU5O z@LJvzRf_rRqH;Ei=q@YQ!;c87vvj->76r4DRr{K(z7TLl`)gIMHsW7m9p>1|&w%UV zfD0a<-O5d)hkTwKy&O>%08{I5#ZW45E9??wHS4O_Y6vy9G!xc@Gok@yaWB1p3pX36tWpeWNcA0& zHou6p21RYH%;K%sVA_3(d)!6|zGyO2TUAI-1Evwq(|;#S%zU&W(67?|thdOq3h0&b zwvwihuL`LUb!#MARfNc?#B+lPwj!Mjh5gx}Y^q3}%M_!X{ZtX>69Xx1lhZ4wDHz?JI?H+a?P9u!64e1+iXb(I7-*bJGEiF0ep z!NL35ga&29VCOYPQJ7U5ty7JLDJnw4TV3K}wd?R8AU!OUhhgX5nZm^Y^bMUo)i3kV zs&T7vXh9i%u5i_ zRhXH0E+t#ZPt6%1%JmbX@?zLqiz@C#1weKEqNq5J@KjXoM?{4=r(r9qEWq`dsJ;?M zamH2aE-_SRqlWh_qZ{{U9CdLVRnQ(WJ)sB}254{{mPKScI!#xuWwM-mpZ$?&(F)ca z)HYt%D%BbhT*Vno4TosN7S6AxXwQ#EJCIVa4B#VfJAV(t%<9!^stQ7gY~X!ozVNtq z)0{7?7ic&XmO1KZx|mCJE@%IaC)&G%aO{rsOs1*wMoYr(%A1DifT&#<-hU~_tr+A+!IX|71F?n{*{O2Nu z=1~2a%Dgcfq3Lzi!+lyG>k3MNBvo~;6=UpSPm5sP*+!aHJ}WXXM0{$*+W>k<;L}!!8`D~ zO>0^8&%4ud*V?ck9{0n;=RZe|wI!cP@;e`=O$2pN57C+}>@<)BH&fG)uNh8w8y!G; zQe8sM-d(I&fd*|>#Sk=!K07>5CPt_wZ!5g7fo*zW{dpg9BChln%YYCYm)|@Hb+qP{^+n6(ZC+~ZH!1-1mDp|=&YE`o8s{8JK zH?jGRO$q&l*6J{{!V^&mt~6q7!TLgW)#O5gb+~`DdzPh=9S(rZg3&f+#R^Az-xUdb z8DzSR>6=qoY@aIHJWl^GKxw0yFJ1+5xTyWrJN>t;vhrcd$3 z8?VuUlaWveKnx$TJM^^()TsYvPAafIXFMe=K&xeZ(hqIOx9f+9-G1>h>=Gzn@4#+?O{| z7whQow?@S*v`!RDdKOrkl&h(2c=cd@QgWyG@LaNJf)5(tpNe=3hhZB%|FwCj^&|j( zOBk5(X?EzEm)WQ5xym{b3R<+XTmIoV}@Z9n^XB$%p@X2PwW1?!AB z`7Z04!1dcGTVYePr++XnJLezFTTj^WZ>2Y;MRZ-LTLO1RiM{*NWterC#N3-)-$1-m zsrGWT(G!obTbTbI9rK7z1V01&JH-gT3CCi@C*K~T(v3u-ajl6`L`P>&(`y$kI0?gr z{d&a2*rsG@=3GJ#BTCnaG&RxH^wQXyfgG6RCo?$_Q!iJ|51Ew5<)^xf zk!QZ!lhlqIW3X)YJfCJjUAvq1uVUJw{aKD$SLF=Y?TEY8Z?%jicnQrj8K|PWu(Q2S zgvsvAGn;41*rU5BvEO7Du(DeN97L-Xby84Vc~*wwlR%%}Az+{dZ)t`NKrp`M+}g~_ z5HDYY7-zU4Ch8_d%fn4J7&vLL0|w%K9B`$>J^(Z~{yd!_{qWpG*jhT~grmZPV+N{% zf?29|HK9#eVtFnF^w8D4WMa1iD;79B@hMg;9yFE-lv_9#8~i{#_dXC^`73bi{u|{nb>bo0222MmgI}J`I0>dW9C*f=(v| z9i`nvxP0+g580=qbuYKNaIti8z->yTeqNv1IKGD4`Vt}&qW9)=I^K8B!s<6ZLWT47 z(O*ZXzrUMBwd*l1r=Gf-vB?U6*I-qEhS8wZFW_%$4`)*iY3`e>LInX>3wsT4+~lSM z?Xjii+Hhi}QYd_QnbG$;>b=QjipT31W{aaLRsK?whOFGlIC@;f41A-;-)T8#fevsN zs>ovf{&?YqeyaQS=ju1;Wbw{bMR<)c5w>M>V6#B|$zv#&A#Bs3+AZi}Pk%}!gZ+RI z|M|b_^Jfp>FOL^xs1P>n?j0zf{nXNl8x3&QfnP=V%=ftsxkzC}PI-qYuP(9ZRc%5} z-qΞ+T(=V~b&gQA<*pL6gDqg0n$r-^^@S+UUc3kFl|^S5MnTtX}A4{|7G_5FaOIK zcS2@xgz6xw^Z{g)2CA?Wy!Fl9mwc_ zbAIzH&vM(wmz2<{59vw%x!>s@@n&-&f52X!?g$A^lmmm~w1#;E6rUk*lIpG*tMcgz z*~X?aL+^H1^&rHmbMkM|WrU;chxp}|cxpCR&^3Nm&UaNTFD7*$ z${b)C^3$7LZC-?5Qn(Z5!faFWC$nX)fcNk(&p;i3C4hn! zhzrR@6JJX~2H#6??9cAg4|i_V;4x`<#Vlb?1}%9%+;QSS_W^IkmXKvdcwX#4r+GOU zqm3~?=lHo-R+91Z-^~04r99sJUrw*+{lU%TY$X2yEIis*T<>@HH)jxNk34qmL?up41_U1%dF~h} zZ#8Qu-Bngq!=+P=8qa)nrBm6ql%I_rnAU>0PZU^I%C8{M#Ccy0W_(3JQLtMUI7fP! z1Bb|;g@VJwqt_u&Smz6+lcF7ULfoV%s9_!#D3G=q zj}ntFi7E#+sKDZ_bb&|ex>zV?EFlsk)dzamZv<7_Y`hXF z@s19W-ECqFg^;JG4Z)qp1^A)L=(u%IG1=y1!|T;pg{vzv#QY^LS*DvN5bl;4t2n)| zFF#rR*v+DlssN1Ia8U5`-UIB&lGSObe8Q?DtoT=>%siG4N~chnfepvGgF=Xs^g}$t zfO)9XPpFJ%5pq|^AAX29JBpb^j#a*zDD!>!B`Y#&SA(={?$;@-Zcgmte~2-TFdBlo z7Hx5z-a`YbZg7)db)0|or6hfuvZRi6kcs4gFRmcmQFWX}$X(fIS{qyLvEp{K-&sG(inXZ0WJW$PLeav}%YC8~H(ZBSDT9Gy6hBaQR{MV~dsY z^wXS5{)RF6e(R=n4~H}GPT0JruaDVgCmyfTW|(M?xvkD=;UQrW`(WK8A{B! z{!ry~`!Mk*hnD{uMw?uP)ZhALM)kdG2Wt=VsNFE)MD#ap@UN~p{kgpUY{CR(Mu}KJ zS^5|xrn&zd<08XbvvbA=d2Rm^b$A z=Dc&gSDK9s1%sX=Lc^fG@whGhoI?@f?Z( z4E@u_q93f!Lffi@(K0d+FIMEcjtNWQ1n(o4Y*>9*HiJ~&aU8>1=lU3Fg2;ngA7x{B zy(ri_dPltAuowO!j=im%(qVJN`kFSzipx@L|MwwZ0q^I}#{_=+OE~?B?LY zZ7CG2uDbV*Bk-M6x1xNi5(xTfr<`T4>r4F?7c3vhap)b!=}YV>H2DKlI%K;hi_j%) z#GYHzC%JrkL?9~hHO6D>jJ(EQF056<%n^Fxyx>Xe{zem+sUqygRCs(!RjW$<;J=S= zxHW|-R)DdBB)R=0gYHUDIV!RO6xoS%8p|F?vftAH|1PqlpTx-yc)6Eg^SRq76r<0F zaqxrJDmItZZb<19`za0?wNW4uMbzk1=cbcg_N^a*Mk3XV6^-%d^9x0@BsmDrh!NdC z)D*860vT4wKOdRPBCW$M7+7XBC~=kj(M$)g!vUo`A-13^$)MrNSHjK&KfRIqWG1$zSZKvy{lR#T=aqu^ z2}N}O&r6+LXSQ&~5|zqLgUL|THx8MgA%2zqtTa^-5b z8Z|R@gPbHpKPc&$ogI3|VjVeXdqpRtj;7+Bp`ks%_~Jz#6kH2s+Y3Xq^DNJ7%osv+ zYQ)GDKxJ}l_XR$G3P&>jtn>zIU3@6KCj6{n7Q*c9zeP$Ck`tHZ2t&YXWx1bcYb`fp ze3ENA2Qr|jfMHZD{igwnDLA33d3<9U*V>EbIb-B}T|aTeXk^(k99N_W`5d#PQKyj= z0W%AO-b7@&%36SkQBvtZdVW@!bO9Xn_eP4QOIr$y0NP&|AEgPn31G09V}(NTm!^;i zx+V|(l=`*@1=iT?dV{&TVfu4;+{13R9#6^=HC&Lrus9XqGhO zb839?iE-lys;J|n)}_$-AeE)j<2_cH;D`G?^9ri~1l$;ejds>S(`7e$= z@`itS&RC5AECHW9V;;Z$k;}qhi>Gq-B@QRy8|=859~Uvxk5WIu*-aYoeh7M~`7c{t zO6_qCa-8U+nG3Tu!ZU16_B;5SV>@AHbp$ni44|SVd*erwqa4bq8X?ye$yP@!ZUI*6H3b?TuTHd0X5|E>e<1fiW1E@?>%TGRgHGkGogWrs9IvfwT4jK34p z_H9VWJr->acZ((M42S>u%+#BIJ~PTHE@w_8Z5$>shvAj+D_LW-Wmr5xLq?~9P&7L$+g@9V2?#?0iUQ^3L__p`yK z!mfsU!rp_9NA}U<$X?5v?_Puh%VBJYEQW|?_F%|&eg4@S*_Flm&0_`Z=V0G;pW~y< zQ0%AxeyPdcF`>ZF*H7=y4}-lq^!D?v?Q3)7UFmy%pOJ6{l4f`>qBt3PDe`a~la--w zHKijoAy7iO)q3}bhJEDDf;*=PTZs~LhT;&}B!$5S6wAY(o zEEYtr9f<)Gm=cOQ|JDK_+8=~HfmSmR9kWGJg+LN^h(r8?UY>{k63=0EYL{G7<@xP} z%Q&y-4C>gIyBhg+pYLvQ6mdg;Zc<3uw_}r1)5mEE!;?%q5P7Lqzj(NK?JU*YBl8i3 zR!hVPWTL>1GFCCjvJT{SPk|lQWsC_uJ&Fm;tfO5)t^20S^Ny}vrZ|KK@@{<%<)7ICV{)=srox~ z5Q(7QFOC~DQPQbok?{0>^-T|~IdS`T>NN_z|gcymzf z9wA159A|1w#r`np3X2q-1OlVfJ@ClJsX=t&h%YrVZ!}E>~vfyN8#|)bM)%TW0 zf8R}cm9z_SE^oP(?nHzgo@0K7-k46Qqi1{Bo1RmJZr@R z^*|$z$Zb2b)C%Ovv~D0Y{UoP(c$9&fE*qlO;#>(CX1dS7x!>pGYud3drbOS#$O%D} zYAn0150#JMEFAsLMyT%wOL#37gLq6az&OQoj`)-ducW#)iO?q?zRou|2RXEN z6oICZYHFg6V12W{!o+#)?^ex%Oa$V#z=~;InNY|>xiAvuVEa2q|0pF&O@h;>N0sTV z3Lc3{uc7pLF1V#XZKSVetwUri<$@y>aB=C_U@M z8F`EzIBBc5xvgB#G(e>wr*F*bn&tOoI0VL$M~-8oRa4^0I>qPRTJwauMY=g?O57l? zE>K9kxRi?{8$%!Q$uL?BhIdtn5QYmI!|8FJpL@rsfM#rG7~+YI25lHPTw5b!0vbKW z+e#wZl%6Gz`cADnJ}V28>5C5RU*)pyP&X0%waUdkP_(N@H{?jxh=C2&zj@jEcM!Mc zCvaik?Z#T;rLL`&30`rs%IHJpi+XZ))5yR(U{nQ}=zmyWFUfz_C8f}&^SLu1${`0> z7YE~yE<6@5G@-ICJB&f*GRE4F*Vn-q7HjA)r*B<;D%veVaEmYUlSq{Y@eF^r!^3?a zgGFq-bI4~B+Z=M@Hl6moKoN1b!UvwQmM~?hyKpEI9>-b@?1LPNbXwsvO{WyEcd)OL zn-chCNuZKz!c3J0TWxbvanpPDqy-rdEfi)!^lUl>t!{-4ubI~L2X5IbN7-jcv|)*f zlsS4sRuVa>V`IO=gU>`6fEnT4n1rJ~nnzLlHhfxaKSRUm-sa-hoRjt8$rQM)Y||A} z&Uts0xx}?=0j2BYsAPO_5*W9}_&E?&lzHPB?M&TJ$Vsu;k3eE5yQa1^G$FNui(k>j zzNnV)=7%Z7s2uVNWXKn91w}I8DDVwZbG9}miiSIUV2^%9OIH^L@j+JPkaZbWkUU7oN|Du$#& z&XD822_HAHplTBkon@2Cd2mOZC`L!KdKZG`Jdi|srg;+wVjtOG$MTIso{w$~Ot}`QtJe2P1YgyIi>x#)n_8=!si9Hb{7@9;IaD4)34$TjiNnuhRGu%26HJ;|MjzQxoOO9yY+ zh1>9_xsK@~)|i}_D^ktWn2~nAlg7_1iHhxf%_69Qt20up0sF zI139hjB|(xl4_U{f?81)@%b5lc195}lGi_2sL+{cQgcI_@uG!mycvai9_N!La7rUh z9sKFMYwn9SkU_qX5|E}x&M{IfAvO|Y%#0X8;~|2f%pWAPf@lYaayVT92RG3Wj}pjx zF29dB^gXAJL;MV%CecWj-%f+7VJFK? zqz+bGIrWMT^$~^jbNetNxuA)W8+`kg3jkf>)-Yd>8|Q(0bUc6l3Fjbs!g@*9s1H5mme7Z`>AkwvzE{iygj_6iCKHUff*_*P@{RaD;r zj}nn3-?S{o(^f;ZQ_R@gI9pL*s-d#trPHVIp+P~=LJo!%j;84n!;+M9X_K;QLDJyx zh_$(zo6Q4c4++xJc&cSr;-o!>jM|v$`oJP9Fy1+DkOVX8_d$y-QZA1AB92> z-I`(IiH@~aZ!7Np2@kj4y$`%Jgwr?n^g?a}8W1zk8n2V37G~GUjgeRy&!P&-XE_&K zRn;w^FBLwP9F>WUY@Icw_MZIRBxJKRj+-;_XDTl6kK){p4%kxE^bc+))f-1fI2<)B z6g!jwTgAT2X<{tc#^l-j3KQ$a3`4EgN9n-)y4Q!+M3Kc?-el6LJrMW@q3iywlydA6 zLMnxkzJwLrJJi?x>JzN_oBjyOJ3Fhi^ko&_yZ%7M?d=0&! z+%>ZA+@5Eg)OGLooiCQ@Ec_FC3$j1RJ;H1Tl6IE7c$bAEto+8RId5EvIGe=q-c8W^ z(dpVtV5o|4RW*)~4uLQpAo#@nqOtecRJMN?_J%k9v^l&PwPs{bwcX?5FQnp)H>Ayp zGvj>l8ql$EL<)2;7jmxAq#wj9@X6tq0!v(24&WD0s+X$0dGWskhCA{K#PTFmDs}gQ zj!S1;nYfeU{9HIp%(^kRcv~~Z_BND@ico%Uya*%oFj+%&vmeJdsvQaw4+`JhxIVig zK82ac`N$MwlO4uCX58$SN=cH<(1m$;d;5kkS6t=nf|(O*R{5G?Ks1UHEYee&zA|7{EW+EBQS_ov5O| z3h$9Rt-rSs(@bU%2KuTAgIJ^*Rnn~_ld#96#R(%vSx;Z~t5u2rRB&Wt`q(#%bL~dw z&=n$z-a4|3v5>TWR7I=qtV4Z^Ova@{7kpJ1NmM5dAS8lV;#eh+$d{!mVo1;sTW6^& z$BnjWHQVL5NxiHuNnhU@x586f*T$0JI<(?+W*@kJlL?O>?$f0Z2hyU}G^q33yHlWW zMkO7wG|7T-+LVdL__oNBUbDONi6(Uv;CU$E7lA`8fDs|+wZuN~M$}fhvX-D*L^_~e z8Hu%E?|%*1-kC42Q`|5PcE6y zqn{g1<87lF5|B<}4@Yt}(SKE|)vGqXP4i1$LQYxaNn=T&5Pxrl>&X>oQ_(EVhH!Tmix4Z%If!ZPcDrFiRkOX2g21Su1*FydXEd zVfTM^F(;Z^L{b-4Xg6bmMD4SVMM9;<;<@BlV&oD}ZG)5j4c4&NDh0;_9R2YX`Ld3H zLNHJuwc-^mDt{(^PkdX?7!DB;6+6|ymfFLX5>$;?tQO<(<0Y>`!Z{Ov&?I9o5+>B; zt-yGa5FfM}m`0sblKg<~%aF947M2fk5xz0cgl*US@Kq*<-RN0k-TG;T}u!7a6*7@QU^Oz`JOa*8+S5s5aN3YI0? zf(P+ILW2+`SXnfpTBll!C4gYjpRZkET(j-;8r5+A3d`5bh;|{vR>9%Nv0^=*uw-Ft zVt{wg`BYo6gVXdosyM7mhka7!G`?80U{m)V$|}4bUhLD`vtSpNUj*auXp6YRgO1?{ zp3)R=${{_{xcjirO*(ar{bkyb)i9xalyi^^_>1c|1bjUc9>J9bg&>(B$$~1R9QI`Z zQAN|WI*kZjgjraOyoxbc*Ub&AonyLfN}N>`Ple^H>|Zk8R!=Sc&CU%FYW+0wPZyM}3@@&)C`*SaW4{YL8ZK~4~Jf2w{y6UrM@ zQbDDuc#yb84?Jxx7+asj@!<2^ggp*Cho>PKCFa5VfzD-ce*;>Yx=Z6Vkgj7{29u6l zgxRb(T}W1GDI^idI3gc|_GO%}bp>Z?X2ZWw@@x1bCQYw+%9HJ$ua!Gx8t7Y{iS zrib*C7~;zTp zxso})!Nz-L!74>u zkC$ahuKNtx3mDF{dB%29gbJ?aWD8b6RxvpOlfy1CRs?t;z?64kDW=Hk+445Ia4m|w z;E~Sl*wCC<5pqN(*cRXcHe^H>RyL#;mqWA9rQ*pi;vn%jSW+DQW9wi^bpXJG=P!g? zSfky}T-Ob$2~^X#&LmDBq4=_v{ssBFAEX`>_7Fa`pztho@nU6B_c1Q~^l7;2X0Qa{ z7nv#O+nLZEdk0enRRq%NeLY{^W|X(s3RMhXx?A#@=_;5U*;2NCk9oLTqDC#MU6*M2 z)`w6nDShSDm34k6@XS;&r`pplO)0$^QH8LgC`1~Xd)_G6;8TrV&J)KpBtKQwG-4)R zaC`FY@-6fmNL}bE_c8O2tAD|2)8N1clZde<<*B!_f(4;r_r5e+lB4w+@O)uI2uD&W zjcS~rMMyQwE>7MhCsCunqgFpT-?0%X8UuJOLARyAdq;mGCPh0?3(!(5c$KX%rnu?L zWh*wOR{P|zAN&bX-P~0P(;2)1zt`t!hfW<5JS#2+Ge9vy&Gc-ZidM(9QvSB}q3gAe zCF$9uK)JOacGN*z`58(w8c08TCfiEK6$8N98AW=vN1ci_N4jF#8GjMOV5C|IC?Iiy zs99LB3xy*OxO{iB2UWXyc5LV(1PU3U7R)!U2l_|=;x@plEe*M#=Td7CHua=#COQ0z z1IIRZv{%I@cW(CU^!iH=r2&2v6E;i%&g!+iUN7bDsi43A&R4pFi;0~u%ijdooYzgO z+{7FD{LCV1)Qytv{}rb_TIyA8wK4dqSLx*TIjr0ncRs)0K>Yh-(DD<0M6v(#qBifw zs#s)wt*R|G^inK`VAdzci~~#(X>I<%%@_m80ev3W09L1O66iRK%jB9nk?%BN{)miP z9>3R&e{?Chrl;jn9i0K@WS;FR?=o54tj~rid8S$;RhdlEtus70F?BB1u&JT0jCQAO z53airiR7YEhIq8}R{9~42P3#B?jklJo~Q=UK|i%t=9dM4-)&E3%x2*lmYC`Z8O`2e z3_9;?6PxQ*F8w3=6(hFNIvSUOnBelED_*5Fd?b@$Mtwx#7LbxJ7e&JOvz)u1zp=v6 zD{Tx9tL8g_uM&*2A&>F@#>86Kpav!k3cAjgp)1mXffnEWSh6yb!{(eXH0RR zx^aOuVwl(-gpbNDo#pLffoe=pxId+JviRg?*HbMdW#>-gz#LI~CYCeSG6rX@TDi1M z01)^CIlmS}B#^6|$R-<~sEaw@Vj3NyJ;k8kuI<*dmI}~971PK8p@_?h*7Y#7gjQmf z`peJe;=Qxxm=-Uh!H(5erGt}sab+U%bwE%CwP|(N9EYSU{nWrQ6<1sVMtb%0IYpT& z06?#rEl9NQs-lp|q=yOhAp`jM$mZz1IfXp59zs#Sx|#!e4nlV_Td5Z-d;-quuYap1 zg)JrlWr5Cq zGKR$Jj6_*rTVf5+wMcn}OOg#Rk=>c4Kwp?(TvEN0nT?$&%?vA5Tu|Stm9}j#MF`4! z&h=&h&Wb>DsPO1;VYy8@w!9z?%VC z_=pC^vDm_90jaW? zq1>jh+5@Z}vmse#6FbDgkv8lL%X#%HU$8)HZ`6+Gb`?mG6V6KCM9fNYrCO1Yl6@XE zLUEPolQV(pVK?Z`*^e51S|geGLUr=eU1XPhwuy))jS}|MN*jk!BTWfB1E{{yl_)7e zrf?o^!kMv$f)uXu&5O41COTYHGK}$*kqll;Fy(`@2R0kEt{N4@HHi7&*<7FGb6g}3 z+vw*dmt4UOZRH$qoiwvpDRR)G#Y96@DcyNG(;RiwCG%;fnhkQ>vN?3)R-@|IX4-j7 z;ED-xKiPb4VzQ^P+%Zpi`jLyCr^!M9`WBhx`1SX*Dz7i6Of}|vG;tB6!H%}=#Y;>1 z;dMb(|4HJwjf%*%x(KbAfru&8=s>r+2$~^)ajG^o&AgaH#*VQZyK|<>IA0;QibRFY zs4zniZQfG;A(?rpHt#)v1;F@0jEZld>5lO4BPY*+K+)SCDKVBEp?+yScPy&B!`}cv zJ6$O|J=@QWj0))gt}qRz&dW?WK+9t(uVQC;fui-Tayge3Xrw*>FqpuO#y*~OBmhhgEtMj}Yizhria zT78LWGHEWG;U#Y}8N*aaFxxy4TZw_40ujPTNG_GfPtS?{B?JR!8s@lE1 zn?sUv&Fc49`N>%n1WsWc^GlFezNgI=3qm^^# z%t!L&mZ862w*ZXTl^SiE%6r$B5~)Qx?6aZVIWuA7&l6g0U!{FEnRtWYLUPR}G+h%J ziG)%z%9vjTypjpFP>YC@Tug_$T%9OOCa#3(#&aeu5CGjGNYtALsum(J56)+KDQl*^ zc!U|Ko1=@W2xmt9S;ou1RZa%NP!Ju3}*u# zjT1&DD)D%Uc`Gc+5bL@eQ|MATJAptN)%UwIRK(6Uo~XvCrktb)tSe-BMekFhoew-$ zMk<;s^YZ0_R6v4ielejZ0~ajk!0To(UI~+UE@myu(6}fMg1J1HK24mjjO*D;B=wlo zWdwl_fXoANAp$sNDrrwuXL4YI@QA{6rYpJeg6-7qgl9x z0u2@7-mQjF+89gsZ}0dahZ_Vd7!|Shj3Fc*8AN)~*FYC2e>Oq7d!EdHu_u&wbCovW zDWoA-$aKz@TPe79X}l~?JiEob^CUMh-n!a=Z7GDOb3|&6-!y9oMo2 zxfP>~7o$BNqvscULt|RZR?4;So7e~wETo{1JJeJnx5Wlw%a}vds9m#FAl6XT)c_r;!xQbRt)D0BwK+p0nljm*?~Y#+Nk#`*O6jFZ4I)>B3$u9W}dXPP`ld; zm`qA|eq92W1`EXM>ene~q2kq5$p5<805b^BB>{N|77oGl#(92hq$B1dn4dB0sn!V$ zgzuisGx$tmD#V4}LnyhgGT=f7g`6%?xj8OEA(dZgNgp;29KBw@UaJG2N!O6@!8Ena zlYQ3L%mk=NPI9f3$3>YYC`C46YA^Xml6V>-Z(D>UG>nREDmRxs^=B>PhCGOKu~0~2 zV(N7oxCTP0%fliAkfq451uuq3Q5Gkd=q_%Exlmtc)3Rnx<5$lgkXOOf zTAaj8UQ`>!2ik4@?1?kUy_(79+Xfe?;()f;nqg0V8a zbJ|)QwR#cRXkyluX)97p5!=vy^@9=hK3^r87uf11=FpU6O0r*YjAhGt07)BSjPbKl zFmeNc)z$EaK7R#^&$*hAiD`qa3ASA0t3>$2`XTc2IW4EMJJ5aQaQL&xs||z%ywu+* zK1bu;GL-fdD_nl2nOCV3nJ zP_9EVu|Fr>M=r($3_ z&O-Kx;h;z{;D7z(M3;HLFfxn9r!&E{RC_+qRH#NT7D}i%R zT*pOwA%sCQ*KQ4vC}{Xofrxw^_D1Irjtu^C z{Cy?_VqjnWx$1)&dtM93tj`ASew*G zyWm42$c`s)6ZvxIMA$Nj%newTQCg}MPd@rvq4;6H=C|$mTM z>Q96yKP*l~L8l1rE`*?r`8^HGZ_oSLp;-NJOHm0)setLD`Zx8VR#-}aIbMs z3Y5>;O%lKE{<#te&!ox##&;di&QPOUx0^M4%0PNJYWO?*0UZY0t54<3=%(-cHDLYU z53&27cQTZ(tAp+z9?)U|G#WzThJcdHzrx*{0rj@C_|;SShkYD{8C!3&3_mrl2XhZE zA1yTgnlx90ZO&W(i8sV_yBxXluN#mr!VDO}JUGjq3wQD=Le|m~%3KhiOU*H@CZB!k z5LFb-T~XM!hx(25ydlyGI|d=bJ02~~e2j0^M!D&d1=h9xN%g-k%;(OV0`6~zl~k=E z<+Iu4X`#o>C`B%yB2oCWQSe~ z6{D~*-JMen-~R6`CC3%DdgvRc?WJ>S)fd|6-FxMSU~=KT)BEKGDQFOJ*_X?=d=xT~ zHD>LpPPu6{*mU$6528jG=d~!(@F=PtrNsSt`y0T4_AiM` zEAL18)Eh&BJxk2ti?10{B<7O-HD;}Y8ieO`!4ezI{^5)Aaj--sIuLzjJ})mfWQ0hz z9Umqp07h~+(f_tMfGy=mt@j-(W|j_&tAzjgSIFe{VIm$$ngHH$VM1i`{1^Q07Ztph zg5yw;>K3o3oq<66&*V|3%|tz~$MyZ&_HzR7D}N6$UgWCH070v{>~MHx>IKYw47u%` zh%xHJwd^|yUSsn+jWx5<%jUD%1Uft&i8-b0GCPx;(_<$S>vYfwEb+-F7C?}(qb?5@ z=1~_BllC)p&F^+NQ~jIPW%4M}kW~QcQNW(!}b>YB`;Cy0C1-M4QSFxZ&Jv zZTphA4p|pS!W7N9Mi(&AhUmsfFvbE#sMVz?2+ZvHin@=3^xHh2LqQ%0C|p1`szK2_ z(b0M)y`e0-g0wFbZlnStvg+o4HvY+C&HO3 zo?Z^*oJRT_t^$mQQCeAL0Td1d@YiXj1G1T5C)aKU=dy#~8aVxuZd|8-x;i9So-`)Z zu&Dk*fg>XY7ZG^Ef8EA=Rh9mA)S-ZACs+^xJFk}|E`Bw#OECkP92%*2x&v3be~v3JpUnZu~Fig5yAeiQ_4*> zpm;s2+G9ld+2RK9FBlE@t@Ssp?Lf^7vynz`XZkEzu7=M=O>O7a)Cb4bl%KCSlU{UJ z%)~|?(R+DIppomu=@>+B0-Hc9n03Z8H`ag z*rDO)KW#|41)U+rjt9|uw7K9>jV_ADzY{d6FE0K5_RzOCpoDhFtZ*zMegSwi) zzYn64P6?bhmQvkZb^o}whgIaeiy2q9@m(tJ=yYs{P7f!|Y*^3Zk35iF!%?=W4?I*e z`Uv`Un2Jj6lx_(xH1#OK3}86GP2!7HDp%^s%{;cbjXSPS6a zLf>7r1=2KUq4)hAm4ZBmD+4TEh#WbB(VmSJ>ra!dzDnu|b`cq*&)qDoxI&g4VOz-u z8}-P^oeZAqUFy=@(42GSnJ+p~(eLsB5}EzBj#|<5SQ$4yupv8VFY`4~o9!7_w8qF~ zCTz^Lm7YQeOhM2P?^MKp8EJ?-;hxJLoR>fYAZ8D5gaZ`V$w1|Iy^NQ-YAyf2#w)YL z8VkPJ5|7sVKNYyeOylBXVaXqdaZCBW z?TW-NgtT$eY z?#+wd&5B1)a9YCp?o*8)8k`l3?lA|pgs(@`i=b(lOi}qcD7w~d#|l>kWb~wE7$enN zmjy?lp}YC^XpBBizg4uF8x5{i!OKs)%L5PR>{?Zj2KleiOiq|Rq#I==Tmt_53cx@E z3;^nOYek@Rg&4}ERpqkV=bsJ-9M5XvcS|3(E-f4kkyZb_{lPrW0+iZ~fnoO!=L@rZ z#vcRG!3rv;_~3u#Tu~(^>oJ6Dc0NaOE9yX)=VbQIY8?&N$b(T8fhATQ0P~TTw-4L= z!T2he93?l=O_z8dupFwSP_e z$#4JJj>$oo%z0X5@_ZC385 z-S!Z`f{X`xc<1&m-B@S6JDi?n3P9|zK==d~TM2!jQ@zm%B758~0me4SG)FbuNOlwX>}g0-a% zjjH~(E1;oO7f_$)1R*`-5IbzgA-ba72yr0R(reJb4OBsXqBXa5kwyTv>!vXW+bp%} zmAz(e!ws@T69*YoLD34e)~f+X$UbCEVm8FJ!2d=G&|>|ISB1hi>{Xpf_|Qg7`!XU~ zK9FfbqhOs6uXj=A{9DM#0U8BZklt7Zy>W3H+k&XNt*A=EF(bYgWG0A28AZ)%Y~&a0 z*7S@#CWAjzGCX}F@~hUTU|HMEU^9k*V4nUxs^q_HO{jz6!}_T!0y)$OlFjej5gB1N zT)=7q`Zk<9S_4XHCiiI?oNnE550zg+HE}-jp++p%bt#_O z7}-H%30J8+SvOi6mY9ps8Gu^nJA;{FT#Z!fN)TIkPs~2yva6fAW>qbeh(88HFljV0zvt1U=7j1J= zE!`}pR}XyvLyl{9N+09~b`+=Qi^?8AJ)PmHrMrb5YmseB-I}bAhd01$VY8K9-spfY z7N%aBsygIFv^Ulr_<-{D;Hw=y&76VcDu}d5IW5Nrd~A4PPLFfmC08{V)@Y9GNUGKh z5+lRbtp^KXBN%xwh?gUBMlZaP?$VCNIT>_f+yWFp97Gios!nKWeO6hLrIIc@h1rz> zbiV+xIMeTaut~Lny`4=EWzV2U}J) zr{#tIS!qxv6N7G!*8Z10rxXC)aP_Qc8T{tHO;w^nYa7!~5PLMx%af(Qygqav&%Z}b zITV4m$ zC7y8D-iMHibTd^&MrYmT52koD<9`O+ehN%Udf%gJL4s>WNR2cAaZOpQx^g7m$3)4y z&IYC-C-9{322z?O z8Lla}&p>mS#Xy`MU3=`PfPOmD^Cq=q9*mTgoJg5q&g> zMIPZN^c7|l&k2=g3K-A!G#b)}9Ik$qEr5>Nkqp~(7*A3#veq#IUey4OF?~b666KTv z%fJ_;d=eRPW$z>K@!D9#P@418v6iaRqJ`pI);YG|AiFh8q z5M;8tjgyosmRh(en~0u_)mNA=g3!EvX}&D>s@u$$Ykp$BdY}1-Gwd7lVd;A7?S+m! zFQM^tyy3oSK1$fcG$A2LC{K*Wnkh))glb@LtLksc&qtCqmAu8r5B)h2+d zPtVhw-!YsZVy;b1M^(vGVpfmlPX4ZJC{bH^WjCfnYrD0lc7uY>%5ady311nm z7zOLfaG^Z0To#zRwf=a#WW~5DN#QY~bT7PA zEhN*C`1rb3F<*R6dZBr@V%s=t@ARo51%`kr$u0@Wab-WcbX%?}Gq0K5@uL(^M9Fkk&6iCu4d z*CaNCnN~ADC(WpCQFkN_H`CfWK{kE9d00|AxJ{liXNciM)CJC9Z;y%{W`Te!{$Yj7 za$V-OwI(R0;aaUoe#gf_RPfGqZ_Ra+Q8;N%e;;lCa3Xi8hRSADuu`-=#Wv??*)Nbh z#=54JKFx4(2p5u;e=Jf9lZg@mU=T&zB{ee9#o;b|wZ% z_!0fzRTF0yNXgq$x@o32k`&-~Ofs&|FAZ|cS%1?Y*{0Uc3{tN#NFvd|#vot~2$vfq z9A1*j4w{f9FIi-yu*gR(p~+S>1<}qP=J-h_`h`gdeCnv-0EMM;+R{q;Ur5W zaYQ~W(Zq-RsVSr$zca<_$t35(*Y-%0DQnuJn11?V4-8J_%k8mG9_zyMlO)a?NV_-v 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 diff --git a/submodules/TelegramUI/TelegramUI/Resources/Emoji/meh.tgs b/submodules/TelegramUI/TelegramUI/Resources/Emoji/meh.tgs deleted file mode 100644 index 78d31f59b2ab2405d34e66b2a044af2db57bc7eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5604 zcmV8GFMo$H&Mcekkd?bUGjc>UjZ zpZWJ6)8h}n{Uoj4{ufmZhnvrG^$QC9arnd^*HY{k{QPq`{Jy&L*5)|ye{+RrH|uBF z4EWC)Jj285PukkaIBss``ftBV^(Vb@Q?Gu%{`~H@Tj|+_9kkksKMo&w<3D&frj&;R z>a!^JX}asZm%DsfJHz=g1O8#cZa*zAK1>(v>s+%94_EAMuleYnP&fZrRUcaI_(K~= zVRWTFrTc!X`)Sqt9LH+PvsJ#H8f*Mx=H|BZ&U|;terJ?_tE6B2ypq=6+5!Kr79D%5 zR9pOPC41uw4gq5i?f=z?pSd+#dvkH9ajP{<@bu%0n)0nFY39qC8m1o`?Ib^@_^gw7 zZ*v*V)%sw2&o+&Iq1PuI^~+?`EG5FEu*dZh3!r> zFJ*HUM0f$4)4ClnFXbYe6a0zId7`8SmDDgx>M8Del3a#M#d4ud9~AA-=KpBN5>G0+ zxRRJ!C4RK2TrAt?73IziqxI=A!#b&_G$iB3lIkqm08l9=cd>A9ieT6h?W476G}#Zw zfJOj!F6ZToG)VAcb)~oE?1-0+v5rNs`E#n2iIyBuMfFEtM{nvgH zDKld+Nt&tlB5iQOEgKXT_PJg!infZ)YUJkq_3!U=c}5L!_{V3g<38Lf+x@00L>}C{ zKXhF&)h&a6`}P<{3)nKocs0B|Qc{3aOyY$NBc>1&8F%|01l|!un{+!{(N0}c$=U#1~+>CZO|of3k>~6>lJI4!BQUC z#=m4BHd!F4G8|#XYVuMpnK1|60?6`u%Lfb(w<3X++$wAlcK|f2kvrLpj<3apCtAjj z&a+HbJ);#-h>mE3uc04*KfJm9{Lgo!(0k1O&(|Ms-UOH(;F~Diomv5A{_sWx5`cB@(>LWH!4!2XJ! z1e9sFguSD(cdSq3x2O!}f=|#};PPx@DbC{;4us)pw~}cb zh>D)3@W^u*zRMxn6pQ0xJ(^lfunvv=_$+tzNbnyY1pm(hI4xMK%VxI&x9HQYQd@#b*_IM-d+fSXi?wVPu>o4garcN5sePrMQrSd)sE zi=YW=0%;n)Ga*fY1ERkfXi|OW2|(;P^J^RWQ#-##na8!2Kc1QS<0jBNo>=-f^rnIhb`!^^J)FVn^FvOA<;J77?)0aNC*IS1!O zz8FG0Vy9$@oxsw4>!pd5bkEO%17NWRSGg@FFw@+CsxKo0KDzo9dC?6|;&8B=t zGe>YdCQ*Dk@tDF=JJsBPRdCp#TU8p_QkI0vg`|Q$O;a)7i*3*jv!-*S#G?(iGxgXl zx9%|2po8j8q09vIqFbx@d30i-%!WdBKF>QeX$W;enF8Xei>MK=Lh1UlERisabx{R% zedwec2uf@HQo`lB6YfQZD)H!n~lDoPN-#nIG>aFNI*6@Q1S z#G5Id>dL8tb*T-)p--;Nglqln>axFfsxR50e6BGA>TpX{2Fk4nmup$+!uEX9mc4>r zq5{G!bY-?}B3c9b_>^v3v)i)Ut8ZwpuJ$GM%Pef34Z(qhWKm>C6E|#0Y`iDVB0u_| zHb|F44op}JBe9%o%OhMuHf>x8!C5tI!uuvTC(SRbzzS{Mz^eVu_GG`P+!t(T&#dej zPZ?NCfXSn$I!&XoetyTA(q2LdG&z-cUJQmY7cAxdSj44vKI1f#%L#A#W||GF zD;8`y+cg$7(DjbVj(`nrnrk!W7?yJ_wYM!bkj44cREJ12>E=lj8|v3aHk#!;LpvMa z^*_)F>~s-rM%M|wlo&$}&y1J$Nq&h*KEXC!dO47=tvouQnUzQMb*(%~Tq=+1{f6?G zs@YN=z4>JoOXX4GQh7vm-Yk@dz=yb)ZNdwC3P0jXbpWw6An9l?(XA@>a?%`9-~vdp zE8xc};H%wvx?_xQz~ayXD-O@`gu~|o3kJ8=E*adPGdN4^2%}H5Em@ZKZfX9YIm&W9 zSp1kzjGvCD89xw0%q5Lqu{3^IPVNBXyPxA96klNUHOy0;(ArXMOphnE5l3Un0$yN& zZme6X4K4B4!53dm`CdJ0cMOEHHm4L_6@1}5{tDLn;9diuNIRbRCM+GsmT}qxmnApE@cd+EDc`i z`y^`cVBoTBN5J3}TZhVYnzW;eS24{$9I)sb#KHKbm7}P&H))Wm#AFxin3v$fqP?>6 zT}Xky1h)9`V6N9lBn!hy%C5*L%MTwV)y}2M?)~w}Dlc(Gm zMAjYnzYNg%xg|n)%ZM^jSI{xc#lk>?gb4G(GNqaq%o`ki+kxaRyoy+6P&@ZJHE)cr zvtt@lwsT^|=t89>@y@sOwOWUxs%ovmN)=f}-+74TAfL>EIijrKOPUH^^pk15Anxmu^{8=;_mK|A>*(Fw6=o$l*R8&Ls)a1r#_jQW$*J=ESql zIQmGVt`Xh^+J+IX)fSz+$Q-CKv{>-UsAt;<#OQ4~TR}~4BAqaqxlu1^m`56wM?7SL zM48BqrWl|blCq7%a*M#D(K@0n4Wmp=(+6rlkhZURvj7zr+hWXHC3 z3&uotPR_ju*=b3kH2eircU&to8p1+RgqI?_+F?Rc{~+1v3drnW3sHJr!rzfw(~0iH zB?m2RtCGKy@K9v|d)VS%YSD80lwo-{Cb!u+RWgW|IA2I(mVwl4zeG z@jbEy!gq<0I@#&ybF?nGChZIq6Dg@&gc<^!Sa=+j?k2LcuI-?iA~o9F-qoc-XWtry z$(#rx%me_i@Q`m@6U2{_%?x!b$cFv^rFz*bA{5K8E?{~WHAcpX7(s)GT91_}>yFdc z))C%W8VMszgKLKY;dzvl5$2A7I_Mk5A=P=A0LYXY5kqm4_N?=d*Yay;227&0yTt!U z62D3J6HUL&Z`dg5A*dozo1A4*-5Ax4K9lOY zyMal~;=KsX#$jbbl~`15K-bBdBU*h`Ggzu56mX@*403gfFKF((P%&sY8dPKyz1Vyh zD30|RRuEybbjl*Cc<91#>cSAC1db^KQ|ucT^2`8Q!^VUGRyH-7(mck%(kL`hKIx`s zZKgJ%B{Yzk+|%f4Jk@G;-OLFiFmn_fNDG50-9P*yC}^O~S z;*f#N_>lo1NzP6r^#k5;eL&3q2GbHm)#k_`yNct&b;m_j$3>nT7gih>dMz#!0d286 zP9*i*2^_1k$wk8(vU`5N#xCfuThO2A*4WAZBkK2uy&5~+UnAY`c53X4ve&mL+cRTc zkJBSjxHOi}LSCE*mvRKd_C&aZBPC*q+EUNbO~Sab3094Sr$!F;R*$NeAi=Dsp>cX zW{K7dx_F`jBcDl6xD^~_^TFrXtXP7P1Pl-}$oy5{{n7_rxURV6oNrY@tY8_ z9j!Rc>sKZtcVH5=S8SUqFG|S!{R}~|gShZz@IgU>Cev`^h@Z3ZEylug&~0r@Y+z*+ zp&ziqYkKrL5wk>O$Q*E8o#kW?pVk;9h-*QKCST@iF&uO(grrKgX;oK537gc8#Eede z>U9?|iJGAUL_<7U2!{3D50d1FIqPOJGMEv332iALC&)2$JW54$ag?)e^l?L-0ATbk z2<}cCp`|myi?e~wgc!)zvAI)-(LM-vuG>Ua;>Aitl1Uu_t)ESb|4+Y=XyG_Qsyyu?H0G`5k+H$DZG@2Y-Ie{0^^K z5tu!n7NG%p_!X3COcHcZW&gxksg8$x>e}DRPTG7>mIP1eS)7@^4FP1fHmW7f{EkX= zfq|>!4q`EG!qm3;Avv<9f0D}>x=2cBN0H{B?3T2!(NBSBN;e}dq^d04rprR+Kil?! zrchW{4sAbNVZBUOUb+P0ihP;P z%sAZ^%B;bOVelOj@w-c8<$lyx5HxLCMv8=!5O}2-?xr9|X7H#oQQ`btX_OD18i7zz z(oOhrO4r;N!CG-#1=mi}Lckn* zTE{Nxds@d%_C2j*PwUv1WqVr3p4PFab?j*!ds@ey*0D#ezM8ZSkd;vZqXJN;rz#jd zrk*D`jN(L84O3RuLJc*_TA4A#Sft-nnOud*7Clc7g2nEF6jwZT=D}h`9m_amA z)H%R?GFAQJI;e>l)5tewc?f^5v?P)O5}ErU-+Olb{D;B=A8f-gwF)LDX+=Zx1ImT= zi!8opbnF=&dq&5e(XkV9&*<1QI`)i?7s=?TXBi#tflqc2F43(hXO3^oz-fWY@;M&k zCD4YNh#LJ8O{N1&&IQvC=X{!<@#hpw1MZSwr3{QEjO(%11xQ9j0@G z?d0EG-1YDEC*N@AsJr|*|4GBc2l zDo2(CyuoAD>Q2coqvT(O_l}ugjiL!EfGA`(VYKP)ak@RLm5qnPc2%?Dsge?O#P4ap zgL?AlLp#gx$TG4ZJ}Uz~F6wGw6(463VGm&it>uo8;UR}&6k`bXHQ2=Z&DetnSim^c z*z+R@_~_vXZBtF2Pmho7`B4kZUs1ca*l>R{6APunmKWxG3Mb`~1Qi1+YiySS#@>0WtEV5-Z4VRq)x?PJymT&Sx&FF%b8)CNR z=&Qffw3cRCt(sQ+`t>7A-b0}u^b5h?ntuz-lkMlvBs=kMzki$`Ectii@o-m#6aRt- yt7B?GEpFyb2Szt-C#NQf>^dnSY;A&nl7a(;UP}o2ORfyB{`?;*2|ECSwEzHzo8HL) diff --git a/submodules/TelegramUI/TelegramUI/Resources/Emoji/thumbs_up_1.tgs b/submodules/TelegramUI/TelegramUI/Resources/Emoji/thumbs_up_1.tgs deleted file mode 100644 index a4ac5afca8091b890b6660e587748ab42d5d32a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17926 zcmV(#K;*w4iwFP!000021MPiTk|Rfwo?vnQ# z?{__QTxh#i3x1p{gd`WgS<_#{^h~N$~Hf`ry(G4n% z#LT*Z8B~+aXfNL&CvS+PN8m&4mD}-7d?3FrVBb#nNBB8)A)Tz-J3TwXVo4s??Rb0H zx*8hJPKa25P&=o#kvl>hKe;!a73c7UE+q2cn6`6?hbIDtrd+EW`8=LWsc z4eG%*DDR@Yd2Z6X-lV>(v3&oVBsN*dg`3o(|Hd{6D$eEaf0M*s=n00H7-T(tYnvo* z6eIB?Y*O{|-IV2_@&20>(*;N9^8Uz^KF0nepv2g8Vd z%fa@?SI_-vJv_QU?P8qg@aW_;V+n5)OAulg;h7fXxaApKyM1sC;nhF?JpSHT*!0WS zPyE(l)KyMo5x%M^hn6=u|MD|yNi~U9f$^WZ^S$OM2hsmHPSbL~cQ{P{b#x8t>Q{M< z7^Y%8nu%Y+R$VaT{!0$i`$^C(p#+!p4<$M-%T~ z^q8zE$vIFi{`$v%tQH|YA)&~w7({eHRX;#NVfDTIeu#v!onp*qkyCAv(fLG1UrE9o zMSM4qtX8k$x4ER^x2pJc5XVD_%Iz)%s!6YGA#aIdN67~wHeW=;rvtg?tSB~|h~#Y6 z2TZw2>#?14A~x5kn8G8B2m=m^MFcmw$)36$k2P%}H;5<(8S^14I@%@)hGH@EPuQB~ zUm50KG4n5}dC|GbplZ4_566=}w#R%q?DMBz&%-`mNK`b`Q!)Zk2--&ZSMo6;FYr*PM@#%>K<8xv z9bxe9A|jiSkxJzg5y@TzuCNzFi9S&r1_a;sa!R%zG0up9<6i6;qlpa~@YGZ+HxS7( z-i{L_Y73DeVltT=?j~A5KF@fg9KR;)EoZ;CJ*So?vMq0-JeH?NzAHk%Y((~Djr+RIVZqGHKeCrd7msLNvbfE?<+p@YzH@jPi#Y#e|+Dvm8s$agr2 z)MKYUwFWi{cktLzxYNukv#@bNX=JIoB{fdCr zb!0|?30OL`upXJKue9;ftywz6rbb>#gUqS3LM^T(sGp2@T}$Wp;jz4s&L_rn)t`(~ zvv?bRJ`ah#j?OI^oiC6%C(^m*7t&d51EDjH`XQZ#H6tQ~(a0QG)>Tv>6jY@tm1_?V zx-79KEf;fTDHl^JKUxa#{D|4~2%q!_9}cO_n8o8Ui{}O1T20yY=6!PbGwGi$C(&;+ z=r$X8-+ztanxVRz)ZEI(RL1;YQ3(Bw*4(Zg;k#~skmAZHRX@nzJ<>`b=2bE!P+sxxl`|Mr(WIAJ9q0IyYNX z&(Qs{r1WOHB^o0!qmM-LTetY$WV2q};rrapYSiCie#-BEquqjY5DABq`kVLq-e$L6 z+UooK-DFzZr!}+_xT&uJN%pScH88*OIDNhmaV_9KT<1o z{yuk;)^K#6yG?g!{ayVKy|nYUFbpb7jUivv`HLbpDyQsUvq9W-Z%NU2*ZEszA?>8| zcb(|)3_{#02r>J9-!>-q%uuxN#Z}>e*0j|Zf#~Gw2Z%%ecn*^JMdQZ&Dt^%s++}z+ z+@(XMc-)jIWWEe{dHRjJ!Cf9(oJ8~{{sYqh_QMl+N?Gz zpn^CG<63!5l}Dgts_mU8-WEL$Z>v_9?rTN0bm%;I`q=TB@!Ihkd&_ot&DP$t-M@&3 zvdGC6p%UeLw7`+H6U~oAFf9-JT+DVkc-hK!3Pin=GgvkME2q!Pd3@4s*Qx5gx=2t3bZI?PrGb>V)#$390G!fC!UB`wl-Whg!|2Z~rY%~PFjm?G_B zFo+Dy@!1LaQ}+MP`9F}qk!0qLP~t*e(L<4@wte2k($abebTf5we`m9X7rqavg8fq? z^+jYQuC%rn5dX-BDU?g z(On40&Bf9*3Rxu=efn_v;|++CtKu31qgvBh7`>^yVDFFh6uicN|v7OE}p!vS#PyLkJN z*}70D^ug2R5TpbhLJrtCBd!oOcEa`|3g|Xfopoij%e#O)qlF+Y&w^AQJ*Apo|Cvz{H>|&!5ZYRgLiX#8QFP zh>UDzYZ{ZE4oZ0~m4cB{*a+34wwcM>L{SDLbp5#*v!=!RQ3>@T^X@~Pzssi3N0HUD z+3lSh4Kvd))AuudKU2sveLvIpQ})dC{rgSd&$854m!-z%m!-O0htEK8jq*TY>e+Yh zR+@TTs4pzmMKUhz4TlA#*~Ji&!1x8NjKEpTX#n-HLcBT!_=OkJ0X5Aw5cwd>Bhc}p zCGwbi#<1?bBS|s&P=;T!R*dh0cxu3wD(WuD5y*f-sd_3CAfbhGyLPq!u9sNBPE#$+ z-Eh&2)Ney&6O=r^_kE*ZLT^jkv;-$g;ZnqL5Q41dG40; zW3vG5jYLSa-I5=?sX)@!-2&)#lg-RV*#dVsrgXSlnT`9# zP1r2D)KnHiNPAgGX*<=g7NmtKx%45kU_zqf_n&`6{UTZU-oh$S&dBAn^Cm?IY zUv8&H&Xu#qj}-d?fJrK+ajryUZ!+Rex>FrmcUNqq91}e;#lww?iMp%VsY1&k8nmLe zbjc#9F|)Q^h~mlYzlnBI6A^kW--V8pqNgfEJ5}gy*^0fj*Lz|>BsoM#c7}1@WpBDD zG5#I#xf~DN%mY)=a)w?x*$z#;p_3D;QEd^PDG^6F|6r6_?c4<)Hx2zZeN_v4?$n)j z>e)?YQ}(@?>{FZF$5ci6pY)kcli^KGhFPfljRuiVCX9$YESb2y=2ruL88TdZA|b;A zA@owHCe3`OmN9WH$BjLb-MC%&65O85s}1aL*8Bu}BcmRcJ$D!7?t?R>9pV|vg5T=M zWx<7RVPJB{;(5WT=97b3*&Ukla~ePYgGmR|O~nc@(8dhu!AC-GKwxH<59&OK zSh(rJ(JH?n?c}`3&*kr_9Uzz+3_0Pzg!9)QPzAV@^{=@g|JXY!^`G86qv%%;z4Ow8d;*F;>;)O~WXT zY7{q(kIJ!w%^VlwHq*FWxtw=0!gt9C&!0p#Rl|3q8Xoharak!m*n_j|_nkXmUUPtc zOcg~utq>K*9n2Oq+?gTrQUiodwW$XzRo{k!nL^7QzCrULE_aX#RQEocd!J1>MMlju z+^2tc5%DTRa^VC8VXa=)b~PMR+W6@u3{-ibQdNuKUHs{Yc~pQi*}xAELqjgabokRF zaet~)*?hEzh2RLF!`W}pcWZgU0c_@mNVXL-+j02E@0_J z81x7Cy;c5r9VVo}Vc2)?4}ZH)Xr-zCP)H#Z>W@O9^8SR4j|2Hg#1GY$*j*~bvoHaJ zrPYOXt8KrVpZBH$AuLm+?hCXqZuOi3aCixm(Hav6e$}q($^5T4Ym{QnT@$!A1kG#7?eW|3{B5=I zg3BB9Kn7x6Aiy6P;s_WlDeRrSY2S#WB*#sDu}aW_T!JjM<7hX7{XpQNRiR`&Jfa-k z(qC<|f1jk!5OE^LAXTc0z5t1fHXerCWeYOoc5{|kX@De=ThQ2}UBv8_mF)v&hsxpN z0NBmPrbpwTR~g|al*bGw1%#n&78}fIdZj3i3bI5Mly5eU9%$wn7p&hTB&IH_PQykz zj5}_NO%rifMJI4TG#%m zDB_)?7T6_?$(zXU6__dbhU`hjHyTFCW}8l5gav$yw#%>%VAn!*h5p*acAA900pXu* zB2QWK3Ry#=cWTX5wB{^e{YJyX4*||;u0NpqBT#VjK%joXYh4O)vbG9EhIj_cQZfT0 zNaVAe1~aBN1`I|n?}N*622csHoPkPg7G>n&BJ%Up`YA#g+Af7xk>t?PBdBM>nd@Us zbhFh_RA><%Q5_3}1J)P3vXN`S5l>cCB$|REfKI(UrdY~^fMs5B*bWk7;>>wC$f@j1 z1?YG#0ElSgYb65R20gT%4!WE&3_KB^K^$eT6%r0rRy=-j9MF7lKzW3l9$`KMha4ht zIplgklO51(ekKaYu(as%%7*TD!YmbG1<~1W!z?AByoJ#Lr$vCV;A!NRLdh#UkRbe8 z7{Loyb^(c2QFhvBOzqcA`+3ukRDMH09%)b;n9~^D8#-3iV>R_?8O!b~xuwT-O>;1b zvmzoJSyT&kVDZWejU|Gz#o6XSWo&UY2mzrDe($a_Fqt?NEsfDbFa*YEjM#2AY_#eugsd_0@YNV%Y4XbCm6ui0 zP95}-bkMoWHZ9hVW3kQ>+;{FiB0K?36@KQ?^31I7+%jcTH7as_HbqjnikdyDUeNf6 z@H;>^2~JG~6l>K?YPQ6xp5Um%*;}TukXXLX6dNNhhn)nBWh4t`kk5S8TJRnW*qT+0 zI0KjysXZ1+s~Mr{Vy+kXbzOhz-BOQ{wW^UdZB)uQ;v`;cqZG6vQ7R;hy%?#YC+&I* z=c0a9?;;S;pW$7K$jnXxNaQ2Z0U6X=xR5OtYS`sN+I2`hxsUKpvJ+8uXN zwkPdgZhd~}6MJrpeQ5DNOP}AlaWa!Tvm|1cM9j?mEQy#U5mVO8l8F11M9f0oR~Pc; zvqIi}Qpo$qLx$sLr+5<(AD{P>)lVW4BK(BET9@#}{(SK>#+(CoBh-5OD72nl`6O}0 z_#_Xo?t1;2mJh~*Qbjw%Se9q2>+#dBUQ=%Rm^j2oD+|r=l@kWsR*@UIZ{$BI=ZoBU z{*~)Ws$c0)w4qe+ug455cie_NM$@qKBoI{NIQDOCy8meovSa5CL^PErx`@#wg0^8l z6rml9V@>$*0=-$}{FgD^#Z`LwEwmOwdTf;<_X0$^ug+jr3i39vUP`7Ju-Y=yrDZyX zeUKxm{*h%OMdc7;$_XGa$WdT!6R4TQYKeZeWrj=CbPOrL^g3uCI$xzHqzmk-5nuy) zP4UEe3c#6JZ<+bRGQ|k<-16KXTO|h_LW>63drcjSl0z`372(Xb-XhDzMb@NzSszO*SUU}s4Q&Kr|ImS)(aZ>$WSfeJx~dWbDn z0Z>*EdP~P|6a#@~|Fc66(Oq1l*RAu9t`I$Ez*!IvMq3VP6JqBAjqWRU?(wx@s9L-0 z`T%Uv9^$MXY@KCqAiTj|zhOb=JmZCzBIIg5~aNrxC*wN@@Sp1P`mlX1DYz^G-b z!16#G)uW8=wyr8FA(&Z6u$Von0ZssLfx7SR~R-`068LdSk;X%hKWR-1Y~Tdim5 z0pnbi#Tl+@X=%a9OSko6i()ayv5jN3s09IhOgdX`%+N}jX5N8Ae+VJ4jUA&m60MW;9 z&V+{979_dGn^|g{6M;Z(=-!IOsu`ClZ+vEOp6*Qu1$v!*0R43C~>k8wi31sRJ`KlQ5qsdZ^4-H%=+yG-;2lY+?I!6n2*{ zkl9Zg0&I2LWqD|zmq!<2Wv?d$*mr1c&KyM@QF*YD#Z`7y>*AKRCCBq6Cq++&E^S%a z)|NI_c3esAGTPoYBF%N$63fw%iBITj4%T5E*o_x?oNP*!2TUmjhxw}M&qkC$%Ws08|f7o3lHxp-nq5*+pmon=6!;SkD&$vc@ zIcK-koia%PgeuE${FtW>Ar*`Lpd^GwO=!mC@WC~m1xPxqX;rR)=&Kwkt5qKIkI3eZ zYGdTk?iWDa#GaU~E^k>K_$K4m4at2qR$}^+e`MnVPq~!^eX|jFsHY(yC0>k zT_GD|k%I?VM&%KYBU#8bTIzB~u1VK%4H`Ru>}2H@K;tYZA@kPWiW*#KKy=x#k+cyB zfLIvC*rxle2*h=Dw!w5=N;aYy1Bw&Wvk~>wtD>@iTR@iG>f*-Qz%*2|CJ9z%8lWq% zjYIxX`Tp7|sfDT?Xr5Xd+!GNOz*&@lz!U@2v3%l+aSc#f<+&-}mubRvq6P&}A}M6O z%QkQ@U>75aTMR@|8ckGC9xN4E1f&WpckP|QK?-ZLOvGsEO2bK24weC^RmZ#WdmM4D zp}CajZGmHbNk=1!1mY~jwb=#?K)4&s1a#fHo*gS?5(*>911|0guzIVvnb~rGfp|t$ zjrB?k6M%7I7ZQZ~GETmZao8=j5e=imLOsSDHYy=Uu`Ajsp+ya1iLDEmjz~+!@Sg)Z zcQ7rn-hgv5Co`%!t&$I*jiNAF14z{g^hD8NWf|QFouq36xFX?%waIH`uEB=E^YG4( z{g?H^0~SVtx*0&!9rd3HYb>hAbcj8kthI{S3<1$_{?1%euH~B8f^dzu_Bo)gcXCZ5 z-vflOBprCqB3ScN>WUE%R1ZhUr3beQW{>Li z4b3VAA{GIN<{JpY6%@|8ePtJ!#%Bzk35##-Xr~C16M`~1YbTHU5!%7iPN}sGXS(rZ zS08V{G$C>vNDMaQ9aBp{Za26lLyjc&?hbfDKvL`SfVU|6N0fj@jMnBFk!tWFi=8nb zVM2`Y-mI6L>O_cF-;HV5j3Ylrrx-!qkm_KPaw~1~vJSt=Gas2}Ue{|mmDGn&QnzS& zod)g)F>u%HJ)Z9Lbf;h31wMm#Gl=)%hWwc~_;`7P6>t$|9nGwxc>#>$3D*P)B{)ht zepHSzw5@MuCD1dkYT4=Vi8tn(ZDMdi3wd}Bv7k=VGLoX6nhEAk^KZ{NFx`um$wZ}C zrh^BU36MEnr88jcx0olP)r~>|2V@A~s~eWlO*v-;u#hQlKAgOH9nR?)!@%<^s0wy< z1ayGATSpy=yf2bpyiO~|Pepi5t%#d)i&$0(p`(bfBdr>F43LW9p4dQl7sxI;0h+5@ z7I$NI5nl)nIDm?STI*eLg95;#NR5i`vZMxeKU`D6s7vrl(g8KM;FSlFbEdTT2-4zu z2qT2vS_w4?9T}?9iQK6sr!$U{xS73X$dW68j@rZtUa>l#(T0tPJr!_bZRx0zQN-xg zh(Jkm94k^S4m6sy6EWp-HR)E?QNAu=*#yWQQxOuC0FE`u0+x^XkQ;c#}jsQZ` zJSnbnVZf+}gFqJ^_-~BhdW5||dKlz@oNVY=@;5^a!rMTfYU2fVJ?c1Q4RNL&1G(Np zgN*JIF%ap1bMkaXrS;ye-n`svw{Dkvmk|e?@aTORBaIQYW{53{Y~~;dm$4Hp;dMQq?SWh){{G@XhBGX1DO-i zdZmts5p6j{By&?mm zLAK6dbrlxDOn3a3xsgg!Nlhx>Zv_>Egcy)kkqInDodD`s*A0wG)ia8{NiHhP@0S!V zktdKm&1_V?f4SZ6UT!w}ApW4^SE|lANluONE}zg|tk}K6i8q}^_BANZt{8N+U0s3C!?b@VuDM*1}I1tk=Rcae6(LGI~7NaTK=KwUM=fD zDTHUcDf1Z@ey9$P(Yv>L`*OG4yxeQQ)5CS-9(#5UL8xT>tj^8Wei_dZO~OGua8)$} z@`P;xS6&$;NV%7!iGws1q+$F$z~NQWcoVO(NVIu*#=S3)hS5Na-rMcV-FEYGuaPEb z%>V`=+t6Rc0tXeRpSSWoV%9RlKf* z3^bMVlfXdJxO)N>==*mLUXuy_&@r2*Q=X_8X$ZkIt&tExsg=dqMN?P|A!89)Qx2im z4QqbSj+frO+-&zQw{G>`?fzyB?+S|%WB_qmm0Kt%0P_R{evN5a$%o**yoF_!Xerhy zQK(r+Hv$Fv0Q~d96qe8gLpdUboN9W2^_h5H(QHOSwnA*MruYp|F9}63#hp&r+v?rR z&3f;0tKPZY->QSR@n(+VD^^U15;>MTLvd;SA@o$xyin1c2+G4vFx6PE00jCzSzzJ; zeFGT>ueEw288ZvRkR?;x1Uf#*--(?T#zgmn#A4cH6s+`-SMWB1J;Fh4nllY#XSBQ8~Fuhk3#a*~4 zz@qaSk1e8>l5n=x!pX4*gooG((M*skT0JH+Bw*IM?9nz*2X+?GB%nXCu81RvJqL1b z4#L6->FOTKD0t@&+gYEDw>FV-G+vmr)D`g{PM5JM7u4`F0U5PpY?pb=*g#2NBKQE-gd3#}3QZUoj)ecmbk zidgugsvor84q`)|cq)9=v#9p(Cbe~UJrPZ0%P5`{U1iYF!Bl3h$EH%EqPK7O!%2V` zk-4n;WfA6O(}iOX>_)nznp+Jcw^}W?+LqjE)7+|gh|C5DW`o0$3{IL1*77SRgVRU` z*O3e!MuwsvC7~EaY8#D6UjETEd!*5QB8D(0;EJWxG19R|O|F;|DoYfDXCwA)Tv()t zBt|i%0=J>dNW4;1PB=B9P~O>tQD!TKSrMg!M~7f4rftNU&E1fZ8hm1;>4TySp-O$* z#WpAPnZ|}#fDgd57t#@6MKPAR@rM_9jI*3B6lFz38@d$_SIf^;r4U%%qlY5gY|_X& z0*;ZBcmi})2y~?a&c~vCDylj8XB^}VRfnH@bdbb*i8%E9VM*FDha8nG0exF$cGJBS zzIN$h3D+^N4#Z2ekk3S%7|Jx5+VLp17fU!uDGtv=Av|qzc5A^o41K>W)b)!2m3LkJ z0F>rrB6%gPTY6&|2au-1{)wRD{m{9HxY`f{C7=?;50*QYaS$ok=y*p7cLYw>44jNq zSis59%f_lpNQr3OECdJg1=H!de>Tc{z+6yIcwuc8b-CPztK1oAs%V1=BUB0lnfzIL>^8sqO9cf zA>hzTukGpxNzWM zYSMY2cam>Nw8$^B-{5&DU}3tI23g=K_v<#~>cYR(9Qx;)4Six#}CYy*4%0axX>=$bWyAZs!> zPoQkeFH36IIYz6TJCJXQA{<7Z8E|a0)7GB1lW#pUlMa`XT z0a-=EU#tK}5~1o3IJziF(|F`PBpjj^ac`559Xbs#MUg;`u_`5$h8~T60N4uVq9%tdV?3k_yW4>rQ_Yl( zmHqj-SqFp*D%rDNMaX4sQb-o$2vCjy3)X^UlW{m5o=xOMQAh%vDOqOqZ!hD-nt>DF zge955kWFhS6gGSoWKZ!ElCzp>7bxQPLK|)KTIMV4*Hp*_7;%l^khc?ZY&0&T(YP*+ z#(gvzXDe5+K6W9|0J@FD>y;}-VQYj*qvn^L5BC#tt`QBQE2c4U3KAQl^;l=O?~rEG z3odva6+vw&Le7)F(c>7ELe=glbbNe*%cGFK8gRXdj4QX1aZ#3j4CfFO&cXU|dZUQz zJQ#2Wv%x)7^HXyseXEQ25^=TAjI+do90SK>omP@3O^>_rew5J@sp~M>1wS0^J8GB{ zPbp}=Fl&j5Y%LTU;5!ZqFkU6(I^2h7AQ(Zr0mM`~@KTY!!HM=bqg(}JiF6BnzlW6b zczZSIilnwr8J%o^je(R4;aJMGLqo1>h#)o{j?(z6TYg(h4lo?U#Z=52h2cm8h9et} zRMv8sFy;WrlNq!ZI>@iKFn)p3Z)ikGca(CD5M7NT3KCnJO!cP#DXk6s5R-ZpM!8(z z3y^g#`giF=4e$%Vjlu zjTUGp92sC?j^*24kI*$>A#BVe)sPU0)3Dv!$v0tmL#WCNLRA_FRlJ1yTBqn|RngBJ z{Aw$Z)Z_y|D`CKi__~|@ra?5vidC{%s>-Gc(1hC!R?8dCR`KeMm_3^mc$2_)X1+y> z5BsiRxDHccgBWm8M6a7jwssrI)`&aWEks|nMw%FsmKW>vM6}kOy?XHgN;1-GBa7Zm zvXw&7W*C1NSw^J4)IU}CG?ihyQL?#kC`Clj(RNcjFBIS-@eU5L1!>)UWbkDb(WaGc zvNlCA2(od(`Z&j;WCI$Dnblp`hG(X%s-fF5^qRo8S_UEg|yW z5WDI3lWk2slVYxE`Mun$L z_30eyc?a4`ate?VNWxht4N*aDA!&MQQLY&vr_>x-!XaXhS|lx@=6M*ScM(&8QcB-f zFkpaKuR5kIZcoiiHt_=mKEB6po?58T$7?Fscg367kf(k`d&W4)p1=X>n>ME(+ zFu@?&YI+&Z%rmBZ%g`qMdm|{7!0`!1;=gORBYcNLQ0> z1N%KL*zaD;!NU-4FhS+MY>Adq6@^EY7^EB1cr~PZNw+MLiNR4ruXMtyOW}Hg_lc-e z86{~N^K-o&O1G*d$rsDm66?u`d$mfTE)q*YDY}j(wJ3*Sy~enR90LWrMlN2x zQjPV#xol&UCR?_QgX`#S4zfBXUo?FFfN%?%2<39_Rp`NXi~-kQ7Px+E(8wACN9mVm zy{k1%fDG*4M5K)2L_{;SM^A(Ecam+jFyx>=AF|D9>s{i{&&bhcoigAob{1KZ2VDDL z!p*5T)Ea8kh$NMEr4B1Kc`I(yH1RWC%;$E2Pti6-+Z1h6w0#4j?WH&l(=(l(>GVve zXZoHz({+(pW{zOy2xg98<_O+bj$j=arCHfAD?4Uo$E@u54k|k?AfV0a+*zGFt8-^{ z?srz5djZOD_FBzetJ!Ncd#&DkuhnbtNGGD(M0A^oZWGb%8%1<`8c}!^0S7u(9l4sv z$kmi|NT6;ubSdQ8FUBHT3)rgq$NL6GFA|n~`xGlN)VLuJRn_TOfa%IGGD#4!e>@KtaVEBv*PTVov@p#e}cI+;GS*#hgwCep4~`8eH&c z$4xtK+Hup4d)Ic{3z7ZTk!_u0b5BNDcTDs&P~OxT!fIVd(s!?U<4WvWoE{bjV$`*N zC(;dT24-c98V~ZF2eyXyBicBn+uM|GjcGYzVp=d~NrQlx5N?XM$=R($P;TvA2sdo| z25Q4biAUkME<}s(SGXBYEk;d5?k-1=m%|a{2}R9%q3BnF^1ZL4>H?Fmc*PAQ-*+L{ zx{c7PTDUG>3>=(YEUoeea_xLF$27vG5jKsmX@tEuBkXyzbxKbn@k_~}dzLFi`BxHh zq%dde+-|nc78!nnB(>fs1is?V3fWnrA1oM$+^~o>D4KdA*S1a*t){yxv-2(*9&KS= zzWr&1@NPMXB6pH@i0Ol>)6s=GzTxP>YzlHmQ!!C(jl{Kxv1a(^ESg1O#!@j8h#@?r zRcD1A!l!!~yMGNPV=%)>VVfzD9K}7GKeX3_M^IOe&JUGcSorvvhtEri*SpPY!{kq= zv)UE`2LNAmsgcS_-mR0qvQFv*1Um{IB6cF{#Pu9?uwrFtOpzZWw`6Z}3V)*?HG`4ydBuzWN2g1I2byrBtBtio4>O#v>t#xM~8laqZ=RP)3Z3*SEf~R zPs@Ny+S@%pz|kx$p+%FqU(O0sz|!DP@7f_x8y6c-tH3|vX&wXZwRUh>F;&+e3+JS3 zv}T=imd*_F5Uie(0karTZ&}-R^gVAV>D>V!*=SbfD6^!WcI!LDY8_h^~lBFXOo2acd zGb5>Mc2G5SET0cpx}cKPQ`exAsj{ag4t`d3ZF8fw{{)h*pYZbqcDAnd{0w$3=2Bqx z$Y`vBZQJ|_FE3{j49#Ps{ln`0IUBN>&>ziS1+~6;9C2qpD35 zD?>TC4&`x4WqItv%FPUlf*#elv>JJ~Kb{f* zBO-|$Uozf##O5fUbDcoUV8b>bzc+b$G42Gr@c0QhSwAn78_UtgfkbX?j=LlFmbe2QwO%|$=fRyW8T5a;nE37i4+Jn?>J_NiW=JyKex^r#p)km z=cvQN5F#PILq(rjrb!)GTvt#mjBhx@g}{Y;@;57jmkS~>y^emrv z8aIyd``#7aBbm&hi5->S&F1iI&D0Bi7~NcYXQ=8n=;v4Pa>b~YYT>;mhJx2wN>7>` zYC#w`d+U`qb`FjOEaS@yJEs$N4iB>P_1uiITdY~jF;o!Wl**Be#Fb20hIypa?Z;Tb6T9Dbtd3t_UT|geOGfr zJ9$KkHZwpRo3altq<(mTlZSXA^M|y8SUfLy4Z*^Q=FG?lk`5q4jTHM%_@wmPV^)+H-U` z;b{L5N7w!gizA~Ti6Af0SQ?FY+u^1?$kp9q8<_?3B^p~Z#P2n>5j9Ga4!HU;j`qgU zWkU&e%+Sy5z#n0l58*S*oEihW;i`p@S3%ws-@UUoj!T33|DMZc$ zgPGuG_QN&nQHLoUvP%3GMqeLCr$@{r%XX#09gU4aC%w{KwJXiQYIK%rhdX{Fc;hP= z8Z>qTQ9w**^tpwrB((nB2S*3~ts}6|$q+gG+$}z#+06cGj;_z*Xm-OgiKQIPRvno5 z;Q@}O17P-Z1`De&0z=bTwE2HkE#9<`a%`WJ(}SrY9ZEP(N_2SP`tWm}#^6a#E<^8C zQl3WB2ZwK}xs3i5mD*|iU6esnH7U;WHC|}S({$Lu!jx1EuhVCSGK_`9ql0OnBl;Fp zjK@CMwK$dZ$-V>Von%+^J81AXGu($OP;H-PPoLNiY*h>mw9|akb=>K_AKXd#7Ii>e z+A%E|M;>Z0r|&1s`5pjn+Faa`7>G&E`zahwrFx-vLjj; z&H~?bbFSo2KfFBlTjx_tf`i~j)bmnY*#%X_D&4@O#4;!gPX^^LttiId%LT)RQ1F9l z)8oLSoqrd)Vqnp3BN@#ia8#i&SaTlaa5nL8Hjl&XQvFV~&_<_#(<{ofBAKgBSF0LK zUmec$3Z{m(b8%tnycwaaE4ex>T&?(YZAp=6V&VB*t?#M%S!^AUu<`pGXHLr2u|37s z$=DjFu(%OhhE)+tJ971WKIZCh6<346S$)<$S2u9=gCS<Q`#L0gmP5>B-aYou^+4U^tDCX@tBRBV=9Vy6OH+_wU`ff9n92%@ExT z(S6$?x(hf}GmkR!DBpA*v!E5jPbaW+f=PfP**HbDinm&z+@g^uYQpaLUf#(`M`6{y-( z-w0HP@d_*;U~7K1*8H{{uBwMi&nQ3;M4Au&0z{<^_?w0bil(rLnm0;7+JV#t zK)pX{PBr}gyD?3=j%f%0v|;;Su*^cy?5|G!18x=)9Wf4NrXg>@uoUAO1o<)0f@f=8 zu95Spa*YYw08kI4Aba;F7lCsE;QVGoZ?L$rHt>vCRf`;0nP)g0mq1I5_~N&A%4wl$ zM}su@su5FXt7$aKKXg}p6LsqY0voCJ0M@r&)gI zzFbqTKDvQ zvTTI8qkQDX{1m#t3Y!JC!4wjk)VDU@VCax4A7=xUbm&kRLx)D$9SgG{nsl0?)d6sJ zPhIldTDqbA-*;o1dM(=&?D-<%t6H{xpae!tj>>BMvV-~D6(gHq zXpy6|$#&p*h;ZNogKTTFO*LdfuaJ)w)xMZ7r;w1H(1@@NY}Rh&403Np17I7N$E?!1 z0pBE@LyaM|I;0V{uJ1aewpbNHVe(Bn{+LazN3e8c|n+P0?b%br}F7=BtjFR|ZHT%!9L-#g-0F zgEyyuAsm^TwAY~;162A?=_U-2)o11u_OMK0_hSnCQZtn_E?&Yi&fMEP^Rkq5H!JCW zH3O{GiuMT0c+MgZi%acjqhRQ|9Xpn=`2mFt$B|g9_?g2cYCPH1#~UzB(6m6LT@8q3 zk!mnt-QXG&f%>$}rPK9|<$-I84mr7rx)G@c_p#Us^Wy9%!mHeyt>;A*BE+lj#xy!E zOe|URi1rOGw0>`)Y@XZcHCg7vv&>5ysiuPZFbZnjHl=CYelX*9omQafN>5k%g$*|| zcsGN0FYIfX*@BOnEqF}_$t;_hWi!ui*LZ+wINU=gyp}QHRX*p0*KVSR?fI~CY(D0j zvJK~;j=CM5!p0G&EPl|I^R^Q~2Sca%w`Uwq3$KO(n`!5XrD3X6{;ES_0n?|X5z<=7g+w}A!rK=1$l>+9v(Uw-Gc-{e1@b%t6C z&#&Sa{rt0*+q3MxXxY7p)!%>m73lxt@AMd@s?y1+n80ZfY;-8leU=YEA|KSkg)c&SN;5kR7o*k9;$^vcGgs|p#8>lg|H`oLGwIi-o&K?l$`>UMg&Ob<2< zdPZ0#0GS%di*h@J8%;6VT?o(RgP~JVVX=^l(MRAN%PY3}j^z~?quE(cZiWr+9WOwK z2;L9yl!MMbu?B;V%F2Y^VI4Py(rEjd4uiu4rvkI3nJdr9W*rkflf@O;|4uU(XC#lMd59xl2k<_t1Dd&;9u zy|eAJ=CC5=qvG#?@;Sbi@+Xy|Y}vu=V*b=uQXb==#Q$Ix_>lI_+8Xk!i7%wLuGG}? z0qN1i6&QK8p|&fL9x)}+!Bl|Hru>N#t!K3ilkHbv`=?nxw<+h}O3okid@GakYf&Cr zvrUU-9eU0X#hXC@yucFghLE2ScGc3oR5p>rPc;=)0Rfx=voV5(HEuGz5bbtNTAzi2 zgyRq&xKFW-cU5s*1HutxEkzj*fXjf_~{0x zrW}YOo_Z34w4|DxT8ybX-)lxr{6VAfzmBe<#{E}$ji~fr|DFGt=HxUdr#U&z$!Shb zj-2M?G$*Gy`8}AE4+R~Invf-j&KY^exqkfT{|C{F33#qg0sx@G BV?Y1^ diff --git a/submodules/TelegramUI/TelegramUI/Resources/Emoji/thumbs_up_2.tgs b/submodules/TelegramUI/TelegramUI/Resources/Emoji/thumbs_up_2.tgs deleted file mode 100644 index c251cb8632ae10eb69c792213e4d6b8aa7ccf325..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17993 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 diff --git a/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj b/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj index a9c03c9e22..2588253396 100644 --- a/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj +++ b/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj @@ -34,17 +34,6 @@ 091BEAB3214552D9003AEA30 /* Vision.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D02DADBE2138D76F00116225 /* Vision.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 0921F60B228C8765001A13D7 /* ItemListPlaceholderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0921F60A228C8765001A13D7 /* ItemListPlaceholderItem.swift */; }; 0921F60E228EE000001A13D7 /* ChatMessageActionUrlAuthController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0921F60D228EE000001A13D7 /* ChatMessageActionUrlAuthController.swift */; }; - 0925902C22EF8158003D6283 /* thumbs_up_5.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 0925902622EF8157003D6283 /* thumbs_up_5.tgs */; }; - 0925902D22EF8158003D6283 /* thumbs_up_6.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 0925902722EF8158003D6283 /* thumbs_up_6.tgs */; }; - 0925902E22EF8158003D6283 /* thumbs_up_3.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 0925902822EF8158003D6283 /* thumbs_up_3.tgs */; }; - 0925902F22EF8158003D6283 /* thumbs_up_1.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 0925902922EF8158003D6283 /* thumbs_up_1.tgs */; }; - 0925903022EF8158003D6283 /* thumbs_up_2.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 0925902A22EF8158003D6283 /* thumbs_up_2.tgs */; }; - 0925903122EF8158003D6283 /* thumbs_up_4.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 0925902B22EF8158003D6283 /* thumbs_up_4.tgs */; }; - 092A65DB22EF16900032E20C /* lol.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 092A65D522EF16900032E20C /* lol.tgs */; }; - 092A65DD22EF16900032E20C /* meh.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 092A65D722EF16900032E20C /* meh.tgs */; }; - 092A65DE22EF16900032E20C /* confused.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 092A65D822EF16900032E20C /* confused.tgs */; }; - 092A65DF22EF16900032E20C /* celeb.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 092A65D922EF16900032E20C /* celeb.tgs */; }; - 092A65E022EF16900032E20C /* heart.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 092A65DA22EF16900032E20C /* heart.tgs */; }; 092F368D2154AAEA001A9F49 /* SFCompactRounded-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 092F368C2154AAE9001A9F49 /* SFCompactRounded-Semibold.otf */; }; 092F36902157AB46001A9F49 /* ItemListCallListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 092F368F2157AB46001A9F49 /* ItemListCallListItem.swift */; }; 09310D32213ED5FC0020033A /* anim_ungroup.json in Resources */ = {isa = PBXBuildFile; fileRef = 09310D1A213BC5DE0020033A /* anim_ungroup.json */; }; @@ -1277,17 +1266,6 @@ 091954782294754E00E11046 /* AnimatedStickerUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedStickerUtils.swift; sourceTree = ""; }; 0921F60A228C8765001A13D7 /* ItemListPlaceholderItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListPlaceholderItem.swift; sourceTree = ""; }; 0921F60D228EE000001A13D7 /* ChatMessageActionUrlAuthController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageActionUrlAuthController.swift; sourceTree = ""; }; - 0925902622EF8157003D6283 /* thumbs_up_5.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = thumbs_up_5.tgs; sourceTree = ""; }; - 0925902722EF8158003D6283 /* thumbs_up_6.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = thumbs_up_6.tgs; sourceTree = ""; }; - 0925902822EF8158003D6283 /* thumbs_up_3.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = thumbs_up_3.tgs; sourceTree = ""; }; - 0925902922EF8158003D6283 /* thumbs_up_1.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = thumbs_up_1.tgs; sourceTree = ""; }; - 0925902A22EF8158003D6283 /* thumbs_up_2.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = thumbs_up_2.tgs; sourceTree = ""; }; - 0925902B22EF8158003D6283 /* thumbs_up_4.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = thumbs_up_4.tgs; sourceTree = ""; }; - 092A65D522EF16900032E20C /* lol.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = lol.tgs; sourceTree = ""; }; - 092A65D722EF16900032E20C /* meh.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = meh.tgs; sourceTree = ""; }; - 092A65D822EF16900032E20C /* confused.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = confused.tgs; sourceTree = ""; }; - 092A65D922EF16900032E20C /* celeb.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = celeb.tgs; sourceTree = ""; }; - 092A65DA22EF16900032E20C /* heart.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = heart.tgs; sourceTree = ""; }; 092F368C2154AAE9001A9F49 /* SFCompactRounded-Semibold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SFCompactRounded-Semibold.otf"; sourceTree = ""; }; 092F368F2157AB46001A9F49 /* ItemListCallListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListCallListItem.swift; sourceTree = ""; }; 09310D1A213BC5DE0020033A /* anim_ungroup.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = anim_ungroup.json; sourceTree = ""; }; @@ -2611,25 +2589,6 @@ name = "Animated Stickers"; sourceTree = ""; }; - 092A65D422EF16900032E20C /* Emoji */ = { - isa = PBXGroup; - children = ( - 0925902922EF8158003D6283 /* thumbs_up_1.tgs */, - 0925902A22EF8158003D6283 /* thumbs_up_2.tgs */, - 0925902822EF8158003D6283 /* thumbs_up_3.tgs */, - 0925902B22EF8158003D6283 /* thumbs_up_4.tgs */, - 0925902622EF8157003D6283 /* thumbs_up_5.tgs */, - 0925902722EF8158003D6283 /* thumbs_up_6.tgs */, - 092A65D522EF16900032E20C /* lol.tgs */, - 092A65D722EF16900032E20C /* meh.tgs */, - 092A65D822EF16900032E20C /* confused.tgs */, - 092A65D922EF16900032E20C /* celeb.tgs */, - 092A65DA22EF16900032E20C /* heart.tgs */, - ); - name = Emoji; - path = TelegramUI/Resources/Emoji; - sourceTree = ""; - }; 092F368B2154AAD6001A9F49 /* Fonts */ = { isa = PBXGroup; children = ( @@ -3284,7 +3243,6 @@ D0471B521EFD8EBC0074D609 /* Resources */ = { isa = PBXGroup; children = ( - 092A65D422EF16900032E20C /* Emoji */, 09E2D9ED226F1AF300EA0AA4 /* Emoji.mapping */, D0955FB32191278C00F89427 /* PresentationStrings.mapping */, 09310D13213BC5DE0020033A /* Animations */, @@ -5312,12 +5270,10 @@ buildActionMask = 2147483647; files = ( 09874E4F21078FA100E190B8 /* Generic.html in Resources */, - 092A65E022EF16900032E20C /* heart.tgs in Resources */, 09874E5021078FA100E190B8 /* GenericUserScript.js in Resources */, 09874E5121078FA100E190B8 /* Instagram.html in Resources */, 09874E5221078FA100E190B8 /* Twitch.html in Resources */, 09874E5321078FA100E190B8 /* TwitchUserScript.js in Resources */, - 0925902F22EF8158003D6283 /* thumbs_up_1.tgs in Resources */, 094735122275D72100EA2312 /* anim_mute.json in Resources */, 09874E5421078FA100E190B8 /* Vimeo.html in Resources */, 09874E5521078FA100E190B8 /* VimeoUserScript.js in Resources */, @@ -5329,7 +5285,6 @@ D0EB42051F3143AB00838FE6 /* LegacyComponentsResources.bundle in Resources */, D0E9BAA21F056F4C00F079A4 /* stp_card_discover@3x.png in Resources */, D0E9BAB01F056F4C00F079A4 /* stp_card_mastercard@3x.png in Resources */, - 092A65DF22EF16900032E20C /* celeb.tgs in Resources */, 09310D32213ED5FC0020033A /* anim_ungroup.json in Resources */, 09E2D9EF226F1AFA00EA0AA4 /* Emoji.mapping in Resources */, D0955FB521912B6000F89427 /* PresentationStrings.mapping in Resources */, @@ -5352,16 +5307,13 @@ D0F972101FFE4BD5002595C8 /* MessageSent.caf in Resources */, D0E9BAB71F056F4C00F079A4 /* stp_card_visa_template@2x.png in Resources */, D0E9BA951F056F4C00F079A4 /* stp_card_applepay@2x.png in Resources */, - 092A65DB22EF16900032E20C /* lol.tgs in Resources */, D0E9BAA01F056F4C00F079A4 /* stp_card_diners_template@3x.png in Resources */, 094735132275D72100EA2312 /* anim_delete.json in Resources */, 094735192277483C00EA2312 /* anim_infotip.json in Resources */, 094735142275D72100EA2312 /* anim_unarchive.json in Resources */, D0E9BAAA1F056F4C00F079A4 /* stp_card_form_front@3x.png in Resources */, D0E9BA971F056F4C00F079A4 /* stp_card_applepay_template@2x.png in Resources */, - 092A65DD22EF16900032E20C /* meh.tgs in Resources */, D0E9BAB41F056F4C00F079A4 /* stp_card_placeholder_template@3x.png in Resources */, - 0925903022EF8158003D6283 /* thumbs_up_2.tgs in Resources */, D0E9BAA71F056F4C00F079A4 /* stp_card_form_back@2x.png in Resources */, D0E9BAB11F056F4C00F079A4 /* stp_card_mastercard_template@2x.png in Resources */, D0E9BA9D1F056F4C00F079A4 /* stp_card_diners@2x.png in Resources */, @@ -5370,17 +5322,13 @@ D0E9BAAC1F056F4C00F079A4 /* stp_card_jcb@3x.png in Resources */, D0E9BA911F056F4C00F079A4 /* stp_card_amex@2x.png in Resources */, D0E9BA931F056F4C00F079A4 /* stp_card_amex_template@2x.png in Resources */, - 0925903122EF8158003D6283 /* thumbs_up_4.tgs in Resources */, D0E9BAA91F056F4C00F079A4 /* stp_card_form_front@2x.png in Resources */, D0E9BAA41F056F4C00F079A4 /* stp_card_discover_template@3x.png in Resources */, D0E9BAA81F056F4C00F079A4 /* stp_card_form_back@3x.png in Resources */, - 092A65DE22EF16900032E20C /* confused.tgs in Resources */, D0E9BAA11F056F4C00F079A4 /* stp_card_discover@2x.png in Resources */, D0E9B9EA1F00853C00F079A4 /* PhoneCountries.txt in Resources */, 094735152275D72100EA2312 /* anim_unpin.json in Resources */, D0E9BAB31F056F4C00F079A4 /* stp_card_placeholder_template@2x.png in Resources */, - 0925902E22EF8158003D6283 /* thumbs_up_3.tgs in Resources */, - 0925902D22EF8158003D6283 /* thumbs_up_6.tgs in Resources */, D0E9BAAE1F056F4C00F079A4 /* stp_card_jcb_template@3x.png in Resources */, D0E9BAAB1F056F4C00F079A4 /* stp_card_jcb@2x.png in Resources */, 09E2DA132273367900EA0AA4 /* anim_archiveAvatar.json in Resources */, @@ -5391,7 +5339,6 @@ D0E9BAB21F056F4C00F079A4 /* stp_card_mastercard_template@3x.png in Resources */, D0E9BA981F056F4C00F079A4 /* stp_card_applepay_template@3x.png in Resources */, D0E9BAA51F056F4C00F079A4 /* stp_card_form_applepay@2x.png in Resources */, - 0925902C22EF8158003D6283 /* thumbs_up_5.tgs in Resources */, D0E9BAB81F056F4C00F079A4 /* stp_card_visa_template@3x.png in Resources */, D0AF797822C2E26500CECCB8 /* meson.build in Resources */, D0E9BA9B1F056F4C00F079A4 /* stp_card_cvc_amex@2x.png in Resources */, From 1538f60ceb407a4381af0fb1165f39ce5988db14 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 31 Jul 2019 02:40:55 +0300 Subject: [PATCH 12/41] Animated emoji thumbnail fix --- .../TelegramUI/AnimatedStickerUtils.swift | 2 -- .../ChatMessageAnimatedStickerItemNode.swift | 15 +++++++-------- .../TelegramUI/TelegramUI/StickerResources.swift | 7 ++++++- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift index 60af58a4e5..541d311c4a 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift @@ -189,8 +189,6 @@ func experimentalConvertCompressedLottieToCombinedMp4(data: Data, size: CGSize, return } - let scale = size.width / 512.0 - let bytesPerRow = (4 * Int(size.width) + 15) & (~15) var currentFrame: Int32 = 0 diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index 7f0213f6bd..5eefd44ece 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -136,15 +136,14 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } } - if self.telegramFile == nil { - self.emojiFile = item.associatedData.animatedEmojiStickers[item.message.text.trimmedEmoji]?.file - - if let emojiFile = self.emojiFile { - self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, file: emojiFile, small: false, size: CGSize(width: 384.0, height: 384.0), thumbnail: false)) + if self.telegramFile == nil, let emojiFile = item.associatedData.animatedEmojiStickers[item.message.text.trimmedEmoji]?.file { + if self.emojiFile?.id != emojiFile.id { + self.emojiFile = emojiFile + let dimensions = emojiFile.dimensions ?? CGSize(width: 512.0, height: 512.0) + self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, file: emojiFile, small: false, size: dimensions.aspectFilled(CGSize(width: 384.0, height: 384.0)), thumbnail: false)) self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, fileReference: .message(message: MessageReference(item.message), media: emojiFile)).start()) + self.updateVisibility() } - - self.updateVisibility() } } @@ -179,7 +178,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if let file = file { let dimensions = file.dimensions ?? CGSize(width: 512.0, height: 512.0) - let fittedSize = isEmoji ? dimensions.aspectFilled(CGSize(width: 384.0, height: 384.0)) : dimensions.aspectFitted(CGSize(width: 384.0, height: 384.0)) + let fittedSize = isEmoji ? dimensions.aspectFilled(CGSize(width: 480.0, height: 480.0)) : dimensions.aspectFitted(CGSize(width: 384.0, height: 384.0)) self.animationNode.setup(account: item.context.account, resource: file.resource, width: Int(fittedSize.width), height: Int(fittedSize.height), playbackMode: playbackMode, mode: .cached) } } diff --git a/submodules/TelegramUI/TelegramUI/StickerResources.swift b/submodules/TelegramUI/TelegramUI/StickerResources.swift index b6d228e3bf..73e54f2246 100644 --- a/submodules/TelegramUI/TelegramUI/StickerResources.swift +++ b/submodules/TelegramUI/TelegramUI/StickerResources.swift @@ -535,8 +535,10 @@ public func chatMessageAnimatedSticker(postbox: Postbox, file: TelegramMediaFile if let blurredThumbnailImage = blurredThumbnailImage { c.interpolationQuality = .low + let thumbnailFittedSize = blurredThumbnailImage.size.aspectFilled(fittedRect.size) + let thumbnailFittedRect = CGRect(origin: CGPoint(x: fittedRect.origin.x - (thumbnailFittedSize.width - fittedRect.width) / 2.0, y: fittedRect.origin.y - (thumbnailFittedSize.height - fittedRect.height) / 2.0), size: thumbnailFittedSize) let thumbnailScaledInset = thumbnailInset * (fittedRect.width / blurredThumbnailImage.size.width) - c.draw(blurredThumbnailImage.cgImage!, in: fittedRect.insetBy(dx: -thumbnailScaledInset, dy: -thumbnailScaledInset)) + c.draw(blurredThumbnailImage.cgImage!, in: thumbnailFittedRect.insetBy(dx: -thumbnailScaledInset, dy: -thumbnailScaledInset)) } if let fullSizeImage = fullSizeImage, let cgImage = fullSizeImage.0.cgImage, let cgImageAlpha = fullSizeImage.1.cgImage { @@ -549,6 +551,9 @@ public func chatMessageAnimatedSticker(postbox: Postbox, file: TelegramMediaFile } } + let img = context.generateImage() + let cgImg = img?.cgImage + return context } } From e90f49d5d50bea5b69d689c3e503592de564d80f Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 31 Jul 2019 02:42:11 +0300 Subject: [PATCH 13/41] Fix --- .../TelegramUI/ChatMessageAnimatedStickerItemNode.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index 5eefd44ece..7c640bd7d1 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -178,7 +178,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if let file = file { let dimensions = file.dimensions ?? CGSize(width: 512.0, height: 512.0) - let fittedSize = isEmoji ? dimensions.aspectFilled(CGSize(width: 480.0, height: 480.0)) : dimensions.aspectFitted(CGSize(width: 384.0, height: 384.0)) + let fittedSize = isEmoji ? dimensions.aspectFilled(CGSize(width: 384.0, height: 384.0)) : dimensions.aspectFitted(CGSize(width: 384.0, height: 384.0)) self.animationNode.setup(account: item.context.account, resource: file.resource, width: Int(fittedSize.width), height: Int(fittedSize.height), playbackMode: playbackMode, mode: .cached) } } From 6ea5883b6ee0fafd568a0385b4246500087fed49 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 31 Jul 2019 14:25:05 +0300 Subject: [PATCH 14/41] Changed animated emoji insets --- .../TelegramUI/AnimatedStickerNode.swift | 5 +- .../ChatMessageAnimatedStickerItemNode.swift | 50 ++++++++++--------- .../TelegramUI/TelegramUI/EmojiUtils.swift | 2 +- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift index 48f4cfb86a..986b3d8307 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift @@ -470,10 +470,13 @@ final class AnimatedStickerNode: ASDisplayNode { self.timer.swap(nil)?.invalidate() } - func playIfNeeded() { + func playIfNeeded() -> Bool { if !self.isPlaying { + self.isPlaying = true self.play() + return true } + return false } func updateLayout(size: CGSize) { diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index 7c640bd7d1..bc410385bc 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -306,11 +306,11 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let displayLeftInset = params.leftInset + layoutConstants.bubble.edgeInset + avatarInset let imageInset: CGFloat = 10.0 - let innerImageSize = imageSize + var innerImageSize = imageSize imageSize = CGSize(width: imageSize.width + imageInset * 2.0, height: imageSize.height + imageInset * 2.0) - var imageFrame = CGRect(origin: CGPoint(x: 0.0 + (incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + avatarInset + layoutConstants.bubble.contentInsets.left) : (params.width - params.rightInset - imageSize.width - layoutConstants.bubble.edgeInset - layoutConstants.bubble.contentInsets.left - deliveryFailedInset)), y: 0.0), size: CGSize(width: imageSize.width, height: imageSize.height)) + let imageFrame = CGRect(origin: CGPoint(x: 0.0 + (incoming ? (params.leftInset + layoutConstants.bubble.edgeInset + avatarInset + layoutConstants.bubble.contentInsets.left) : (params.width - params.rightInset - imageSize.width - layoutConstants.bubble.edgeInset - layoutConstants.bubble.contentInsets.left - deliveryFailedInset)), y: 0.0), size: CGSize(width: imageSize.width, height: imageSize.height)) if isEmoji { - imageFrame = imageFrame.offsetBy(dx: incoming ? -imageInset : imageInset, dy: 0.0) + innerImageSize = imageSize } let arguments = TransformImageArguments(corners: ImageCorners(), imageSize: innerImageSize, boundingSize: innerImageSize, intrinsicInsets: UIEdgeInsets(top: imageInset, left: imageInset, bottom: imageInset, right: imageInset)) @@ -455,10 +455,14 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } let updatedImageFrame = imageFrame.offsetBy(dx: 0.0, dy: floor((contentHeight - imageSize.height) / 2.0)) + var updatedContentFrame = updatedImageFrame + if isEmoji { + updatedContentFrame = updatedContentFrame.insetBy(dx: -imageInset, dy: -imageInset) + } - strongSelf.imageNode.frame = updatedImageFrame - strongSelf.animationNode.frame = updatedImageFrame.insetBy(dx: imageInset, dy: imageInset) - strongSelf.animationNode.updateLayout(size: updatedImageFrame.insetBy(dx: imageInset, dy: imageInset).size) + strongSelf.imageNode.frame = updatedContentFrame + strongSelf.animationNode.frame = updatedContentFrame.insetBy(dx: imageInset, dy: imageInset) + strongSelf.animationNode.updateLayout(size: updatedContentFrame.insetBy(dx: imageInset, dy: imageInset).size) imageApply() if let updatedShareButtonNode = updatedShareButtonNode { @@ -662,29 +666,29 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let _ = item.controllerInteraction.openMessage(item.message, .default) } else if let _ = self.emojiFile { if item.context.sharedContext.immediateExperimentalUISettings.playAnimatedEmojiOnce { - self.animationNode.playIfNeeded() - } - - if self.item?.message.text == "❤️" { - let hapticFeedback: HapticFeedback - if let currentHapticFeedback = self.hapticFeedback { - hapticFeedback = currentHapticFeedback - } else { - hapticFeedback = HapticFeedback() - self.hapticFeedback = hapticFeedback - } - hapticFeedback.prepareImpact() - hapticFeedback.impact(.heavy) - Queue.mainQueue().after(0.2) { - hapticFeedback.impact(.medium) - Queue.mainQueue().after(0.74) { - hapticFeedback.impact(.medium) + if self.animationNode.playIfNeeded() { + if self.item?.message.text == "❤️" { + let hapticFeedback: HapticFeedback + if let currentHapticFeedback = self.hapticFeedback { + hapticFeedback = currentHapticFeedback + } else { + hapticFeedback = HapticFeedback() + self.hapticFeedback = hapticFeedback + } + hapticFeedback.prepareImpact() + hapticFeedback.impact(.heavy) Queue.mainQueue().after(0.2) { hapticFeedback.impact(.medium) Queue.mainQueue().after(0.74) { hapticFeedback.impact(.medium) Queue.mainQueue().after(0.2) { hapticFeedback.impact(.medium) + Queue.mainQueue().after(0.74) { + hapticFeedback.impact(.medium) + Queue.mainQueue().after(0.2) { + hapticFeedback.impact(.medium) + } + } } } } diff --git a/submodules/TelegramUI/TelegramUI/EmojiUtils.swift b/submodules/TelegramUI/TelegramUI/EmojiUtils.swift index 5da3ef8e68..cb435f4146 100644 --- a/submodules/TelegramUI/TelegramUI/EmojiUtils.swift +++ b/submodules/TelegramUI/TelegramUI/EmojiUtils.swift @@ -147,7 +147,7 @@ extension String { } var trimmedEmoji: String { - if self.unicodeScalars.count > 1, self.unicodeScalars.first?.value == 0x2764 { + if self.unicodeScalars.count > 1, self.unicodeScalars.first?.value == 0x2764, self.emojis.count == 1 { return String(self.unicodeScalars.prefix(self.unicodeScalars.count - 1)) } else { return self From dccb44dfdb143050727a2c6e1d8fceca4c89034a Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 31 Jul 2019 20:55:27 +0300 Subject: [PATCH 15/41] Changed animated emoji size calculation --- .../TelegramUI/ChatMessageAnimatedStickerItemNode.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index bc410385bc..f417745b12 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -219,7 +219,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let displaySize = CGSize(width: floor(displaySize.width * item.presentationData.animatedEmojiScale), height: floor(displaySize.height * item.presentationData.animatedEmojiScale)) if let dimensions = emojiFile.dimensions { - imageSize = dimensions.aspectFilled(displaySize) + imageSize = CGSize(width: displaySize.width * dimensions.width / 512.0, height: displaySize.height * dimensions.height / 512.0) } else if let thumbnailSize = emojiFile.previewRepresentations.first?.dimensions { imageSize = thumbnailSize.aspectFitted(displaySize) } From 6aa7b85c7011283e648895b479443dad357db15a Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 1 Aug 2019 00:47:53 +0300 Subject: [PATCH 16/41] Various Siri improvements --- SiriIntents/IntentContacts.swift | 53 ++++++++++- SiriIntents/IntentHandler.swift | 95 ++++++++++++++----- SiriIntents/IntentMessages.swift | 13 ++- .../TelegramCore/TelegramCore/Account.swift | 5 +- .../TelegramCore/PhoneNumbers.swift | 28 ++++-- 5 files changed, 157 insertions(+), 37 deletions(-) diff --git a/SiriIntents/IntentContacts.swift b/SiriIntents/IntentContacts.swift index 19ae8cf1e6..cfe9f540bf 100644 --- a/SiriIntents/IntentContacts.swift +++ b/SiriIntents/IntentContacts.swift @@ -12,13 +12,17 @@ struct MatchingDeviceContact { let phoneNumbers: [String] } -func matchingDeviceContacts(stableIds: [String]) -> Signal<[MatchingDeviceContact], NoError> { +enum IntentContactsError { + case generic +} + +func matchingDeviceContacts(stableIds: [String]) -> Signal<[MatchingDeviceContact], IntentContactsError> { guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else { - return .single([]) + return .fail(.generic) } let store = CNContactStore() guard let contacts = try? store.unifiedContacts(matching: CNContact.predicateForContacts(withIdentifiers: stableIds), keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: .fullName), CNContactPhoneNumbersKey as CNKeyDescriptor]) else { - return .single([]) + return .fail(.generic) } return .single(contacts.map({ contact in @@ -34,19 +38,58 @@ func matchingDeviceContacts(stableIds: [String]) -> Signal<[MatchingDeviceContac })) } +private func matchPhoneNumbers(_ lhs: String, _ rhs: String) -> Bool { + if lhs.count < 10 && lhs.count == rhs.count { + return lhs == rhs + } else if lhs.count >= 10 && rhs.count >= 10 && lhs.suffix(10) == rhs.suffix(10) { + return true + } else { + return false + } +} + func matchingCloudContacts(postbox: Postbox, contacts: [MatchingDeviceContact]) -> Signal<[(String, TelegramUser)], NoError> { return postbox.transaction { transaction -> [(String, TelegramUser)] in var result: [(String, TelegramUser)] = [] outer: for peerId in transaction.getContactPeerIds() { - if let peer = transaction.getPeer(peerId) as? TelegramUser, let phone = peer.phone { + if let peer = transaction.getPeer(peerId) as? TelegramUser, let peerPhoneNumber = peer.phone { for contact in contacts { for phoneNumber in contact.phoneNumbers { - if arePhoneNumbersEqual(phoneNumber, phone) { + if matchPhoneNumbers(phoneNumber, peerPhoneNumber) { result.append((contact.stableId, peer)) continue outer } } } +// var parsedPhoneNumbers: [String: ParsedPhoneNumber] = [:] +// let parsedPeerPhoneNumber: ParsedPhoneNumber? +// if let number = parsedPhoneNumbers[peerPhoneNumber] { +// parsedPeerPhoneNumber = number +// } else if let number = ParsedPhoneNumber(string: peerPhoneNumber) { +// parsedPeerPhoneNumber = number +// parsedPhoneNumbers[peerPhoneNumber] = number +// } else { +// parsedPeerPhoneNumber = nil +// } +// +// for contact in contacts { +// for phoneNumber in contact.phoneNumbers { +// let parsedPhoneNumber: ParsedPhoneNumber? +// if let number = parsedPhoneNumbers[phoneNumber] { +// parsedPhoneNumber = number +// } else if let number = ParsedPhoneNumber(string: phoneNumber) { +// parsedPhoneNumber = number +// parsedPhoneNumbers[phoneNumber] = number +// } else { +// parsedPhoneNumber = nil +// } +// +// if parsedPeerPhoneNumber == parsedPhoneNumber { +// result.append((contact.stableId, peer)) +// continue outer +// } +// } +// } } } return result diff --git a/SiriIntents/IntentHandler.swift b/SiriIntents/IntentHandler.swift index b79c9b2d39..1bc5d9ab2a 100644 --- a/SiriIntents/IntentHandler.swift +++ b/SiriIntents/IntentHandler.swift @@ -4,6 +4,7 @@ import TelegramCore import Postbox import SwiftSignalKit import BuildConfig +import Contacts private var accountCache: Account? @@ -47,7 +48,7 @@ enum IntentHandlingError { } class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling, INStartAudioCallIntentHandling, INSearchCallHistoryIntentHandling { - private let accountPromise = Promise() + private let accountPromise = Promise() private let resolvePersonsDisposable = MetaDisposable() private let actionDisposable = MetaDisposable() @@ -86,7 +87,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown" - let account: Signal + let account: Signal if let accountCache = accountCache { account = .single(accountCache) } else { @@ -97,7 +98,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag let encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!) account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, appData: .single(buildConfig.bundleData(withAppToken: nil))), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: accountAuxiliaryMethods, encryptionParameters: encryptionParameters) - |> mapToSignal { account -> Signal in + |> mapToSignal { account -> Signal in if let account = account { switch account { case .upgrading: @@ -117,12 +118,9 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag return .complete() } } else { - return .complete() + return .single(nil) } } - |> afterNext { account in - account.resetStateManagement() - } |> take(1) } self.accountPromise.set(account) @@ -138,6 +136,11 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag } private func resolve(persons: [INPerson]?, with completion: @escaping ([INPersonResolutionResult]) -> Void) { + guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else { + completion([INPersonResolutionResult.notRequired()]) + return + } + guard let initialPersons = persons, !initialPersons.isEmpty else { completion([INPersonResolutionResult.needsValue()]) return @@ -205,8 +208,14 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag |> take(1) |> mapToSignal { matchedContacts in return account - |> mapToSignal { account in - return matchingCloudContacts(postbox: account.postbox, contacts: matchedContacts) + |> introduceError(IntentContactsError.self) + |> mapToSignal { account -> Signal<[(String, TelegramUser)], IntentContactsError> in + if let account = account { + return matchingCloudContacts(postbox: account.postbox, contacts: matchedContacts) + |> introduceError(IntentContactsError.self) + } else { + return .fail(.generic) + } } } self.resolvePersonsDisposable.set((signal @@ -219,6 +228,8 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag return INPersonResolutionResult.success(with: person) }) } + }, error: { error in + completion([INPersonResolutionResult.unsupported()]) })) } @@ -230,14 +241,20 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag let account = self.accountPromise.get() let signal = account - |> mapToSignal { account -> Signal in - return matchingCloudContact(postbox: account.postbox, peerId: PeerId(peerId)) - |> map { user -> INPerson? in - if let user = user { - return personWithUser(stableId: "tg\(peerId)", user: user) - } else { - return nil + |> introduceError(IntentHandlingError.self) + |> mapToSignal { account -> Signal in + if let account = account { + return matchingCloudContact(postbox: account.postbox, peerId: PeerId(peerId)) + |> introduceError(IntentHandlingError.self) + |> map { user -> INPerson? in + if let user = user { + return personWithUser(stableId: "tg\(peerId)", user: user) + } else { + return nil + } } + } else { + return .fail(.generic) } } @@ -248,6 +265,8 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag } else { completion([INPersonResolutionResult.needsValue()]) } + }, error: { error in + completion([INPersonResolutionResult.notRequired()]) })) } else { self.resolve(persons: intent.recipients, with: completion) @@ -258,6 +277,10 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag } func resolveContent(for intent: INSendMessageIntent, with completion: @escaping (INStringResolutionResult) -> Void) { + guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else { + completion(INStringResolutionResult.notRequired()) + return + } if let text = intent.content, !text.isEmpty { completion(INStringResolutionResult.success(with: text)) } else { @@ -267,6 +290,11 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag func confirm(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) { let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self)) + guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else { + let response = INSendMessageIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity) + completion(response) + return + } let response = INSendMessageIntentResponse(code: .ready, userActivity: userActivity) completion(response) } @@ -278,6 +306,9 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag return .generic } |> mapToSignal { account -> Signal in + guard let account = account else { + return .fail(.generic) + } guard let recipient = intent.recipients?.first, let customIdentifier = recipient.customIdentifier, customIdentifier.hasPrefix("tg") else { return .fail(.generic) } @@ -305,7 +336,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag } |> deliverOnMainQueue).start(error: { _ in let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self)) - let response = INSendMessageIntentResponse(code: .failure, userActivity: userActivity) + let response = INSendMessageIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity) completion(response) }, completed: { let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self)) @@ -325,18 +356,27 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag |> take(1) |> introduceError(IntentHandlingError.self) |> mapToSignal { account -> Signal<[INMessage], IntentHandlingError> in + guard let account = account else { + return .fail(.generic) + } + account.shouldBeServiceTaskMaster.set(.single(.now)) account.resetStateManagement() - return account.stateManager.pollStateUpdateCompletion() + let completion: Signal = account.stateManager.pollStateUpdateCompletion() + |> map { _ in + return Void() + } + + return (completion |> timeout(4.0, queue: Queue.mainQueue(), alternate: .single(Void()))) |> introduceError(IntentHandlingError.self) |> take(1) |> mapToSignal { _ -> Signal<[INMessage], IntentHandlingError> in return unreadMessages(account: account) |> introduceError(IntentHandlingError.self) - } - |> afterDisposed { - account.shouldBeServiceTaskMaster.set(.single(.never)) + |> afterDisposed { + account.shouldBeServiceTaskMaster.set(.single(.never)) + } } } |> deliverOnMainQueue).start(next: { messages in @@ -346,7 +386,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag completion(response) }, error: { _ in let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchForMessagesIntent.self)) - let response = INSearchForMessagesIntentResponse(code: .failure, userActivity: userActivity) + let response = INSearchForMessagesIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity) completion(response) })) } @@ -373,8 +413,11 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag return .generic } |> mapToSignal { account -> Signal in - var signals: [Signal] = [] + guard let account = account else { + return .fail(.generic) + } + var signals: [Signal] = [] var maxMessageIdsToApply: [PeerId: MessageId] = [:] if let identifiers = intent.identifiers { for identifier in identifiers { @@ -478,6 +521,10 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag |> take(1) |> introduceError(IntentHandlingError.self) |> mapToSignal { account -> Signal<[CallRecord], IntentHandlingError> in + guard let account = account else { + return .fail(.generic) + } + account.shouldBeServiceTaskMaster.set(.single(.now)) return missedCalls(account: account) |> introduceError(IntentHandlingError.self) @@ -497,7 +544,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag completion(response) }, error: { _ in let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchCallHistoryIntent.self)) - let response = INSearchCallHistoryIntentResponse(code: .failure, userActivity: userActivity) + let response = INSearchCallHistoryIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity) completion(response) })) } diff --git a/SiriIntents/IntentMessages.swift b/SiriIntents/IntentMessages.swift index 8e29092f39..904faa445c 100644 --- a/SiriIntents/IntentMessages.swift +++ b/SiriIntents/IntentMessages.swift @@ -13,6 +13,10 @@ func unreadMessages(account: Account) -> Signal<[INMessage], NoError> { var signals: [Signal<[INMessage], NoError>] = [] for entry in view.0.entries { if case let .MessageEntry(index, _, readState, notificationSettings, _, _, _, _) = entry { + if index.messageIndex.id.peerId.namespace != Namespaces.Peer.CloudUser { + continue + } + var hasUnread = false var fixedCombinedReadStates: MessageHistoryViewReadState? if let readState = readState { @@ -133,7 +137,7 @@ private func callWithTelegramMessage(_ telegramMessage: Message, account: Accoun } private func messageWithTelegramMessage(_ telegramMessage: Message, account: Account) -> INMessage? { - guard let author = telegramMessage.author, let user = telegramMessage.peers[author.id] as? TelegramUser else { + guard let author = telegramMessage.author, let user = telegramMessage.peers[author.id] as? TelegramUser, user.id.id != 777000 else { return nil } @@ -194,9 +198,16 @@ private func messageWithTelegramMessage(_ telegramMessage: Message, account: Acc break loop } } + + if telegramMessage.text.isEmpty && messageType == .text { + return nil + } message = INMessage(identifier: identifier, conversationIdentifier: "\(telegramMessage.id.peerId.toInt64())", content: telegramMessage.text, dateSent: date, sender: sender, recipients: [], groupName: nil, messageType: messageType) } else { + if telegramMessage.text.isEmpty { + return nil + } message = INMessage(identifier: identifier, content: telegramMessage.text, dateSent: date, sender: sender, recipients: []) } diff --git a/submodules/TelegramCore/TelegramCore/Account.swift b/submodules/TelegramCore/TelegramCore/Account.swift index bdf726a392..09546839d5 100644 --- a/submodules/TelegramCore/TelegramCore/Account.swift +++ b/submodules/TelegramCore/TelegramCore/Account.swift @@ -1304,7 +1304,10 @@ public class Account { self.managedOperationsDisposable.add(managedPendingPeerNotificationSettings(postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedSynchronizeAppLogEventsOperations(postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedNotificationSettingsBehaviors(postbox: self.postbox).start()) - self.managedOperationsDisposable.add(managedAnimatedEmojiUpdates(postbox: self.postbox, network: self.network).start()) + + if !self.supplementary { + self.managedOperationsDisposable.add(managedAnimatedEmojiUpdates(postbox: self.postbox, network: self.network).start()) + } let mediaBox = postbox.mediaBox self.storageSettingsDisposable = accountManager.sharedData(keys: [SharedDataKeys.cacheStorageSettings]).start(next: { [weak mediaBox] sharedData in diff --git a/submodules/TelegramCore/TelegramCore/PhoneNumbers.swift b/submodules/TelegramCore/TelegramCore/PhoneNumbers.swift index ce5c9a345d..7bcbd37500 100644 --- a/submodules/TelegramCore/TelegramCore/PhoneNumbers.swift +++ b/submodules/TelegramCore/TelegramCore/PhoneNumbers.swift @@ -16,11 +16,27 @@ public func isViablePhoneNumber(_ string: String) -> Bool { return phoneNumberUtil.isViablePhoneNumber(string) } -public func arePhoneNumbersEqual(_ lhs: String, _ rhs: String) -> Bool { - let result = phoneNumberUtil.isNumberMatch(lhs as NSString, second: rhs as NSString, error: nil) - if result != .NO_MATCH && result != .NOT_A_NUMBER { - return true - } else { - return false +public class ParsedPhoneNumber: Equatable { + let rawPhoneNumber: NBPhoneNumber? + + public init?(string: String) { + if let number = try? phoneNumberUtil.parse(string, defaultRegion: NB_UNKNOWN_REGION) { + self.rawPhoneNumber = number + } else { + return nil + } + } + + public static func == (lhs: ParsedPhoneNumber, rhs: ParsedPhoneNumber) -> Bool { + var error: NSError? + let result = phoneNumberUtil.isNumberMatch(lhs.rawPhoneNumber, second: rhs.rawPhoneNumber, error: &error) + if error != nil { + return false + } + if result != .NO_MATCH && result != .NOT_A_NUMBER { + return true + } else { + return false + } } } From 42673dc7f0ba37737573aa5ad95df3d916a57ceb Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 1 Aug 2019 01:42:30 +0300 Subject: [PATCH 17/41] Tuned heartbeat --- .../TelegramUI/ChatMessageAnimatedStickerItemNode.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index f417745b12..8f402cdf45 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -679,12 +679,12 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { hapticFeedback.impact(.heavy) Queue.mainQueue().after(0.2) { hapticFeedback.impact(.medium) - Queue.mainQueue().after(0.74) { - hapticFeedback.impact(.medium) + Queue.mainQueue().after(0.78) { + hapticFeedback.impact(.heavy) Queue.mainQueue().after(0.2) { hapticFeedback.impact(.medium) - Queue.mainQueue().after(0.74) { - hapticFeedback.impact(.medium) + Queue.mainQueue().after(0.78) { + hapticFeedback.impact(.heavy) Queue.mainQueue().after(0.2) { hapticFeedback.impact(.medium) } From 23c76db8f4a1bb243e5fd4571b501ecc16b3560e Mon Sep 17 00:00:00 2001 From: Peter <> Date: Thu, 1 Aug 2019 01:45:55 +0300 Subject: [PATCH 18/41] Fix animated stickers --- .../Telegram-iOS-Hockeyapp-Internal.xcscheme | 1 - .../Display/Display/GenerateImage.swift | 71 +++++++++++++++++++ .../TelegramUI/AnimatedStickerNode.swift | 7 ++ .../TelegramUI/AnimatedStickerUtils.swift | 30 ++++---- .../CachedResourceRepresentations.swift | 2 +- .../TelegramUI/StickerResources.swift | 3 - submodules/TelegramUI/TelegramUI/YUV.m | 33 +++++---- 7 files changed, 118 insertions(+), 29 deletions(-) diff --git a/Telegram-iOS.xcworkspace/xcshareddata/xcschemes/Telegram-iOS-Hockeyapp-Internal.xcscheme b/Telegram-iOS.xcworkspace/xcshareddata/xcschemes/Telegram-iOS-Hockeyapp-Internal.xcscheme index 2db06cb59b..61e39f8bfe 100644 --- a/Telegram-iOS.xcworkspace/xcshareddata/xcschemes/Telegram-iOS-Hockeyapp-Internal.xcscheme +++ b/Telegram-iOS.xcworkspace/xcshareddata/xcschemes/Telegram-iOS-Hockeyapp-Internal.xcscheme @@ -81,7 +81,6 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" enableAddressSanitizer = "YES" enableASanStackUseAfterReturn = "YES" - enableUBSanitizer = "YES" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/submodules/Display/Display/GenerateImage.swift b/submodules/Display/Display/GenerateImage.swift index 7c02da4e7c..7fd2d96038 100644 --- a/submodules/Display/Display/GenerateImage.swift +++ b/submodules/Display/Display/GenerateImage.swift @@ -1,5 +1,6 @@ import Foundation import UIKit +import Accelerate private let deviceColorSpace: CGColorSpace = { if #available(iOSApplicationExtension 9.3, *) { @@ -13,6 +14,8 @@ private let deviceColorSpace: CGColorSpace = { } }() +private let grayscaleColorSpace = CGColorSpaceCreateDeviceGray() + let deviceScale = UIScreen.main.scale public func generateImagePixel(_ size: CGSize, scale: CGFloat, pixelGenerator: (CGSize, UnsafeMutablePointer, Int) -> Void) -> UIImage? { @@ -39,6 +42,74 @@ public func generateImagePixel(_ size: CGSize, scale: CGFloat, pixelGenerator: ( return UIImage(cgImage: image, scale: scale, orientation: .up) } +private func withImageBytes(image: UIImage, _ f: (UnsafePointer, Int, Int, Int) -> Void) { + let selectedScale = image.scale + let scaledSize = CGSize(width: image.size.width * selectedScale, height: image.size.height * selectedScale) + let bytesPerRow = (4 * Int(scaledSize.width) + 15) & (~15) + let length = bytesPerRow * Int(scaledSize.height) + let bytes = malloc(length)!.assumingMemoryBound(to: UInt8.self) + memset(bytes, 0, length) + + let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue) + + guard let context = CGContext(data: bytes, width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: deviceColorSpace, bitmapInfo: bitmapInfo.rawValue) else { + return + } + + context.scaleBy(x: selectedScale, y: selectedScale) + context.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: image.size)) + + f(bytes, Int(scaledSize.width), Int(scaledSize.height), bytesPerRow) +} + +public func generateGrayscaleAlphaMaskImage(image: UIImage) -> UIImage? { + let selectedScale = image.scale + let scaledSize = CGSize(width: image.size.width * selectedScale, height: image.size.height * selectedScale) + let bytesPerRow = (1 * Int(scaledSize.width) + 15) & (~15) + let length = bytesPerRow * Int(scaledSize.height) + let bytes = malloc(length)!.assumingMemoryBound(to: UInt8.self) + memset(bytes, 0, length) + + guard let provider = CGDataProvider(dataInfo: bytes, data: bytes, size: length, releaseData: { bytes, _, _ in + free(bytes) + }) + else { + return nil + } + + let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue) + + guard let context = CGContext(data: bytes, width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: grayscaleColorSpace, bitmapInfo: bitmapInfo.rawValue) else { + return nil + } + + context.scaleBy(x: selectedScale, y: selectedScale) + + withImageBytes(image: image, { pixels, width, height, imageBytesPerRow in + var src = vImage_Buffer(data: UnsafeMutableRawPointer(mutating: pixels), height: vImagePixelCount(height), width: vImagePixelCount(width), rowBytes: imageBytesPerRow) + + let permuteMap: [UInt8] = [3, 2, 1, 0] + vImagePermuteChannels_ARGB8888(&src, &src, permuteMap, vImage_Flags(kvImageDoNotTile)) + vImageUnpremultiplyData_ARGB8888(&src, &src, vImage_Flags(kvImageDoNotTile)) + + for y in 0 ..< Int(scaledSize.height) { + let srcRowBytes = pixels.advanced(by: y * imageBytesPerRow) + let dstRowBytes = bytes.advanced(by: y * bytesPerRow) + for x in 0 ..< Int(scaledSize.width) { + let a = srcRowBytes.advanced(by: x * 4 + 0).pointee + dstRowBytes.advanced(by: x).pointee = 0xff &- a + } + } + }) + + guard let image = CGImage(width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bitsPerPixel: 8, bytesPerRow: bytesPerRow, space: grayscaleColorSpace, bitmapInfo: bitmapInfo, provider: provider, decode: nil, shouldInterpolate: false, intent: .defaultIntent) + else { + return nil + } + + return UIImage(cgImage: image, scale: selectedScale, orientation: .up) +} + public func generateImage(_ size: CGSize, contextGenerator: (CGSize, CGContext) -> Void, opaque: Bool = false, scale: CGFloat? = nil) -> UIImage? { let selectedScale = scale ?? deviceScale let scaledSize = CGSize(width: size.width * selectedScale, height: size.height * selectedScale) diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift index 986b3d8307..cd1448d983 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift @@ -195,6 +195,13 @@ private final class AnimatedStickerCachedFrameSource: AnimatedStickerFrameSource lhs = lhs.advanced(by: 1) rhs = rhs.advanced(by: 1) } + var lhsRest = UnsafeMutableRawPointer(frameBytes).assumingMemoryBound(to: UInt8.self).advanced(by: (decodeBufferLength / 8) * 8) + var rhsRest = UnsafeMutableRawPointer(decodeBytes).assumingMemoryBound(to: UInt8.self).advanced(by: (decodeBufferLength / 8) * 8) + for _ in (decodeBufferLength / 8) * 8 ..< decodeBufferLength { + lhsRest.pointee = rhsRest.pointee ^ lhsRest.pointee + lhsRest = lhsRest.advanced(by: 1) + rhsRest = rhsRest.advanced(by: 1) + } frameData = Data(bytes: frameBytes, count: decodeBufferLength) } diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift index 541d311c4a..bb317b7bf1 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift @@ -99,19 +99,21 @@ func fetchCompressedLottieFirstFrameAJpeg(data: Data, size: CGSize, cacheKey: St encodeRGBAToYUVA(yuvaFrameData.assumingMemoryBound(to: UInt8.self), context.bytes.assumingMemoryBound(to: UInt8.self), Int32(size.width), Int32(size.height), Int32(context.bytesPerRow)) decodeYUVAToRGBA(yuvaFrameData.assumingMemoryBound(to: UInt8.self), context.bytes.assumingMemoryBound(to: UInt8.self), Int32(size.width), Int32(size.height), Int32(context.bytesPerRow)) - if let colorImage = context.generateImage() { + if let colorSourceImage = context.generateImage(), let alphaImage = generateGrayscaleAlphaMaskImage(image: colorSourceImage) { + let colorContext = DrawingContext(size: size, scale: 1.0, clear: false) + colorContext.withFlippedContext { c in + c.setFillColor(UIColor.black.cgColor) + c.fill(CGRect(origin: CGPoint(), size: size)) + c.draw(colorSourceImage.cgImage!, in: CGRect(origin: CGPoint(), size: size)) + } + guard let colorImage = colorContext.generateImage() else { + return + } + let colorData = NSMutableData() let alphaData = NSMutableData() - let alphaImage = generateImage(size, contextGenerator: { size, context in - context.setFillColor(UIColor.white.cgColor) - context.fill(CGRect(origin: CGPoint(), size: size)) - context.clip(to: CGRect(origin: CGPoint(), size: size), mask: colorImage.cgImage!) - context.setFillColor(UIColor.black.cgColor) - context.fill(CGRect(origin: CGPoint(), size: size)) - }, scale: 1.0) - - if let alphaImage = alphaImage, let colorDestination = CGImageDestinationCreateWithData(colorData as CFMutableData, kUTTypeJPEG, 1, nil), let alphaDestination = CGImageDestinationCreateWithData(alphaData as CFMutableData, kUTTypeJPEG, 1, nil) { + if let colorDestination = CGImageDestinationCreateWithData(colorData as CFMutableData, kUTTypeJPEG, 1, nil), let alphaDestination = CGImageDestinationCreateWithData(alphaData as CFMutableData, kUTTypeJPEG, 1, nil) { CGImageDestinationSetProperties(colorDestination, [:] as CFDictionary) CGImageDestinationSetProperties(alphaDestination, [:] as CFDictionary) @@ -257,8 +259,12 @@ func experimentalConvertCompressedLottieToCombinedMp4(data: Data, size: CGSize, lhs = lhs.advanced(by: 1) rhs = rhs.advanced(by: 1) } - for i in (yuvaLength / 8) * 8 ..< yuvaLength { - + var lhsRest = previousYuvaFrameData.assumingMemoryBound(to: UInt8.self).advanced(by: (yuvaLength / 8) * 8) + var rhsRest = yuvaFrameData.assumingMemoryBound(to: UInt8.self).advanced(by: (yuvaLength / 8) * 8) + for _ in (yuvaLength / 8) * 8 ..< yuvaLength { + lhsRest.pointee = rhsRest.pointee ^ lhsRest.pointee + lhsRest = lhsRest.advanced(by: 1) + rhsRest = rhsRest.advanced(by: 1) } deltaTime += CACurrentMediaTime() - deltaStartTime diff --git a/submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift b/submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift index cdd435ad6a..e962023208 100644 --- a/submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift +++ b/submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift @@ -271,7 +271,7 @@ final class CachedAnimatedStickerRepresentation: CachedMediaResourceRepresentati let height: Int32 var uniqueId: String { - return "animated-sticker-\(self.width)x\(self.height)-v6" + return "animated-sticker-\(self.width)x\(self.height)-v7" } init(width: Int32, height: Int32) { diff --git a/submodules/TelegramUI/TelegramUI/StickerResources.swift b/submodules/TelegramUI/TelegramUI/StickerResources.swift index 73e54f2246..772a8c99a2 100644 --- a/submodules/TelegramUI/TelegramUI/StickerResources.swift +++ b/submodules/TelegramUI/TelegramUI/StickerResources.swift @@ -551,9 +551,6 @@ public func chatMessageAnimatedSticker(postbox: Postbox, file: TelegramMediaFile } } - let img = context.generateImage() - let cgImg = img?.cgImage - return context } } diff --git a/submodules/TelegramUI/TelegramUI/YUV.m b/submodules/TelegramUI/TelegramUI/YUV.m index 78381d714e..08a52aba58 100644 --- a/submodules/TelegramUI/TelegramUI/YUV.m +++ b/submodules/TelegramUI/TelegramUI/YUV.m @@ -22,12 +22,16 @@ void encodeRGBAToYUVA(uint8_t *yuva, uint8_t const *argb, int width, int height, error = vImageUnpremultiplyData_ARGB8888(&src, &src, kvImageDoNotTile); - uint8_t *buf = (uint8_t *)argb; - uint8_t *alpha = yuva + (width * height * 1 + width * height * 1); - for (int i = 0; i < width * height; i += 2) { - uint8_t a0 = (buf[i * 4 + 0] >> 4) << 4; - uint8_t a1 = (buf[(i + 1) * 4 + 0] >> 4) << 4; - alpha[i / 2] = (a0 & (0xf0U)) | ((a1 & (0xf0U)) >> 4); + uint8_t *alpha = yuva + width * height * 2; + int i = 0; + for (int y = 0; y < height; y += 1) { + uint8_t const *argbRow = argb + y * bytesPerRow; + for (int x = 0; x < width; x += 2) { + uint8_t a0 = (argbRow[x * 4 + 0] >> 4) << 4; + uint8_t a1 = (argbRow[(x + 1) * 4 + 0] >> 4) << 4; + alpha[i / 2] = (a0 & (0xf0U)) | ((a1 & (0xf0U)) >> 4); + i += 2; + } } vImage_Buffer destYp; @@ -79,12 +83,17 @@ void decodeYUVAToRGBA(uint8_t const *yuva, uint8_t *argb, int width, int height, error = vImageConvert_420Yp8_CbCr8ToARGB8888(&srcYp, &srcCbCr, &dest, &info, NULL, 0xff, kvImageDoNotTile); uint8_t const *alpha = yuva + (width * height * 1 + width * height * 1); - for (int i = 0; i < width * height; i += 2) { - uint8_t a = alpha[i / 2]; - uint8_t a1 = (a & (0xf0U)); - uint8_t a2 = ((a & (0x0fU)) << 4); - argb[i * 4 + 0] = a1 | (a1 >> 4); - argb[(i + 1) * 4 + 0] = a2 | (a2 >> 4); + int i = 0; + for (int y = 0; y < height; y += 1) { + uint8_t *argbRow = argb + y * bytesPerRow; + for (int x = 0; x < width; x += 2) { + uint8_t a = alpha[i / 2]; + uint8_t a1 = (a & (0xf0U)); + uint8_t a2 = ((a & (0x0fU)) << 4); + argbRow[x * 4 + 0] = a1 | (a1 >> 4); + argbRow[(x + 1) * 4 + 0] = a2 | (a2 >> 4); + i += 2; + } } error = vImagePremultiplyData_ARGB8888(&dest, &dest, kvImageDoNotTile); From 35ef08fc06dcf4204486c3cdbcdaf83e7b0ca539 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 1 Aug 2019 04:10:51 +0300 Subject: [PATCH 19/41] UI fixes --- .../TelegramUI/TelegramUI/ChatHistoryListNode.swift | 2 +- .../ChatMessageAnimatedStickerItemNode.swift | 12 ++++++------ .../TelegramUI/ThemeSettingsController.swift | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift index 55c06eeedf..61c0929385 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift @@ -545,7 +545,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { var animatedEmojiStickers: [String: StickerPackItem] = [:] for case let item as StickerPackItem in items { if let emoji = item.getStringRepresentationsOfIndexKeys().first { - animatedEmojiStickers[emoji] = item + animatedEmojiStickers[emoji.trimmedEmoji] = item } } return animatedEmojiStickers diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index 8f402cdf45..43a818c58e 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -676,17 +676,17 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { self.hapticFeedback = hapticFeedback } hapticFeedback.prepareImpact() - hapticFeedback.impact(.heavy) + hapticFeedback.impact(.medium) Queue.mainQueue().after(0.2) { - hapticFeedback.impact(.medium) + hapticFeedback.impact(.light) Queue.mainQueue().after(0.78) { - hapticFeedback.impact(.heavy) + hapticFeedback.impact(.medium) Queue.mainQueue().after(0.2) { - hapticFeedback.impact(.medium) + hapticFeedback.impact(.light) Queue.mainQueue().after(0.78) { - hapticFeedback.impact(.heavy) + hapticFeedback.impact(.medium) Queue.mainQueue().after(0.2) { - hapticFeedback.impact(.medium) + hapticFeedback.impact(.light) } } } diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift index 75e291f4ca..a962138eea 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift @@ -437,8 +437,8 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The let fontSize = settings.fontSize let dateTimeFormat = presentationData.dateTimeFormat - let largeEmoji = settings.largeEmoji - let disableAnimations = settings.disableAnimations + let largeEmoji = presentationData.largeEmoji + let disableAnimations = presentationData.disableAnimations let accentColor = settings.themeSpecificAccentColors[settings.theme.index]?.color let theme = makePresentationTheme(themeReference: settings.theme, accentColor: accentColor, serviceBackgroundColor: defaultServiceBackgroundColor, preview: true) From 7d434ac5c9b54c5baeb8c896063fbda4e93d282c Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 1 Aug 2019 12:23:56 +0300 Subject: [PATCH 20/41] Don't autoplay previously seen animated emoji on repeated appearance on screen --- .../TelegramUI/AnimatedStickerNode.swift | 6 +- .../ChatControllerInteraction.swift | 1 + .../ChatMessageAnimatedStickerItemNode.swift | 69 +++++++++++-------- .../TelegramUI/DebugController.swift | 20 +----- .../Sources/ExperimentalUISettings.swift | 8 +-- 5 files changed, 53 insertions(+), 51 deletions(-) diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift index cd1448d983..51d72672c7 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift @@ -306,6 +306,9 @@ final class AnimatedStickerNode: ASDisplayNode { private let fetchDisposable = MetaDisposable() private let eventsNode: AnimatedStickerNodeDisplayEvents + var shouldAutoPlay: () -> Bool = { + return true + } var started: () -> Void = {} var reportedStarted = false @@ -407,7 +410,7 @@ final class AnimatedStickerNode: ASDisplayNode { } private func updateIsPlaying() { - let isPlaying = self.visibility && self.isDisplaying + let isPlaying = self.visibility && self.isDisplaying && self.shouldAutoPlay() if self.isPlaying != isPlaying { self.isPlaying = isPlaying if isPlaying { @@ -454,6 +457,7 @@ final class AnimatedStickerNode: ASDisplayNode { return } if !strongSelf.reportedStarted { + strongSelf.reportedStarted = true strongSelf.started() } }) diff --git a/submodules/TelegramUI/TelegramUI/ChatControllerInteraction.swift b/submodules/TelegramUI/TelegramUI/ChatControllerInteraction.swift index 3fdd99985b..b68c91ae19 100644 --- a/submodules/TelegramUI/TelegramUI/ChatControllerInteraction.swift +++ b/submodules/TelegramUI/TelegramUI/ChatControllerInteraction.swift @@ -123,6 +123,7 @@ public final class ChatControllerInteraction { var pollActionState: ChatInterfacePollActionState var stickerSettings: ChatInterfaceStickerSettings var searchTextHighightState: String? + var seenOneTimeAnimatedMedia = Set() init(openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool, openPeer: @escaping (PeerId?, ChatControllerInteractionNavigateToPeer, Message?) -> Void, openPeerMention: @escaping (String) -> Void, openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect) -> Void, navigateToMessage: @escaping (MessageId, MessageId) -> Void, clickThroughMessage: @escaping () -> Void, toggleMessagesSelection: @escaping ([MessageId], Bool) -> Void, sendCurrentMessage: @escaping (Bool) -> Void, sendMessage: @escaping (String) -> Void, sendSticker: @escaping (FileMediaReference, Bool, ASDisplayNode, CGRect) -> Bool, sendGif: @escaping (FileMediaReference, ASDisplayNode, CGRect) -> Bool, requestMessageActionCallback: @escaping (MessageId, MemoryBuffer?, Bool) -> Void, requestMessageActionUrlAuth: @escaping (String, MessageId, Int32) -> Void, activateSwitchInline: @escaping (PeerId?, String) -> Void, openUrl: @escaping (String, Bool, Bool?) -> Void, shareCurrentLocation: @escaping () -> Void, shareAccountContact: @escaping () -> Void, sendBotCommand: @escaping (MessageId?, String) -> Void, openInstantPage: @escaping (Message, ChatMessageItemAssociatedData?) -> Void, openWallpaper: @escaping (Message) -> Void, openHashtag: @escaping (String?, String) -> Void, updateInputState: @escaping ((ChatTextInputState) -> ChatTextInputState) -> Void, updateInputMode: @escaping ((ChatInputMode) -> ChatInputMode) -> Void, openMessageShareMenu: @escaping (MessageId) -> Void, presentController: @escaping (ViewController, Any?) -> Void, navigationController: @escaping () -> NavigationController?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, callPeer: @escaping (PeerId) -> Void, longTap: @escaping (ChatControllerInteractionLongTapAction, Message?) -> Void, openCheckoutOrReceipt: @escaping (MessageId) -> Void, openSearch: @escaping () -> Void, setupReply: @escaping (MessageId) -> Void, canSetupReply: @escaping (Message) -> Bool, navigateToFirstDateMessage: @escaping(Int32) ->Void, requestRedeliveryOfFailedMessages: @escaping (MessageId) -> Void, addContact: @escaping (String) -> Void, rateCall: @escaping (Message, CallId) -> Void, requestSelectMessagePollOption: @escaping (MessageId, Data) -> Void, openAppStorePage: @escaping () -> Void, displayMessageTooltip: @escaping (MessageId, String, ASDisplayNode?, CGRect?) -> Void, seekToTimecode: @escaping (Message, Double, Bool) -> Void, requestMessageUpdate: @escaping (MessageId) -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void, automaticMediaDownloadSettings: MediaAutoDownloadSettings, pollActionState: ChatInterfacePollActionState, stickerSettings: ChatInterfaceStickerSettings) { self.openMessage = openMessage diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index 43a818c58e..82be722df1 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -51,7 +51,26 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { super.init(layerBacked: false) self.animationNode.started = { [weak self] in - self?.imageNode.alpha = 0.0 + if let strongSelf = self { + strongSelf.imageNode.alpha = 0.0 + + if let item = strongSelf.item { + if let _ = strongSelf.emojiFile { + item.controllerInteraction.seenOneTimeAnimatedMedia.insert(item.message.id) + } + } + } + } + + self.animationNode.shouldAutoPlay = { [weak self] in + if let strongSelf = self { + if let item = strongSelf.item { + if let _ = strongSelf.emojiFile { + return !item.controllerInteraction.seenOneTimeAnimatedMedia.contains(item.message.id) + } + } + } + return true } self.imageNode.displaysAsynchronously = false @@ -171,9 +190,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } else if let emojiFile = self.emojiFile { isEmoji = true file = emojiFile - if item.context.sharedContext.immediateExperimentalUISettings.playAnimatedEmojiOnce { - playbackMode = .once - } + playbackMode = .once } if let file = file { @@ -665,29 +682,27 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if self.telegramFile != nil { let _ = item.controllerInteraction.openMessage(item.message, .default) } else if let _ = self.emojiFile { - if item.context.sharedContext.immediateExperimentalUISettings.playAnimatedEmojiOnce { - if self.animationNode.playIfNeeded() { - if self.item?.message.text == "❤️" { - let hapticFeedback: HapticFeedback - if let currentHapticFeedback = self.hapticFeedback { - hapticFeedback = currentHapticFeedback - } else { - hapticFeedback = HapticFeedback() - self.hapticFeedback = hapticFeedback - } - hapticFeedback.prepareImpact() - hapticFeedback.impact(.medium) - Queue.mainQueue().after(0.2) { - hapticFeedback.impact(.light) - Queue.mainQueue().after(0.78) { - hapticFeedback.impact(.medium) - Queue.mainQueue().after(0.2) { - hapticFeedback.impact(.light) - Queue.mainQueue().after(0.78) { - hapticFeedback.impact(.medium) - Queue.mainQueue().after(0.2) { - hapticFeedback.impact(.light) - } + if self.animationNode.playIfNeeded() { + if self.item?.message.text == "❤️" { + let hapticFeedback: HapticFeedback + if let currentHapticFeedback = self.hapticFeedback { + hapticFeedback = currentHapticFeedback + } else { + hapticFeedback = HapticFeedback() + self.hapticFeedback = hapticFeedback + } + hapticFeedback.prepareImpact() + hapticFeedback.impact(.medium) + Queue.mainQueue().after(0.2) { + hapticFeedback.impact(.light) + Queue.mainQueue().after(0.78) { + hapticFeedback.impact(.medium) + Queue.mainQueue().after(0.2) { + hapticFeedback.impact(.light) + Queue.mainQueue().after(0.78) { + hapticFeedback.impact(.medium) + Queue.mainQueue().after(0.2) { + hapticFeedback.impact(.light) } } } diff --git a/submodules/TelegramUI/TelegramUI/DebugController.swift b/submodules/TelegramUI/TelegramUI/DebugController.swift index c7c4a1b12a..11bed23910 100644 --- a/submodules/TelegramUI/TelegramUI/DebugController.swift +++ b/submodules/TelegramUI/TelegramUI/DebugController.swift @@ -57,7 +57,6 @@ private enum DebugControllerEntry: ItemListNodeEntry { case resetBiometricsData(PresentationTheme) case optimizeDatabase(PresentationTheme) case photoPreview(PresentationTheme, Bool) - case playAnimatedEmojiOnce(PresentationTheme, Bool) case exportTheme(PresentationTheme) case versionInfo(PresentationTheme) @@ -71,7 +70,7 @@ private enum DebugControllerEntry: ItemListNodeEntry { return DebugControllerSection.logging.rawValue case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries: return DebugControllerSection.experiments.rawValue - case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .playAnimatedEmojiOnce, .exportTheme: + case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .exportTheme: return DebugControllerSection.experiments.rawValue case .versionInfo: return DebugControllerSection.info.rawValue @@ -120,12 +119,10 @@ private enum DebugControllerEntry: ItemListNodeEntry { return 18 case .photoPreview: return 19 - case .playAnimatedEmojiOnce: - return 20 case .exportTheme: - return 21 + return 20 case .versionInfo: - return 22 + return 21 } } @@ -472,16 +469,6 @@ private enum DebugControllerEntry: ItemListNodeEntry { }) }).start() }) - case let .playAnimatedEmojiOnce(theme, value): - return ItemListSwitchItem(theme: theme, title: "Play Emoji Once", value: value, sectionId: self.section, style: .blocks, updated: { value in - let _ = arguments.sharedContext.accountManager.transaction ({ transaction in - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in - var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings - settings.playAnimatedEmojiOnce = value - return settings - }) - }).start() - }) case let .exportTheme(theme): return ItemListActionItem(theme: theme, title: "Export Theme", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { guard let context = arguments.context else { @@ -549,7 +536,6 @@ private func debugControllerEntries(presentationData: PresentationData, loggingS entries.append(.resetHoles(presentationData.theme)) entries.append(.optimizeDatabase(presentationData.theme)) entries.append(.photoPreview(presentationData.theme, experimentalSettings.chatListPhotos)) - entries.append(.playAnimatedEmojiOnce(presentationData.theme, experimentalSettings.playAnimatedEmojiOnce)) entries.append(.versionInfo(presentationData.theme)) diff --git a/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift b/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift index 1ca96950e7..37d8e96724 100644 --- a/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift +++ b/submodules/TelegramUIPreferences/Sources/ExperimentalUISettings.swift @@ -7,18 +7,16 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry { public var skipReadHistory: Bool public var crashOnLongQueries: Bool public var chatListPhotos: Bool - public var playAnimatedEmojiOnce: Bool public static var defaultSettings: ExperimentalUISettings { - return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false, chatListPhotos: false, playAnimatedEmojiOnce: true) + return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false, chatListPhotos: false) } - public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool, chatListPhotos: Bool, playAnimatedEmojiOnce: Bool) { + public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool, chatListPhotos: Bool) { self.keepChatNavigationStack = keepChatNavigationStack self.skipReadHistory = skipReadHistory self.crashOnLongQueries = crashOnLongQueries self.chatListPhotos = chatListPhotos - self.playAnimatedEmojiOnce = playAnimatedEmojiOnce } public init(decoder: PostboxDecoder) { @@ -26,7 +24,6 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry { self.skipReadHistory = decoder.decodeInt32ForKey("skipReadHistory", orElse: 0) != 0 self.crashOnLongQueries = decoder.decodeInt32ForKey("crashOnLongQueries", orElse: 0) != 0 self.chatListPhotos = decoder.decodeInt32ForKey("chatListPhotos", orElse: 0) != 0 - self.playAnimatedEmojiOnce = decoder.decodeInt32ForKey("playAnimatedEmojiOnce", orElse: 1) != 0 } public func encode(_ encoder: PostboxEncoder) { @@ -34,7 +31,6 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry { encoder.encodeInt32(self.skipReadHistory ? 1 : 0, forKey: "skipReadHistory") encoder.encodeInt32(self.crashOnLongQueries ? 1 : 0, forKey: "crashOnLongQueries") encoder.encodeInt32(self.chatListPhotos ? 1 : 0, forKey: "chatListPhotos") - encoder.encodeInt32(self.playAnimatedEmojiOnce ? 1 : 0, forKey: "playAnimatedEmojiOnce") } public func isEqual(to: PreferencesEntry) -> Bool { From 70af4eb679c379080e22c7f52010d7873ab99be0 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 1 Aug 2019 12:48:28 +0300 Subject: [PATCH 21/41] Improved one-time animated emoji playback --- .../TelegramUI/AnimatedStickerNode.swift | 58 +++++++++++++++++-- .../ChatMessageAnimatedStickerItemNode.swift | 25 ++++---- 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift index 51d72672c7..db46c3acbc 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerNode.swift @@ -306,9 +306,6 @@ final class AnimatedStickerNode: ASDisplayNode { private let fetchDisposable = MetaDisposable() private let eventsNode: AnimatedStickerNodeDisplayEvents - var shouldAutoPlay: () -> Bool = { - return true - } var started: () -> Void = {} var reportedStarted = false @@ -410,7 +407,7 @@ final class AnimatedStickerNode: ASDisplayNode { } private func updateIsPlaying() { - let isPlaying = self.visibility && self.isDisplaying && self.shouldAutoPlay() + let isPlaying = self.visibility && self.isDisplaying if self.isPlaying != isPlaying { self.isPlaying = isPlaying if isPlaying { @@ -481,6 +478,59 @@ final class AnimatedStickerNode: ASDisplayNode { self.timer.swap(nil)?.invalidate() } + func seekToStart() { + self.isPlaying = false + + let directData = self.directData + let cachedData = self.cachedData + let queue = self.queue + let timerHolder = self.timer + self.queue.async { [weak self] in + var maybeFrameSource: AnimatedStickerFrameSource? + if let directData = directData { + maybeFrameSource = AnimatedStickerDirectFrameSource(queue: queue, data: directData._0, width: directData._2, height: directData._3) + } else if let cachedData = cachedData { + if #available(iOS 9.0, *) { + maybeFrameSource = AnimatedStickerCachedFrameSource(queue: queue, data: cachedData) + } + } + guard let frameSource = maybeFrameSource else { + return + } + let frameQueue = QueueLocalObject(queue: queue, generate: { + return AnimatedStickerFrameQueue(queue: queue, length: 1, source: frameSource) + }) + timerHolder.swap(nil)?.invalidate() + + let maybeFrame = frameQueue.syncWith { frameQueue in + return frameQueue.take() + } + if let maybeFrame = maybeFrame, let frame = maybeFrame { + Queue.mainQueue().async { + guard let strongSelf = self else { + return + } + strongSelf.renderer?.render(queue: strongSelf.queue, width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type, completion: { + guard let strongSelf = self else { + return + } + if !strongSelf.reportedStarted { + strongSelf.reportedStarted = true + strongSelf.started() + } + }) + if case .once = strongSelf.playbackMode, frame.isLastFrame { + strongSelf.stop() + strongSelf.isPlaying = false + } + } + } + frameQueue.with { frameQueue in + frameQueue.generateFramesIfNeeded() + } + } + } + func playIfNeeded() -> Bool { if !self.isPlaying { self.isPlaying = true diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index 82be722df1..910a2e6738 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -62,17 +62,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } } - self.animationNode.shouldAutoPlay = { [weak self] in - if let strongSelf = self { - if let item = strongSelf.item { - if let _ = strongSelf.emojiFile { - return !item.controllerInteraction.seenOneTimeAnimatedMedia.contains(item.message.id) - } - } - } - return true - } - self.imageNode.displaysAsynchronously = false self.addSubnode(self.imageNode) self.addSubnode(self.animationNode) @@ -174,7 +163,19 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let isPlaying = self.visibilityStatus if self.isPlaying != isPlaying { self.isPlaying = isPlaying - self.animationNode.visibility = isPlaying + + var alreadySeen = false + if isPlaying, let _ = self.emojiFile { + if item.controllerInteraction.seenOneTimeAnimatedMedia.contains(item.message.id) { + alreadySeen = true + } + } + + self.animationNode.visibility = isPlaying && !alreadySeen + if self.didSetUpAnimationNode && alreadySeen { + self.animationNode.seekToStart() + } + if self.isPlaying && !self.didSetUpAnimationNode { self.didSetUpAnimationNode = true From 794d92d12c37817210264062cd08761fda80628e Mon Sep 17 00:00:00 2001 From: Peter <> Date: Thu, 1 Aug 2019 15:51:18 +0300 Subject: [PATCH 22/41] Refactor PresentationSurfaceLevel.root into Display --- submodules/Display/Display/PresentationContext.swift | 2 ++ .../TelegramUI/TelegramUI/PresentationSurfaceLevels.swift | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/submodules/Display/Display/PresentationContext.swift b/submodules/Display/Display/PresentationContext.swift index ef14a61fdf..9a8367a7bc 100644 --- a/submodules/Display/Display/PresentationContext.swift +++ b/submodules/Display/Display/PresentationContext.swift @@ -7,6 +7,8 @@ public struct PresentationSurfaceLevel: RawRepresentable { public init(rawValue: Int32) { self.rawValue = rawValue } + + public static let root = PresentationSurfaceLevel(rawValue: 0) } public enum PresentationContextType { diff --git a/submodules/TelegramUI/TelegramUI/PresentationSurfaceLevels.swift b/submodules/TelegramUI/TelegramUI/PresentationSurfaceLevels.swift index 186255ed3e..4d02e324fb 100644 --- a/submodules/TelegramUI/TelegramUI/PresentationSurfaceLevels.swift +++ b/submodules/TelegramUI/TelegramUI/PresentationSurfaceLevels.swift @@ -2,7 +2,6 @@ import Foundation import Display public extension PresentationSurfaceLevel { - static let root = PresentationSurfaceLevel(rawValue: 0) static let calls = PresentationSurfaceLevel(rawValue: 1) static let overlayMedia = PresentationSurfaceLevel(rawValue: 2) static let notifications = PresentationSurfaceLevel(rawValue: 3) From 9953b26b643ab49d9869020fdc42accd542e8684 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:12:52 +0300 Subject: [PATCH 23/41] Refactor AccountContext --- .../project.pbxproj | 563 ++++++++++++++++++ submodules/AccountContext/Info.plist | 22 + .../AccountContext/Sources/AccountContext.h | 19 + .../Sources/AccountContext.swift | 103 ++++ 4 files changed, 707 insertions(+) create mode 100644 submodules/AccountContext/AccountContext_Xcode.xcodeproj/project.pbxproj create mode 100644 submodules/AccountContext/Info.plist create mode 100644 submodules/AccountContext/Sources/AccountContext.h create mode 100644 submodules/AccountContext/Sources/AccountContext.swift diff --git a/submodules/AccountContext/AccountContext_Xcode.xcodeproj/project.pbxproj b/submodules/AccountContext/AccountContext_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..2e1f470179 --- /dev/null +++ b/submodules/AccountContext/AccountContext_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,563 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D06018E522F36A3900796784 /* DeviceAccess.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018E422F36A3900796784 /* DeviceAccess.framework */; }; + D06018E722F36A3F00796784 /* TelegramPresentationData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018E622F36A3F00796784 /* TelegramPresentationData.framework */; }; + D0D3285422F329A900D07EE2 /* AccountContext.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D3285222F329A900D07EE2 /* AccountContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0D3285F22F335B000D07EE2 /* AccountContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3285E22F335B000D07EE2 /* AccountContext.swift */; }; + D0D3289D22F3461700D07EE2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3289C22F3461700D07EE2 /* Foundation.framework */; }; + D0D3289F22F3462000D07EE2 /* TelegramCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3289E22F3462000D07EE2 /* TelegramCore.framework */; }; + D0D328A122F3462400D07EE2 /* Postbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D328A022F3462400D07EE2 /* Postbox.framework */; }; + D0D328A322F3462800D07EE2 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D328A222F3462800D07EE2 /* SwiftSignalKit.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D06018E422F36A3900796784 /* DeviceAccess.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DeviceAccess.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D06018E622F36A3F00796784 /* TelegramPresentationData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TelegramPresentationData.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3284F22F329A900D07EE2 /* AccountContext.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AccountContext.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3285222F329A900D07EE2 /* AccountContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccountContext.h; sourceTree = ""; }; + D0D3285322F329A900D07EE2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D0D3285E22F335B000D07EE2 /* AccountContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountContext.swift; sourceTree = ""; }; + D0D3289C22F3461700D07EE2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D0D3289E22F3462000D07EE2 /* TelegramCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TelegramCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D328A022F3462400D07EE2 /* Postbox.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Postbox.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D328A222F3462800D07EE2 /* SwiftSignalKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwiftSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D0D3284C22F329A900D07EE2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D06018E722F36A3F00796784 /* TelegramPresentationData.framework in Frameworks */, + D06018E522F36A3900796784 /* DeviceAccess.framework in Frameworks */, + D0D328A322F3462800D07EE2 /* SwiftSignalKit.framework in Frameworks */, + D0D328A122F3462400D07EE2 /* Postbox.framework in Frameworks */, + D0D3289F22F3462000D07EE2 /* TelegramCore.framework in Frameworks */, + D0D3289D22F3461700D07EE2 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D0D3284522F329A900D07EE2 = { + isa = PBXGroup; + children = ( + D0D3285322F329A900D07EE2 /* Info.plist */, + D0D3285122F329A900D07EE2 /* Sources */, + D0D3285022F329A900D07EE2 /* Products */, + D0D3289B22F3461700D07EE2 /* Frameworks */, + ); + sourceTree = ""; + }; + D0D3285022F329A900D07EE2 /* Products */ = { + isa = PBXGroup; + children = ( + D0D3284F22F329A900D07EE2 /* AccountContext.framework */, + ); + name = Products; + sourceTree = ""; + }; + D0D3285122F329A900D07EE2 /* Sources */ = { + isa = PBXGroup; + children = ( + D0D3285222F329A900D07EE2 /* AccountContext.h */, + D0D3285E22F335B000D07EE2 /* AccountContext.swift */, + ); + path = Sources; + sourceTree = ""; + }; + D0D3289B22F3461700D07EE2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D06018E622F36A3F00796784 /* TelegramPresentationData.framework */, + D06018E422F36A3900796784 /* DeviceAccess.framework */, + D0D328A222F3462800D07EE2 /* SwiftSignalKit.framework */, + D0D328A022F3462400D07EE2 /* Postbox.framework */, + D0D3289E22F3462000D07EE2 /* TelegramCore.framework */, + D0D3289C22F3461700D07EE2 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D0D3284A22F329A900D07EE2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D0D3285422F329A900D07EE2 /* AccountContext.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D0D3284E22F329A900D07EE2 /* AccountContext */ = { + isa = PBXNativeTarget; + buildConfigurationList = D0D3285722F329A900D07EE2 /* Build configuration list for PBXNativeTarget "AccountContext" */; + buildPhases = ( + D0D3284A22F329A900D07EE2 /* Headers */, + D0D3284B22F329A900D07EE2 /* Sources */, + D0D3284C22F329A900D07EE2 /* Frameworks */, + D0D3284D22F329A900D07EE2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AccountContext; + productName = AccountContext; + productReference = D0D3284F22F329A900D07EE2 /* AccountContext.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D0D3284622F329A900D07EE2 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D0D3284E22F329A900D07EE2 = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1010; + }; + }; + }; + buildConfigurationList = D0D3284922F329A900D07EE2 /* Build configuration list for PBXProject "AccountContext_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D0D3284522F329A900D07EE2; + productRefGroup = D0D3285022F329A900D07EE2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D0D3284E22F329A900D07EE2 /* AccountContext */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D0D3284D22F329A900D07EE2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D0D3284B22F329A900D07EE2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D0D3285F22F335B000D07EE2 /* AccountContext.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D0D3285522F329A900D07EE2 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D0D3285622F329A900D07EE2 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D0D3285822F329A900D07EE2 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.AccountContext; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D0D3285922F329A900D07EE2 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.AccountContext; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D0D3285A22F32F5900D07EE2 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D0D3285B22F32F5900D07EE2 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.AccountContext; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D0D3285C22F32F6B00D07EE2 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D0D3285D22F32F6B00D07EE2 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.AccountContext; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D0D3284922F329A900D07EE2 /* Build configuration list for PBXProject "AccountContext_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0D3285522F329A900D07EE2 /* DebugAppStoreLLC */, + D0D3285A22F32F5900D07EE2 /* DebugHockeyapp */, + D0D3285622F329A900D07EE2 /* ReleaseAppStoreLLC */, + D0D3285C22F32F6B00D07EE2 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D0D3285722F329A900D07EE2 /* Build configuration list for PBXNativeTarget "AccountContext" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0D3285822F329A900D07EE2 /* DebugAppStoreLLC */, + D0D3285B22F32F5900D07EE2 /* DebugHockeyapp */, + D0D3285922F329A900D07EE2 /* ReleaseAppStoreLLC */, + D0D3285D22F32F6B00D07EE2 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D0D3284622F329A900D07EE2 /* Project object */; +} diff --git a/submodules/AccountContext/Info.plist b/submodules/AccountContext/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/AccountContext/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/AccountContext/Sources/AccountContext.h b/submodules/AccountContext/Sources/AccountContext.h new file mode 100644 index 0000000000..5464cb5198 --- /dev/null +++ b/submodules/AccountContext/Sources/AccountContext.h @@ -0,0 +1,19 @@ +// +// AccountContext.h +// AccountContext +// +// Created by Peter on 8/1/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for AccountContext. +FOUNDATION_EXPORT double AccountContextVersionNumber; + +//! Project version string for AccountContext. +FOUNDATION_EXPORT const unsigned char AccountContextVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift new file mode 100644 index 0000000000..bbb43bd555 --- /dev/null +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -0,0 +1,103 @@ +import Foundation +import Postbox +import TelegramCore +import TelegramPresentationData +import TelegramUIPreferences +import SwiftSignalKit +import Display +import DeviceAccess + +public final class TelegramApplicationOpenUrlCompletion { + public let completion: (Bool) -> Void + + public init(completion: @escaping (Bool) -> Void) { + self.completion = completion + } +} + +public final class TelegramApplicationBindings { + public let isMainApp: Bool + public let containerPath: String + public let appSpecificScheme: String + public let openUrl: (String) -> Void + public let openUniversalUrl: (String, TelegramApplicationOpenUrlCompletion) -> Void + public let canOpenUrl: (String) -> Bool + public let getTopWindow: () -> UIWindow? + public let displayNotification: (String) -> Void + public let applicationInForeground: Signal + public let applicationIsActive: Signal + public let clearMessageNotifications: ([MessageId]) -> Void + public let pushIdleTimerExtension: () -> Disposable + public let openSettings: () -> Void + public let openAppStorePage: () -> Void + public let registerForNotifications: (@escaping (Bool) -> Void) -> Void + public let requestSiriAuthorization: (@escaping (Bool) -> Void) -> Void + public let siriAuthorization: () -> AccessType + public let getWindowHost: () -> WindowHost? + public let presentNativeController: (UIViewController) -> Void + public let dismissNativeController: () -> Void + public let getAvailableAlternateIcons: () -> [PresentationAppIcon] + public let getAlternateIconName: () -> String? + public let requestSetAlternateIconName: (String?, @escaping (Bool) -> Void) -> Void + + public init(isMainApp: Bool, containerPath: String, appSpecificScheme: String, openUrl: @escaping (String) -> Void, openUniversalUrl: @escaping (String, TelegramApplicationOpenUrlCompletion) -> Void, canOpenUrl: @escaping (String) -> Bool, getTopWindow: @escaping () -> UIWindow?, displayNotification: @escaping (String) -> Void, applicationInForeground: Signal, applicationIsActive: Signal, clearMessageNotifications: @escaping ([MessageId]) -> Void, pushIdleTimerExtension: @escaping () -> Disposable, openSettings: @escaping () -> Void, openAppStorePage: @escaping () -> Void, registerForNotifications: @escaping (@escaping (Bool) -> Void) -> Void, requestSiriAuthorization: @escaping (@escaping (Bool) -> Void) -> Void, siriAuthorization: @escaping () -> AccessType, getWindowHost: @escaping () -> WindowHost?, presentNativeController: @escaping (UIViewController) -> Void, dismissNativeController: @escaping () -> Void, getAvailableAlternateIcons: @escaping () -> [PresentationAppIcon], getAlternateIconName: @escaping () -> String?, requestSetAlternateIconName: @escaping (String?, @escaping (Bool) -> Void) -> Void) { + self.isMainApp = isMainApp + self.containerPath = containerPath + self.appSpecificScheme = appSpecificScheme + self.openUrl = openUrl + self.openUniversalUrl = openUniversalUrl + self.canOpenUrl = canOpenUrl + self.getTopWindow = getTopWindow + self.displayNotification = displayNotification + self.applicationInForeground = applicationInForeground + self.applicationIsActive = applicationIsActive + self.clearMessageNotifications = clearMessageNotifications + self.pushIdleTimerExtension = pushIdleTimerExtension + self.openSettings = openSettings + self.openAppStorePage = openAppStorePage + self.registerForNotifications = registerForNotifications + self.requestSiriAuthorization = requestSiriAuthorization + self.siriAuthorization = siriAuthorization + self.presentNativeController = presentNativeController + self.dismissNativeController = dismissNativeController + self.getWindowHost = getWindowHost + self.getAvailableAlternateIcons = getAvailableAlternateIcons + self.getAlternateIconName = getAlternateIconName + self.requestSetAlternateIconName = requestSetAlternateIconName + } +} + +public enum TextLinkItemActionType { + case tap + case longTap +} + +public enum TextLinkItem { + case url(String) + case mention(String) + case hashtag(String?, String) +} + +public protocol SharedAccountContext: class { + var accountManager: AccountManager { get } + var currentPresentationData: Atomic { get } + var presentationData: Signal { get } + var applicationBindings: TelegramApplicationBindings { get } + + func handleTextLinkAction(context: AccountContext, peerId: PeerId?, navigateDisposable: MetaDisposable, controller: ViewController, action: TextLinkItemActionType, itemLink: TextLinkItem) +} + +public protocol AccountContext: class { + var genericSharedContext: SharedAccountContext { get } + var account: Account { get } +} + +public final class TempAccountContext: AccountContext { + public let genericSharedContext: SharedAccountContext + public let account: Account + + init(genericSharedContext: SharedAccountContext, account: Account) { + self.genericSharedContext = genericSharedContext + self.account = account + } +} From fa720e03de224a1c88a2d3c0de959dd816fdd6ee Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:13:32 +0300 Subject: [PATCH 24/41] Refactor ActivityIndicator --- .../project.pbxproj | 555 ++++++++++++++++++ submodules/ActivityIndicator/Info.plist | 22 + .../Sources/ActivityIndicator.h | 19 + .../Sources}/ActivityIndicator.swift | 126 ++-- 4 files changed, 659 insertions(+), 63 deletions(-) create mode 100644 submodules/ActivityIndicator/ActivityIndicator_Xcode.xcodeproj/project.pbxproj create mode 100644 submodules/ActivityIndicator/Info.plist create mode 100644 submodules/ActivityIndicator/Sources/ActivityIndicator.h rename submodules/{TelegramUI/TelegramUI => ActivityIndicator/Sources}/ActivityIndicator.swift (56%) diff --git a/submodules/ActivityIndicator/ActivityIndicator_Xcode.xcodeproj/project.pbxproj b/submodules/ActivityIndicator/ActivityIndicator_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..54d0672812 --- /dev/null +++ b/submodules/ActivityIndicator/ActivityIndicator_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,555 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D060183122F35C3D00796784 /* ActivityIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = D060182F22F35C3D00796784 /* ActivityIndicator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D060183C22F35C8100796784 /* ActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060183B22F35C8100796784 /* ActivityIndicator.swift */; }; + D0A0B53122F3701A00628AF3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0A0B53022F3701A00628AF3 /* UIKit.framework */; }; + D0A0B53322F3701F00628AF3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0A0B53222F3701E00628AF3 /* Foundation.framework */; }; + D0A0B53522F3702100628AF3 /* AsyncDisplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0A0B53422F3702100628AF3 /* AsyncDisplayKit.framework */; }; + D0A0B53722F3702E00628AF3 /* TelegramPresentationData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0A0B53622F3702E00628AF3 /* TelegramPresentationData.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D060182C22F35C3D00796784 /* ActivityIndicator.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ActivityIndicator.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060182F22F35C3D00796784 /* ActivityIndicator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityIndicator.h; sourceTree = ""; }; + D060183022F35C3D00796784 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D060183B22F35C8100796784 /* ActivityIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityIndicator.swift; sourceTree = ""; }; + D0A0B53022F3701A00628AF3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D0A0B53222F3701E00628AF3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D0A0B53422F3702100628AF3 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0A0B53622F3702E00628AF3 /* TelegramPresentationData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TelegramPresentationData.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D060182922F35C3D00796784 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D0A0B53722F3702E00628AF3 /* TelegramPresentationData.framework in Frameworks */, + D0A0B53522F3702100628AF3 /* AsyncDisplayKit.framework in Frameworks */, + D0A0B53322F3701F00628AF3 /* Foundation.framework in Frameworks */, + D0A0B53122F3701A00628AF3 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D060182222F35C3D00796784 = { + isa = PBXGroup; + children = ( + D060183022F35C3D00796784 /* Info.plist */, + D060182E22F35C3D00796784 /* Sources */, + D060182D22F35C3D00796784 /* Products */, + D0A0B52F22F3701800628AF3 /* Frameworks */, + ); + sourceTree = ""; + }; + D060182D22F35C3D00796784 /* Products */ = { + isa = PBXGroup; + children = ( + D060182C22F35C3D00796784 /* ActivityIndicator.framework */, + ); + name = Products; + sourceTree = ""; + }; + D060182E22F35C3D00796784 /* Sources */ = { + isa = PBXGroup; + children = ( + D060183B22F35C8100796784 /* ActivityIndicator.swift */, + D060182F22F35C3D00796784 /* ActivityIndicator.h */, + ); + path = Sources; + sourceTree = ""; + }; + D0A0B52F22F3701800628AF3 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D0A0B53622F3702E00628AF3 /* TelegramPresentationData.framework */, + D0A0B53422F3702100628AF3 /* AsyncDisplayKit.framework */, + D0A0B53222F3701E00628AF3 /* Foundation.framework */, + D0A0B53022F3701A00628AF3 /* UIKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D060182722F35C3D00796784 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D060183122F35C3D00796784 /* ActivityIndicator.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D060182B22F35C3D00796784 /* ActivityIndicator */ = { + isa = PBXNativeTarget; + buildConfigurationList = D060183422F35C3D00796784 /* Build configuration list for PBXNativeTarget "ActivityIndicator" */; + buildPhases = ( + D060182722F35C3D00796784 /* Headers */, + D060182822F35C3D00796784 /* Sources */, + D060182922F35C3D00796784 /* Frameworks */, + D060182A22F35C3D00796784 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ActivityIndicator; + productName = ActivityIndicator; + productReference = D060182C22F35C3D00796784 /* ActivityIndicator.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D060182322F35C3D00796784 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D060182B22F35C3D00796784 = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1010; + }; + }; + }; + buildConfigurationList = D060182622F35C3D00796784 /* Build configuration list for PBXProject "ActivityIndicator_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D060182222F35C3D00796784; + productRefGroup = D060182D22F35C3D00796784 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D060182B22F35C3D00796784 /* ActivityIndicator */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D060182A22F35C3D00796784 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D060182822F35C3D00796784 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D060183C22F35C8100796784 /* ActivityIndicator.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D060183222F35C3D00796784 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D060183322F35C3D00796784 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D060183522F35C3D00796784 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ActivityIndicator; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D060183622F35C3D00796784 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ActivityIndicator; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D060183722F35C5400796784 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D060183822F35C5400796784 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ActivityIndicator; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D060183922F35C5F00796784 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D060183A22F35C5F00796784 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ActivityIndicator; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D060182622F35C3D00796784 /* Build configuration list for PBXProject "ActivityIndicator_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D060183222F35C3D00796784 /* DebugAppStoreLLC */, + D060183722F35C5400796784 /* DebugHockeyapp */, + D060183322F35C3D00796784 /* ReleaseAppStoreLLC */, + D060183922F35C5F00796784 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D060183422F35C3D00796784 /* Build configuration list for PBXNativeTarget "ActivityIndicator" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D060183522F35C3D00796784 /* DebugAppStoreLLC */, + D060183822F35C5400796784 /* DebugHockeyapp */, + D060183622F35C3D00796784 /* ReleaseAppStoreLLC */, + D060183A22F35C5F00796784 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D060182322F35C3D00796784 /* Project object */; +} diff --git a/submodules/ActivityIndicator/Info.plist b/submodules/ActivityIndicator/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/ActivityIndicator/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/ActivityIndicator/Sources/ActivityIndicator.h b/submodules/ActivityIndicator/Sources/ActivityIndicator.h new file mode 100644 index 0000000000..d1f730c19a --- /dev/null +++ b/submodules/ActivityIndicator/Sources/ActivityIndicator.h @@ -0,0 +1,19 @@ +// +// ActivityIndicator.h +// ActivityIndicator +// +// Created by Peter on 8/1/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for ActivityIndicator. +FOUNDATION_EXPORT double ActivityIndicatorVersionNumber; + +//! Project version string for ActivityIndicator. +FOUNDATION_EXPORT const unsigned char ActivityIndicatorVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/TelegramUI/TelegramUI/ActivityIndicator.swift b/submodules/ActivityIndicator/Sources/ActivityIndicator.swift similarity index 56% rename from submodules/TelegramUI/TelegramUI/ActivityIndicator.swift rename to submodules/ActivityIndicator/Sources/ActivityIndicator.swift index 8b5c75e40a..477142bfe5 100644 --- a/submodules/TelegramUI/TelegramUI/ActivityIndicator.swift +++ b/submodules/ActivityIndicator/Sources/ActivityIndicator.swift @@ -15,55 +15,55 @@ private func convertIndicatorColor(_ color: UIColor) -> UIColor { } } -enum ActivityIndicatorType: Equatable { +public enum ActivityIndicatorType: Equatable { case navigationAccent(PresentationTheme) case custom(UIColor, CGFloat, CGFloat, Bool) - static func ==(lhs: ActivityIndicatorType, rhs: ActivityIndicatorType) -> Bool { + public static func ==(lhs: ActivityIndicatorType, rhs: ActivityIndicatorType) -> Bool { switch lhs { - case let .navigationAccent(lhsTheme): - if case let .navigationAccent(rhsTheme) = rhs, lhsTheme === rhsTheme { - return true - } else { - return false - } - case let .custom(lhsColor, lhsDiameter, lhsWidth, lhsForceCustom): - if case let .custom(rhsColor, rhsDiameter, rhsWidth, rhsForceCustom) = rhs, lhsColor.isEqual(rhsColor), lhsDiameter == rhsDiameter, lhsWidth == rhsWidth, lhsForceCustom == rhsForceCustom { - return true - } else { - return false - } + case let .navigationAccent(lhsTheme): + if case let .navigationAccent(rhsTheme) = rhs, lhsTheme === rhsTheme { + return true + } else { + return false + } + case let .custom(lhsColor, lhsDiameter, lhsWidth, lhsForceCustom): + if case let .custom(rhsColor, rhsDiameter, rhsWidth, rhsForceCustom) = rhs, lhsColor.isEqual(rhsColor), lhsDiameter == rhsDiameter, lhsWidth == rhsWidth, lhsForceCustom == rhsForceCustom { + return true + } else { + return false + } } } } -enum ActivityIndicatorSpeed { +public enum ActivityIndicatorSpeed { case regular case slow } -final class ActivityIndicator: ASDisplayNode { - var type: ActivityIndicatorType { +public final class ActivityIndicator: ASDisplayNode { + public var type: ActivityIndicatorType { didSet { switch self.type { - case let .navigationAccent(theme): - self.indicatorNode.image = PresentationResourcesRootController.navigationIndefiniteActivityImage(theme) - case let .custom(color, diameter, lineWidth, _): - self.indicatorNode.image = generateIndefiniteActivityIndicatorImage(color: color, diameter: diameter, lineWidth: lineWidth) + case let .navigationAccent(theme): + self.indicatorNode.image = PresentationResourcesRootController.navigationIndefiniteActivityImage(theme) + case let .custom(color, diameter, lineWidth, _): + self.indicatorNode.image = generateIndefiniteActivityIndicatorImage(color: color, diameter: diameter, lineWidth: lineWidth) } switch self.type { - case let .navigationAccent(theme): - self.indicatorView?.color = theme.rootController.navigationBar.controlColor - case let .custom(color, diameter, lineWidth, _): - self.indicatorView?.color = convertIndicatorColor(color) + case let .navigationAccent(theme): + self.indicatorView?.color = theme.rootController.navigationBar.controlColor + case let .custom(color, _, _, _): + self.indicatorView?.color = convertIndicatorColor(color) } } } private var currentInHierarchy = false - override var isHidden: Bool { + override public var isHidden: Bool { didSet { self.updateAnimation() } @@ -74,7 +74,7 @@ final class ActivityIndicator: ASDisplayNode { private let indicatorNode: ASImageNode private var indicatorView: UIActivityIndicatorView? - init(type: ActivityIndicatorType, speed: ActivityIndicatorSpeed = .regular) { + public init(type: ActivityIndicatorType, speed: ActivityIndicatorSpeed = .regular) { self.type = type self.speed = speed @@ -86,28 +86,28 @@ final class ActivityIndicator: ASDisplayNode { super.init() switch type { - case let .navigationAccent(theme): - self.indicatorNode.image = PresentationResourcesRootController.navigationIndefiniteActivityImage(theme) - case let .custom(color, diameter, lineWidth, forceCustom): - self.indicatorNode.image = generateIndefiniteActivityIndicatorImage(color: color, diameter: diameter, lineWidth: lineWidth) - if forceCustom { - self.addSubnode(self.indicatorNode) - } + case let .navigationAccent(theme): + self.indicatorNode.image = PresentationResourcesRootController.navigationIndefiniteActivityImage(theme) + case let .custom(color, diameter, lineWidth, forceCustom): + self.indicatorNode.image = generateIndefiniteActivityIndicatorImage(color: color, diameter: diameter, lineWidth: lineWidth) + if forceCustom { + self.addSubnode(self.indicatorNode) + } } } - override func didLoad() { + override public func didLoad() { super.didLoad() - let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge) + let indicatorView = UIActivityIndicatorView(style: .whiteLarge) switch self.type { - case let .navigationAccent(theme): - indicatorView.color = theme.rootController.navigationBar.controlColor - case let .custom(color, _, _, forceCustom): - indicatorView.color = convertIndicatorColor(color) - if !forceCustom { - self.view.addSubview(indicatorView) - } + case let .navigationAccent(theme): + indicatorView.color = theme.rootController.navigationBar.controlColor + case let .custom(color, _, _, forceCustom): + indicatorView.color = convertIndicatorColor(color) + if !forceCustom { + self.view.addSubview(indicatorView) + } } self.indicatorView = indicatorView let size = self.bounds.size @@ -122,17 +122,17 @@ final class ActivityIndicator: ASDisplayNode { if self.isAnimating { self.indicatorView?.startAnimating() let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) switch self.speed { - case .regular: - basicAnimation.duration = 0.5 - case .slow: - basicAnimation.duration = 0.7 + case .regular: + basicAnimation.duration = 0.5 + case .slow: + basicAnimation.duration = 0.7 } basicAnimation.fromValue = NSNumber(value: Float(0.0)) basicAnimation.toValue = NSNumber(value: Float.pi * 2.0) basicAnimation.repeatCount = Float.infinity - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) basicAnimation.beginTime = 1.0 self.indicatorNode.layer.add(basicAnimation, forKey: "progressRotation") @@ -148,30 +148,30 @@ final class ActivityIndicator: ASDisplayNode { self.isAnimating = !self.isHidden && self.currentInHierarchy } - override func willEnterHierarchy() { + override public func willEnterHierarchy() { super.willEnterHierarchy() self.currentInHierarchy = true self.updateAnimation() } - override func didExitHierarchy() { + override public func didExitHierarchy() { super.didExitHierarchy() self.currentInHierarchy = false self.updateAnimation() } - override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { + override public func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { switch self.type { - case .navigationAccent: - return CGSize(width: 22.0, height: 22.0) - case let .custom(_, diameter, _, _): - return CGSize(width: diameter, height: diameter) + case .navigationAccent: + return CGSize(width: 22.0, height: 22.0) + case let .custom(_, diameter, _, _): + return CGSize(width: diameter, height: diameter) } } - override func layout() { + override public func layout() { super.layout() let size = self.bounds.size @@ -183,12 +183,12 @@ final class ActivityIndicator: ASDisplayNode { let indicatorSize: CGSize let shouldScale: Bool switch self.type { - case .navigationAccent: - indicatorSize = CGSize(width: 22.0, height: 22.0) - shouldScale = false - case let .custom(_, diameter, _, forceDefault): - indicatorSize = CGSize(width: diameter, height: diameter) - shouldScale = !forceDefault + case .navigationAccent: + indicatorSize = CGSize(width: 22.0, height: 22.0) + shouldScale = false + case let .custom(_, diameter, _, forceDefault): + indicatorSize = CGSize(width: diameter, height: diameter) + shouldScale = !forceDefault } self.indicatorNode.frame = CGRect(origin: CGPoint(x: floor((size.width - indicatorSize.width) / 2.0), y: floor((size.height - indicatorSize.height) / 2.0)), size: indicatorSize) if shouldScale, let indicatorView = self.indicatorView { From 1d1d83f69fd591a73e90403fea17bc8003b3f3ad Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:14:01 +0300 Subject: [PATCH 25/41] Refactor AnimationUI --- .../project.pbxproj | 559 ++++++++++++++++++ submodules/AnimationUI/Info.plist | 22 + .../Sources}/AnimationNode.swift | 24 +- submodules/AnimationUI/Sources/AnimationUI.h | 19 + .../AnimationUI/Sources/FrameworkBundle.swift | 7 + 5 files changed, 619 insertions(+), 12 deletions(-) create mode 100644 submodules/AnimationUI/AnimationUI_Xcode.xcodeproj/project.pbxproj create mode 100644 submodules/AnimationUI/Info.plist rename submodules/{TelegramUI/TelegramUI => AnimationUI/Sources}/AnimationNode.swift (82%) create mode 100644 submodules/AnimationUI/Sources/AnimationUI.h create mode 100644 submodules/AnimationUI/Sources/FrameworkBundle.swift diff --git a/submodules/AnimationUI/AnimationUI_Xcode.xcodeproj/project.pbxproj b/submodules/AnimationUI/AnimationUI_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..a332145896 --- /dev/null +++ b/submodules/AnimationUI/AnimationUI_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,559 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D060187122F35FCD00796784 /* AnimationUI.h in Headers */ = {isa = PBXBuildFile; fileRef = D060186F22F35FCD00796784 /* AnimationUI.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D06018A422F361E800796784 /* AnimationNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06018A322F361E800796784 /* AnimationNode.swift */; }; + D06018A722F361F400796784 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018A622F361F400796784 /* Foundation.framework */; }; + D06018A922F361F900796784 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018A822F361F800796784 /* UIKit.framework */; }; + D06018AB22F361FC00796784 /* AsyncDisplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018AA22F361FC00796784 /* AsyncDisplayKit.framework */; }; + D06018AD22F361FF00796784 /* Lottie.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018AC22F361FF00796784 /* Lottie.framework */; }; + D06018AF22F3641F00796784 /* FrameworkBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06018AE22F3641F00796784 /* FrameworkBundle.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D060186C22F35FCD00796784 /* AnimationUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AnimationUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060186F22F35FCD00796784 /* AnimationUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnimationUI.h; sourceTree = ""; }; + D060187022F35FCD00796784 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D06018A322F361E800796784 /* AnimationNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationNode.swift; sourceTree = ""; }; + D06018A622F361F400796784 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D06018A822F361F800796784 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D06018AA22F361FC00796784 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D06018AC22F361FF00796784 /* Lottie.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Lottie.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D06018AE22F3641F00796784 /* FrameworkBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FrameworkBundle.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D060186922F35FCD00796784 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D06018AD22F361FF00796784 /* Lottie.framework in Frameworks */, + D06018AB22F361FC00796784 /* AsyncDisplayKit.framework in Frameworks */, + D06018A922F361F900796784 /* UIKit.framework in Frameworks */, + D06018A722F361F400796784 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D060186222F35FCD00796784 = { + isa = PBXGroup; + children = ( + D060187022F35FCD00796784 /* Info.plist */, + D060186E22F35FCD00796784 /* Sources */, + D060186D22F35FCD00796784 /* Products */, + D06018A522F361F400796784 /* Frameworks */, + ); + sourceTree = ""; + }; + D060186D22F35FCD00796784 /* Products */ = { + isa = PBXGroup; + children = ( + D060186C22F35FCD00796784 /* AnimationUI.framework */, + ); + name = Products; + sourceTree = ""; + }; + D060186E22F35FCD00796784 /* Sources */ = { + isa = PBXGroup; + children = ( + D06018A322F361E800796784 /* AnimationNode.swift */, + D060186F22F35FCD00796784 /* AnimationUI.h */, + D06018AE22F3641F00796784 /* FrameworkBundle.swift */, + ); + path = Sources; + sourceTree = ""; + }; + D06018A522F361F400796784 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D06018AC22F361FF00796784 /* Lottie.framework */, + D06018AA22F361FC00796784 /* AsyncDisplayKit.framework */, + D06018A822F361F800796784 /* UIKit.framework */, + D06018A622F361F400796784 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D060186722F35FCD00796784 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D060187122F35FCD00796784 /* AnimationUI.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D060186B22F35FCD00796784 /* AnimationUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = D060187422F35FCD00796784 /* Build configuration list for PBXNativeTarget "AnimationUI" */; + buildPhases = ( + D060186722F35FCD00796784 /* Headers */, + D060186822F35FCD00796784 /* Sources */, + D060186922F35FCD00796784 /* Frameworks */, + D060186A22F35FCD00796784 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AnimationUI; + productName = AnimationUI; + productReference = D060186C22F35FCD00796784 /* AnimationUI.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D060186322F35FCD00796784 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D060186B22F35FCD00796784 = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1010; + }; + }; + }; + buildConfigurationList = D060186622F35FCD00796784 /* Build configuration list for PBXProject "AnimationUI_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D060186222F35FCD00796784; + productRefGroup = D060186D22F35FCD00796784 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D060186B22F35FCD00796784 /* AnimationUI */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D060186A22F35FCD00796784 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D060186822F35FCD00796784 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D06018AF22F3641F00796784 /* FrameworkBundle.swift in Sources */, + D06018A422F361E800796784 /* AnimationNode.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D060187222F35FCD00796784 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D060187322F35FCD00796784 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D060187522F35FCD00796784 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.AnimationUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D060187622F35FCD00796784 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.AnimationUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D060187722F35FE900796784 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D060187822F35FE900796784 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.AnimationUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D060187922F35FF700796784 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D060187A22F35FF700796784 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.AnimationUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D060186622F35FCD00796784 /* Build configuration list for PBXProject "AnimationUI_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D060187222F35FCD00796784 /* DebugAppStoreLLC */, + D060187722F35FE900796784 /* DebugHockeyapp */, + D060187322F35FCD00796784 /* ReleaseAppStoreLLC */, + D060187922F35FF700796784 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D060187422F35FCD00796784 /* Build configuration list for PBXNativeTarget "AnimationUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D060187522F35FCD00796784 /* DebugAppStoreLLC */, + D060187822F35FE900796784 /* DebugHockeyapp */, + D060187622F35FCD00796784 /* ReleaseAppStoreLLC */, + D060187A22F35FF700796784 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D060186322F35FCD00796784 /* Project object */; +} diff --git a/submodules/AnimationUI/Info.plist b/submodules/AnimationUI/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/AnimationUI/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/TelegramUI/TelegramUI/AnimationNode.swift b/submodules/AnimationUI/Sources/AnimationNode.swift similarity index 82% rename from submodules/TelegramUI/TelegramUI/AnimationNode.swift rename to submodules/AnimationUI/Sources/AnimationNode.swift index aa87e1e9a9..2ef1462a22 100644 --- a/submodules/TelegramUI/TelegramUI/AnimationNode.swift +++ b/submodules/AnimationUI/Sources/AnimationNode.swift @@ -3,9 +3,9 @@ import UIKit import AsyncDisplayKit import Lottie -final class AnimationNode : ASDisplayNode { +public final class AnimationNode : ASDisplayNode { private let scale: CGFloat - var speed: CGFloat = 1.0 { + public var speed: CGFloat = 1.0 { didSet { if let animationView = animationView() { animationView.animationSpeed = speed @@ -15,10 +15,10 @@ final class AnimationNode : ASDisplayNode { private var colorCallbacks: [LOTColorValueCallback] = [] - var played = false - var completion: (() -> Void)? + public var played = false + public var completion: (() -> Void)? - init(animation: String? = nil, colors: [String: UIColor]? = nil, scale: CGFloat = 1.0) { + public init(animation: String? = nil, colors: [String: UIColor]? = nil, scale: CGFloat = 1.0) { self.scale = scale super.init() @@ -47,21 +47,21 @@ final class AnimationNode : ASDisplayNode { }) } - func setAnimation(name: String) { + public func setAnimation(name: String) { if let url = frameworkBundle.url(forResource: name, withExtension: "json"), let composition = LOTComposition(filePath: url.path) { self.animationView()?.sceneModel = composition } } - func setAnimation(json: [AnyHashable: Any]) { + public func setAnimation(json: [AnyHashable: Any]) { self.animationView()?.setAnimation(json: json) } - func animationView() -> LOTAnimationView? { + public func animationView() -> LOTAnimationView? { return self.view as? LOTAnimationView } - func play() { + public func play() { if let animationView = animationView(), !animationView.isAnimationPlaying, !self.played { self.played = true animationView.play { [weak self] _ in @@ -70,21 +70,21 @@ final class AnimationNode : ASDisplayNode { } } - func loop() { + public func loop() { if let animationView = animationView() { animationView.loopAnimation = true animationView.play() } } - func reset() { + public func reset() { if self.played, let animationView = animationView() { self.played = false animationView.stop() } } - func preferredSize() -> CGSize? { + public func preferredSize() -> CGSize? { if let animationView = animationView(), let sceneModel = animationView.sceneModel { return CGSize(width: sceneModel.compBounds.width * self.scale, height: sceneModel.compBounds.height * self.scale) } else { diff --git a/submodules/AnimationUI/Sources/AnimationUI.h b/submodules/AnimationUI/Sources/AnimationUI.h new file mode 100644 index 0000000000..bcb24521bd --- /dev/null +++ b/submodules/AnimationUI/Sources/AnimationUI.h @@ -0,0 +1,19 @@ +// +// AnimationUI.h +// AnimationUI +// +// Created by Peter on 8/1/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for AnimationUI. +FOUNDATION_EXPORT double AnimationUIVersionNumber; + +//! Project version string for AnimationUI. +FOUNDATION_EXPORT const unsigned char AnimationUIVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/AnimationUI/Sources/FrameworkBundle.swift b/submodules/AnimationUI/Sources/FrameworkBundle.swift new file mode 100644 index 0000000000..0ff8e5a0cc --- /dev/null +++ b/submodules/AnimationUI/Sources/FrameworkBundle.swift @@ -0,0 +1,7 @@ +import Foundation +import UIKit + +private class FrameworkBundleClass: NSObject { +} + +let frameworkBundle: Bundle = Bundle(for: FrameworkBundleClass.self) From d2482a2c8c011a92ab0a62b75110b49c3baba791 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:14:36 +0300 Subject: [PATCH 26/41] Refactor CheckNode --- .../CheckNode_Xcode.xcodeproj/project.pbxproj | 555 ++++++++++++++++++ submodules/CheckNode/Info.plist | 22 + submodules/CheckNode/Sources/CheckNode.h | 19 + .../Sources}/CheckNode.swift | 32 +- 4 files changed, 612 insertions(+), 16 deletions(-) create mode 100644 submodules/CheckNode/CheckNode_Xcode.xcodeproj/project.pbxproj create mode 100644 submodules/CheckNode/Info.plist create mode 100644 submodules/CheckNode/Sources/CheckNode.h rename submodules/{TelegramUI/TelegramUI => CheckNode/Sources}/CheckNode.swift (71%) diff --git a/submodules/CheckNode/CheckNode_Xcode.xcodeproj/project.pbxproj b/submodules/CheckNode/CheckNode_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..6bd52fb03f --- /dev/null +++ b/submodules/CheckNode/CheckNode_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,555 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D06018CD22F3665900796784 /* CheckNode.h in Headers */ = {isa = PBXBuildFile; fileRef = D06018CB22F3665900796784 /* CheckNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D06018D822F366B000796784 /* CheckNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06018D722F366B000796784 /* CheckNode.swift */; }; + D06018DB22F366BB00796784 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018DA22F366BB00796784 /* UIKit.framework */; }; + D06018DD22F366BE00796784 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018DC22F366BE00796784 /* Foundation.framework */; }; + D06018DF22F366C200796784 /* AsyncDisplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018DE22F366C200796784 /* AsyncDisplayKit.framework */; }; + D06018E122F366C500796784 /* LegacyComponents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018E022F366C500796784 /* LegacyComponents.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D06018C822F3665900796784 /* CheckNode.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CheckNode.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D06018CB22F3665900796784 /* CheckNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CheckNode.h; sourceTree = ""; }; + D06018CC22F3665900796784 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D06018D722F366B000796784 /* CheckNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckNode.swift; sourceTree = ""; }; + D06018DA22F366BB00796784 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D06018DC22F366BE00796784 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D06018DE22F366C200796784 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D06018E022F366C500796784 /* LegacyComponents.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = LegacyComponents.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D06018C522F3665900796784 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D06018E122F366C500796784 /* LegacyComponents.framework in Frameworks */, + D06018DF22F366C200796784 /* AsyncDisplayKit.framework in Frameworks */, + D06018DD22F366BE00796784 /* Foundation.framework in Frameworks */, + D06018DB22F366BB00796784 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D06018BE22F3665900796784 = { + isa = PBXGroup; + children = ( + D06018CC22F3665900796784 /* Info.plist */, + D06018CA22F3665900796784 /* Sources */, + D06018C922F3665900796784 /* Products */, + D06018D922F366BA00796784 /* Frameworks */, + ); + sourceTree = ""; + }; + D06018C922F3665900796784 /* Products */ = { + isa = PBXGroup; + children = ( + D06018C822F3665900796784 /* CheckNode.framework */, + ); + name = Products; + sourceTree = ""; + }; + D06018CA22F3665900796784 /* Sources */ = { + isa = PBXGroup; + children = ( + D06018D722F366B000796784 /* CheckNode.swift */, + D06018CB22F3665900796784 /* CheckNode.h */, + ); + path = Sources; + sourceTree = ""; + }; + D06018D922F366BA00796784 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D06018E022F366C500796784 /* LegacyComponents.framework */, + D06018DE22F366C200796784 /* AsyncDisplayKit.framework */, + D06018DC22F366BE00796784 /* Foundation.framework */, + D06018DA22F366BB00796784 /* UIKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D06018C322F3665900796784 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D06018CD22F3665900796784 /* CheckNode.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D06018C722F3665900796784 /* CheckNode */ = { + isa = PBXNativeTarget; + buildConfigurationList = D06018D022F3665900796784 /* Build configuration list for PBXNativeTarget "CheckNode" */; + buildPhases = ( + D06018C322F3665900796784 /* Headers */, + D06018C422F3665900796784 /* Sources */, + D06018C522F3665900796784 /* Frameworks */, + D06018C622F3665900796784 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CheckNode; + productName = CheckNode; + productReference = D06018C822F3665900796784 /* CheckNode.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D06018BF22F3665900796784 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D06018C722F3665900796784 = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1010; + }; + }; + }; + buildConfigurationList = D06018C222F3665900796784 /* Build configuration list for PBXProject "CheckNode_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D06018BE22F3665900796784; + productRefGroup = D06018C922F3665900796784 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D06018C722F3665900796784 /* CheckNode */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D06018C622F3665900796784 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D06018C422F3665900796784 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D06018D822F366B000796784 /* CheckNode.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D06018CE22F3665900796784 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D06018CF22F3665900796784 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D06018D122F3665900796784 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.CheckNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D06018D222F3665900796784 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.CheckNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D06018D322F3667B00796784 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D06018D422F3667B00796784 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.CheckNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D06018D522F3668600796784 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D06018D622F3668600796784 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.CheckNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D06018C222F3665900796784 /* Build configuration list for PBXProject "CheckNode_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D06018CE22F3665900796784 /* DebugAppStoreLLC */, + D06018D322F3667B00796784 /* DebugHockeyapp */, + D06018CF22F3665900796784 /* ReleaseAppStoreLLC */, + D06018D522F3668600796784 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D06018D022F3665900796784 /* Build configuration list for PBXNativeTarget "CheckNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D06018D122F3665900796784 /* DebugAppStoreLLC */, + D06018D422F3667B00796784 /* DebugHockeyapp */, + D06018D222F3665900796784 /* ReleaseAppStoreLLC */, + D06018D622F3668600796784 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D06018BF22F3665900796784 /* Project object */; +} diff --git a/submodules/CheckNode/Info.plist b/submodules/CheckNode/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/CheckNode/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/CheckNode/Sources/CheckNode.h b/submodules/CheckNode/Sources/CheckNode.h new file mode 100644 index 0000000000..20e15c1826 --- /dev/null +++ b/submodules/CheckNode/Sources/CheckNode.h @@ -0,0 +1,19 @@ +// +// CheckNode.h +// CheckNode +// +// Created by Peter on 8/1/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for CheckNode. +FOUNDATION_EXPORT double CheckNodeVersionNumber; + +//! Project version string for CheckNode. +FOUNDATION_EXPORT const unsigned char CheckNodeVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/TelegramUI/TelegramUI/CheckNode.swift b/submodules/CheckNode/Sources/CheckNode.swift similarity index 71% rename from submodules/TelegramUI/TelegramUI/CheckNode.swift rename to submodules/CheckNode/Sources/CheckNode.swift index d49dbbda3e..4a1071282c 100644 --- a/submodules/TelegramUI/TelegramUI/CheckNode.swift +++ b/submodules/CheckNode/Sources/CheckNode.swift @@ -4,13 +4,13 @@ import AsyncDisplayKit import LegacyComponents -enum CheckNodeStyle { +public enum CheckNodeStyle { case plain case overlay case navigation } -final class CheckNode: ASDisplayNode { +public final class CheckNode: ASDisplayNode { private var strokeColor: UIColor private var fillColor: UIColor private var foregroundColor: UIColor @@ -18,12 +18,12 @@ final class CheckNode: ASDisplayNode { private var checkView: TGCheckButtonView? - private(set) var isChecked: Bool = false + public private(set) var isChecked: Bool = false private weak var target: AnyObject? private var action: Selector? - init(strokeColor: UIColor, fillColor: UIColor, foregroundColor: UIColor, style: CheckNodeStyle) { + public init(strokeColor: UIColor, fillColor: UIColor, foregroundColor: UIColor, style: CheckNodeStyle) { self.strokeColor = strokeColor self.fillColor = fillColor self.foregroundColor = foregroundColor @@ -32,21 +32,21 @@ final class CheckNode: ASDisplayNode { super.init() } - override func didLoad() { + override public func didLoad() { super.didLoad() let style: TGCheckButtonStyle let checkSize: CGSize switch self.checkStyle { - case .plain: - style = TGCheckButtonStyleDefault - checkSize = CGSize(width: 32.0, height: 32.0) - case .overlay: - style = TGCheckButtonStyleMedia - checkSize = CGSize(width: 32.0, height: 32.0) - case .navigation: - style = TGCheckButtonStyleGallery - checkSize = CGSize(width: 39.0, height: 39.0) + case .plain: + style = TGCheckButtonStyleDefault + checkSize = CGSize(width: 32.0, height: 32.0) + case .overlay: + style = TGCheckButtonStyleMedia + checkSize = CGSize(width: 32.0, height: 32.0) + case .navigation: + style = TGCheckButtonStyleGallery + checkSize = CGSize(width: 39.0, height: 39.0) } let checkView = TGCheckButtonView(style: style, pallete: TGCheckButtonPallete(defaultBackgroundColor: self.fillColor, accentBackgroundColor: self.fillColor, defaultBorderColor: self.strokeColor, mediaBorderColor: self.strokeColor, chatBorderColor: self.strokeColor, check: self.foregroundColor, blueColor: self.fillColor, barBackgroundColor: self.fillColor))! checkView.setSelected(true, animated: false) @@ -61,14 +61,14 @@ final class CheckNode: ASDisplayNode { checkView.frame = CGRect(origin: CGPoint(), size: checkSize) } - func setIsChecked(_ isChecked: Bool, animated: Bool) { + public func setIsChecked(_ isChecked: Bool, animated: Bool) { if isChecked != self.isChecked { self.isChecked = isChecked self.checkView?.setSelected(isChecked, animated: animated) } } - func addTarget(target: AnyObject?, action: Selector) { + public func addTarget(target: AnyObject?, action: Selector) { self.target = target self.action = action if self.isNodeLoaded { From b97ff40a8046eb09562ca86c77dac9c08083ac96 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:15:31 +0300 Subject: [PATCH 27/41] Update Display to Swift 4.2 --- .../Display/Display/Accessibility.swift | 2 +- .../Display/ActionSheetControllerNode.swift | 2 +- .../Display/Display/CAAnimationUtils.swift | 32 ++-- .../ContainedViewLayoutTransition.swift | 8 +- .../Display/ContextMenuActionNode.swift | 2 +- .../Display/ContextMenuController.swift | 2 +- .../Display/DisplayLinkDispatcher.swift | 2 +- submodules/Display/Display/Font.swift | 8 +- submodules/Display/Display/GridNode.swift | 16 +- .../Display/Display/ImmediateTextNode.swift | 6 +- .../Display/LegacyPresentedController.swift | 4 +- .../LegacyPresentedControllerNode.swift | 2 +- submodules/Display/Display/ListView.swift | 141 +++++------------- .../Display/Display/ListViewAnimation.swift | 2 +- .../Display/NativeWindowHostView.swift | 6 +- .../Display/NavigationBackButtonNode.swift | 8 +- .../Display/Display/NavigationBar.swift | 6 +- .../Display/NavigationButtonNode.swift | 8 +- .../Display/NavigationController.swift | 14 +- .../Display/Display/NavigationTitleNode.swift | 6 +- .../NavigationTransitionCoordinator.swift | 6 +- .../Display/PeekControllerMenuItemNode.swift | 2 +- .../Display/Display/PeekControllerNode.swift | 6 +- .../Display/Display/PresentationContext.swift | 2 +- submodules/Display/Display/StatusBar.swift | 4 +- .../Display/Display/StatusBarManager.swift | 2 +- .../Display/Display/StatusBarProxyNode.swift | 4 +- .../Display/Display/TabBarController.swift | 12 +- submodules/Display/Display/TabBarNode.swift | 8 +- ...pLongTapOrDoubleTapGestureRecognizer.swift | 18 +-- .../Display/Display/TextAlertController.swift | 6 +- submodules/Display/Display/TextNode.swift | 28 ++-- .../Display/Display/UITracingLayerView.swift | 2 +- .../Display/UniversalTapRecognizer.swift | 2 +- .../Display/Display/ViewController.swift | 2 +- .../Display/Display/WindowContent.swift | 20 +-- .../Display_Xcode.xcodeproj/project.pbxproj | 20 ++- 37 files changed, 180 insertions(+), 241 deletions(-) diff --git a/submodules/Display/Display/Accessibility.swift b/submodules/Display/Display/Accessibility.swift index 77a8835a7f..cdda8f2de8 100644 --- a/submodules/Display/Display/Accessibility.swift +++ b/submodules/Display/Display/Accessibility.swift @@ -5,7 +5,7 @@ import AsyncDisplayKit public func addAccessibilityChildren(of node: ASDisplayNode, container: Any, to list: inout [Any]) { if node.isAccessibilityElement { let element = UIAccessibilityElement(accessibilityContainer: container) - element.accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(node.bounds, node.view) + element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(node.bounds, in: node.view) element.accessibilityLabel = node.accessibilityLabel element.accessibilityValue = node.accessibilityValue element.accessibilityTraits = node.accessibilityTraits diff --git a/submodules/Display/Display/ActionSheetControllerNode.swift b/submodules/Display/Display/ActionSheetControllerNode.swift index 820547892d..fb100e0246 100644 --- a/submodules/Display/Display/ActionSheetControllerNode.swift +++ b/submodules/Display/Display/ActionSheetControllerNode.swift @@ -139,7 +139,7 @@ final class ActionSheetControllerNode: ASDisplayNode, UIScrollViewDelegate { } self.itemGroupsContainerNode.animateDimViewsAlpha(from: 1.0, to: 0.0, duration: 0.3) - self.layer.animateBounds(from: self.bounds, to: self.bounds.offsetBy(dx: 0.0, dy: -self.bounds.size.height), duration: 0.35, timingFunction: kCAMediaTimingFunctionEaseOut, removeOnCompletion: false, completion: { [weak self, weak tempDimView] _ in + self.layer.animateBounds(from: self.bounds, to: self.bounds.offsetBy(dx: 0.0, dy: -self.bounds.size.height), duration: 0.35, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { [weak self, weak tempDimView] _ in tempDimView?.removeFromSuperview() self?.dismiss(cancelled) diff --git a/submodules/Display/Display/CAAnimationUtils.swift b/submodules/Display/Display/CAAnimationUtils.swift index 44cfa25f4e..7a0df6e933 100644 --- a/submodules/Display/Display/CAAnimationUtils.swift +++ b/submodules/Display/Display/CAAnimationUtils.swift @@ -60,7 +60,7 @@ public extension CALayer { animation.fromValue = from animation.toValue = to animation.isRemovedOnCompletion = removeOnCompletion - animation.fillMode = kCAFillModeForwards + animation.fillMode = .forwards if let completion = completion { animation.delegate = CALayerAnimationDelegate(animation: animation, completion: completion) } @@ -76,7 +76,7 @@ public extension CALayer { if !delay.isZero { animation.beginTime = CACurrentMediaTime() + delay - animation.fillMode = kCAFillModeBoth + animation.fillMode = .both } return animation @@ -94,10 +94,10 @@ public extension CALayer { if let mediaTimingFunction = mediaTimingFunction { animation.timingFunction = mediaTimingFunction } else { - animation.timingFunction = CAMediaTimingFunction(name: timingFunction) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName(rawValue: timingFunction)) } animation.isRemovedOnCompletion = removeOnCompletion - animation.fillMode = kCAFillModeForwards + animation.fillMode = .forwards animation.speed = speed animation.isAdditive = additive if let completion = completion { @@ -106,7 +106,7 @@ public extension CALayer { if !delay.isZero { animation.beginTime = CACurrentMediaTime() + delay - animation.fillMode = kCAFillModeBoth + animation.fillMode = .both } return animation @@ -169,7 +169,7 @@ public extension CALayer { animation.fromValue = from animation.toValue = to animation.isRemovedOnCompletion = removeOnCompletion - animation.fillMode = kCAFillModeForwards + animation.fillMode = .forwards if let completion = completion { animation.delegate = CALayerAnimationDelegate(animation: animation, completion: completion) } @@ -200,10 +200,10 @@ public extension CALayer { if let mediaTimingFunction = mediaTimingFunction { animation.timingFunction = mediaTimingFunction } else { - animation.timingFunction = CAMediaTimingFunction(name: timingFunction) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName(rawValue: timingFunction)) } animation.isRemovedOnCompletion = removeOnCompletion - animation.fillMode = kCAFillModeForwards + animation.fillMode = .forwards animation.speed = speed animation.isAdditive = true if let completion = completion { @@ -213,19 +213,19 @@ public extension CALayer { self.add(animation, forKey: key) } - public func animateAlpha(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = kCAMediaTimingFunctionEaseInEaseOut, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, completion: ((Bool) -> ())? = nil) { + public func animateAlpha(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, completion: ((Bool) -> ())? = nil) { self.animate(from: NSNumber(value: Float(from)), to: NSNumber(value: Float(to)), keyPath: "opacity", timingFunction: timingFunction, duration: duration, delay: delay, mediaTimingFunction: mediaTimingFunction, removeOnCompletion: removeOnCompletion, completion: completion) } - public func animateScale(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = kCAMediaTimingFunctionEaseInEaseOut, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, completion: ((Bool) -> Void)? = nil) { + public func animateScale(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, completion: ((Bool) -> Void)? = nil) { self.animate(from: NSNumber(value: Float(from)), to: NSNumber(value: Float(to)), keyPath: "transform.scale", timingFunction: timingFunction, duration: duration, delay: delay, mediaTimingFunction: mediaTimingFunction, removeOnCompletion: removeOnCompletion, completion: completion) } - public func animateRotation(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = kCAMediaTimingFunctionEaseInEaseOut, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, completion: ((Bool) -> Void)? = nil) { + public func animateRotation(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, completion: ((Bool) -> Void)? = nil) { self.animate(from: NSNumber(value: Float(from)), to: NSNumber(value: Float(to)), keyPath: "transform.rotation.z", timingFunction: timingFunction, duration: duration, delay: delay, mediaTimingFunction: mediaTimingFunction, removeOnCompletion: removeOnCompletion, completion: completion) } - func animatePosition(from: CGPoint, to: CGPoint, duration: Double, delay: Double = 0.0, timingFunction: String = kCAMediaTimingFunctionEaseInEaseOut, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, additive: Bool = false, force: Bool = false, completion: ((Bool) -> Void)? = nil) { + func animatePosition(from: CGPoint, to: CGPoint, duration: Double, delay: Double = 0.0, timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, additive: Bool = false, force: Bool = false, completion: ((Bool) -> Void)? = nil) { if from == to && !force { if let completion = completion { completion(true) @@ -245,20 +245,20 @@ public extension CALayer { self.animate(from: NSValue(cgRect: from), to: NSValue(cgRect: to), keyPath: "bounds", timingFunction: timingFunction, duration: duration, mediaTimingFunction: mediaTimingFunction, removeOnCompletion: removeOnCompletion, additive: additive, completion: completion) } - public func animateBoundsOriginXAdditive(from: CGFloat, to: CGFloat, duration: Double, timingFunction: String = kCAMediaTimingFunctionEaseInEaseOut, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, completion: ((Bool) -> Void)? = nil) { + public func animateBoundsOriginXAdditive(from: CGFloat, to: CGFloat, duration: Double, timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, completion: ((Bool) -> Void)? = nil) { self.animate(from: from as NSNumber, to: to as NSNumber, keyPath: "bounds.origin.x", timingFunction: timingFunction, duration: duration, mediaTimingFunction: mediaTimingFunction, removeOnCompletion: removeOnCompletion, additive: true, completion: completion) } - public func animateBoundsOriginYAdditive(from: CGFloat, to: CGFloat, duration: Double, timingFunction: String = kCAMediaTimingFunctionEaseInEaseOut, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, completion: ((Bool) -> Void)? = nil) { + public func animateBoundsOriginYAdditive(from: CGFloat, to: CGFloat, duration: Double, timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, completion: ((Bool) -> Void)? = nil) { self.animate(from: from as NSNumber, to: to as NSNumber, keyPath: "bounds.origin.y", timingFunction: timingFunction, duration: duration, mediaTimingFunction: mediaTimingFunction, removeOnCompletion: removeOnCompletion, additive: true, completion: completion) } public func animateBoundsOriginXAdditive(from: CGFloat, to: CGFloat, duration: Double, mediaTimingFunction: CAMediaTimingFunction) { - self.animate(from: from as NSNumber, to: to as NSNumber, keyPath: "bounds.origin.x", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: duration, mediaTimingFunction: mediaTimingFunction, additive: true) + self.animate(from: from as NSNumber, to: to as NSNumber, keyPath: "bounds.origin.x", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: duration, mediaTimingFunction: mediaTimingFunction, additive: true) } public func animateBoundsOriginYAdditive(from: CGFloat, to: CGFloat, duration: Double, mediaTimingFunction: CAMediaTimingFunction) { - self.animate(from: from as NSNumber, to: to as NSNumber, keyPath: "bounds.origin.y", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: duration, mediaTimingFunction: mediaTimingFunction, additive: true) + self.animate(from: from as NSNumber, to: to as NSNumber, keyPath: "bounds.origin.y", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: duration, mediaTimingFunction: mediaTimingFunction, additive: true) } public func animatePositionKeyframes(values: [CGPoint], duration: Double, removeOnCompletion: Bool = true, completion: ((Bool) -> Void)? = nil) { diff --git a/submodules/Display/Display/ContainedViewLayoutTransition.swift b/submodules/Display/Display/ContainedViewLayoutTransition.swift index 14b2206685..20c2978053 100644 --- a/submodules/Display/Display/ContainedViewLayoutTransition.swift +++ b/submodules/Display/Display/ContainedViewLayoutTransition.swift @@ -16,11 +16,11 @@ public extension ContainedViewLayoutTransitionCurve { var timingFunction: String { switch self { case .easeInOut: - return kCAMediaTimingFunctionEaseInEaseOut + return CAMediaTimingFunctionName.easeInEaseOut.rawValue case .spring: return kCAMediaTimingFunctionSpring case .custom: - return kCAMediaTimingFunctionEaseInEaseOut + return CAMediaTimingFunctionName.easeInEaseOut.rawValue } } @@ -36,12 +36,12 @@ public extension ContainedViewLayoutTransitionCurve { } #if os(iOS) - var viewAnimationOptions: UIViewAnimationOptions { + var viewAnimationOptions: UIView.AnimationOptions { switch self { case .easeInOut: return [.curveEaseInOut] case .spring: - return UIViewAnimationOptions(rawValue: 7 << 16) + return UIView.AnimationOptions(rawValue: 7 << 16) case .custom: return [] } diff --git a/submodules/Display/Display/ContextMenuActionNode.swift b/submodules/Display/Display/ContextMenuActionNode.swift index 135e5c9c06..64da141003 100644 --- a/submodules/Display/Display/ContextMenuActionNode.swift +++ b/submodules/Display/Display/ContextMenuActionNode.swift @@ -24,7 +24,7 @@ final class ContextMenuActionNode: ASDisplayNode { init(action: ContextMenuAction) { self.actionArea = AccessibilityAreaNode() - self.actionArea.accessibilityTraits = UIAccessibilityTraitButton + self.actionArea.accessibilityTraits = .button switch action.content { case let .text(title, accessibilityLabel): diff --git a/submodules/Display/Display/ContextMenuController.swift b/submodules/Display/Display/ContextMenuController.swift index 4e71c8d903..e4d2ab6d79 100644 --- a/submodules/Display/Display/ContextMenuController.swift +++ b/submodules/Display/Display/ContextMenuController.swift @@ -16,7 +16,7 @@ public final class ContextMenuController: ViewController, KeyShortcutResponder { } public var keyShortcuts: [KeyShortcut] { - return [KeyShortcut(input: UIKeyInputEscape, action: { [weak self] in + return [KeyShortcut(input: UIKeyCommand.inputEscape, action: { [weak self] in if let strongSelf = self { strongSelf.dismiss() } diff --git a/submodules/Display/Display/DisplayLinkDispatcher.swift b/submodules/Display/Display/DisplayLinkDispatcher.swift index 2519977ad3..a86bc9762b 100644 --- a/submodules/Display/Display/DisplayLinkDispatcher.swift +++ b/submodules/Display/Display/DisplayLinkDispatcher.swift @@ -16,7 +16,7 @@ public class DisplayLinkDispatcher: NSObject { } else { self.displayLink = CADisplayLink(target: self, selector: #selector(self.run)) self.displayLink.isPaused = true - self.displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink.add(to: RunLoop.main, forMode: .common) } } diff --git a/submodules/Display/Display/Font.swift b/submodules/Display/Display/Font.swift index ed0a02001d..30f69df956 100644 --- a/submodules/Display/Display/Font.swift +++ b/submodules/Display/Display/Font.swift @@ -69,15 +69,15 @@ public struct Font { public extension NSAttributedString { convenience init(string: String, font: UIFont? = nil, textColor: UIColor = UIColor.black, paragraphAlignment: NSTextAlignment? = nil) { - var attributes: [NSAttributedStringKey: AnyObject] = [:] + var attributes: [NSAttributedString.Key: AnyObject] = [:] if let font = font { - attributes[NSAttributedStringKey.font] = font + attributes[NSAttributedString.Key.font] = font } - attributes[NSAttributedStringKey.foregroundColor] = textColor + attributes[NSAttributedString.Key.foregroundColor] = textColor if let paragraphAlignment = paragraphAlignment { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = paragraphAlignment - attributes[NSAttributedStringKey.paragraphStyle] = paragraphStyle + attributes[NSAttributedString.Key.paragraphStyle] = paragraphStyle } self.init(string: string, attributes: attributes) } diff --git a/submodules/Display/Display/GridNode.swift b/submodules/Display/Display/GridNode.swift index ce9b59319f..d772588965 100644 --- a/submodules/Display/Display/GridNode.swift +++ b/submodules/Display/Display/GridNode.swift @@ -237,7 +237,7 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate { } } - public var indicatorStyle: UIScrollViewIndicatorStyle = .default { + public var indicatorStyle: UIScrollView.IndicatorStyle = .default { didSet { self.scrollView.indicatorStyle = self.indicatorStyle } @@ -1015,8 +1015,8 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate { if !existingItemIndices.contains(index) { if let _ = previousItemFrames[WrappedGridItemNode(node: itemNode)] { self.removeItemNodeWithIndex(index, removeNode: false) - itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false) - itemNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false, completion: { [weak itemNode] _ in + itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false) + itemNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false, completion: { [weak itemNode] _ in itemNode?.removeFromSupernode() }) } else { @@ -1025,15 +1025,15 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate { } else if let previousFrame = previousItemFrames[WrappedGridItemNode(node: itemNode)] { itemNode.layer.animatePosition(from: CGPoint(x: previousFrame.midX, y: previousFrame.midY + contentOffset.y), to: itemNode.layer.position, duration: duration, timingFunction: timingFunction, mediaTimingFunction: mediaTimingFunction) } else { - itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.12, timingFunction: kCAMediaTimingFunctionEaseIn) + itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.12, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue) itemNode.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.5) } } for itemNode in removedNodes { if let _ = previousItemFrames[WrappedGridItemNode(node: itemNode)] { - itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.18, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false) - itemNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.18, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false, completion: { [weak itemNode] _ in + itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.18, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false) + itemNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.18, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false, completion: { [weak itemNode] _ in itemNode?.removeFromSupernode() }) } else { @@ -1055,7 +1055,7 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate { } else if let previousFrame = previousItemFrames[WrappedGridItemNode(node: sectionNode)] { sectionNode.layer.animatePosition(from: CGPoint(x: previousFrame.midX, y: previousFrame.midY + contentOffset.y), to: sectionNode.layer.position, duration: duration, timingFunction: timingFunction, mediaTimingFunction: mediaTimingFunction) } else { - sectionNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseIn) + sectionNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue) } } } else { @@ -1121,7 +1121,7 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate { if addedNodes { if let verticalIndicator = verticalIndicator, self.scrollView.subviews.last !== verticalIndicator { - verticalIndicator.superview?.bringSubview(toFront: verticalIndicator) + verticalIndicator.superview?.bringSubviewToFront(verticalIndicator) } } diff --git a/submodules/Display/Display/ImmediateTextNode.swift b/submodules/Display/Display/ImmediateTextNode.swift index add3df7e25..66ef62b0ef 100644 --- a/submodules/Display/Display/ImmediateTextNode.swift +++ b/submodules/Display/Display/ImmediateTextNode.swift @@ -21,7 +21,7 @@ public class ImmediateTextNode: TextNode { public var trailingLineWidth: CGFloat? - public var highlightAttributeAction: (([NSAttributedStringKey: Any]) -> NSAttributedStringKey?)? { + public var highlightAttributeAction: (([NSAttributedString.Key: Any]) -> NSAttributedString.Key?)? { didSet { if self.isNodeLoaded { self.updateInteractiveActions() @@ -29,8 +29,8 @@ public class ImmediateTextNode: TextNode { } } - public var tapAttributeAction: (([NSAttributedStringKey: Any]) -> Void)? - public var longTapAttributeAction: (([NSAttributedStringKey: Any]) -> Void)? + public var tapAttributeAction: (([NSAttributedString.Key: Any]) -> Void)? + public var longTapAttributeAction: (([NSAttributedString.Key: Any]) -> Void)? public func updateLayout(_ constrainedSize: CGSize) -> CGSize { let makeLayout = TextNode.asyncLayout(self) diff --git a/submodules/Display/Display/LegacyPresentedController.swift b/submodules/Display/Display/LegacyPresentedController.swift index 496b976d23..d0b8308e2e 100644 --- a/submodules/Display/Display/LegacyPresentedController.swift +++ b/submodules/Display/Display/LegacyPresentedController.swift @@ -43,7 +43,7 @@ open class LegacyPresentedController: ViewController { self?.dismiss() }*/ if !asPresentable { - self.addChildViewController(legacyController) + self.addChild(legacyController) } } @@ -67,7 +67,7 @@ open class LegacyPresentedController: ViewController { self.controllerNode.controllerView = self.legacyController.view self.controllerNode.view.addSubview(self.legacyController.view) - self.legacyController.didMove(toParentViewController: self) + self.legacyController.didMove(toParent: self) if let controllerLoaded = self.controllerLoaded { controllerLoaded() diff --git a/submodules/Display/Display/LegacyPresentedControllerNode.swift b/submodules/Display/Display/LegacyPresentedControllerNode.swift index 4aa8fc293d..f64d4772c6 100644 --- a/submodules/Display/Display/LegacyPresentedControllerNode.swift +++ b/submodules/Display/Display/LegacyPresentedControllerNode.swift @@ -33,7 +33,7 @@ final class LegacyPresentedControllerNode: ASDisplayNode { } func animateModalOut(completion: @escaping () -> Void) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion() }) } diff --git a/submodules/Display/Display/ListView.swift b/submodules/Display/Display/ListView.swift index 3fa834e803..e9585eba04 100644 --- a/submodules/Display/Display/ListView.swift +++ b/submodules/Display/Display/ListView.swift @@ -6,8 +6,6 @@ import SwiftSignalKit import DisplayPrivate #endif -private let useBackgroundDeallocation = false - private let infiniteScrollSize: CGFloat = 10000.0 private let insertionAnimationDuration: Double = 0.4 @@ -359,7 +357,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture })) self.displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent)) - self.displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink.add(to: RunLoop.main, forMode: RunLoop.Mode.common) if #available(iOS 10.0, *) { self.displayLink.preferredFramesPerSecond = 60 @@ -372,25 +370,15 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture self.pauseAnimations() self.displayLink.invalidate() - if useBackgroundDeallocation { - assertionFailure() - /*for itemNode in self.itemNodes { - ASDeallocQueue.sharedDeallocation.releaseObject(inBackground: UnsafeMutablePointer(itemNode)) - } - for itemHeaderNode in self.itemHeaderNodes { - ASDeallocQueue.sharedDeallocatio.releaseObject(inBackground: itemHeaderNode) - }*/ - } else { - for i in (0 ..< self.itemNodes.count).reversed() { - var itemNode: AnyObject? = self.itemNodes[i] - self.itemNodes.remove(at: i) - ASPerformMainThreadDeallocation(&itemNode) - } - for key in self.itemHeaderNodes.keys { - var itemHeaderNode: AnyObject? = self.itemHeaderNodes[key] - self.itemHeaderNodes.removeValue(forKey: key) - ASPerformMainThreadDeallocation(&itemHeaderNode) - } + for i in (0 ..< self.itemNodes.count).reversed() { + var itemNode: AnyObject? = self.itemNodes[i] + self.itemNodes.remove(at: i) + ASPerformMainThreadDeallocation(&itemNode) + } + for key in self.itemHeaderNodes.keys { + var itemHeaderNode: AnyObject? = self.itemHeaderNodes[key] + self.itemHeaderNodes.removeValue(forKey: key) + ASPerformMainThreadDeallocation(&itemHeaderNode) } self.waitingForNodesDisposable.dispose() @@ -446,8 +434,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture self.reorderNode = nil if let itemNode = reorderNode.itemNode, itemNode.supernode == self { self.reorderItemNodeToFront(itemNode) - reorderNode.animateCompletion(completion: { [weak itemNode, weak reorderNode] in - //itemNode?.isHidden = false + reorderNode.animateCompletion(completion: { [weak reorderNode] in reorderNode?.removeFromSupernode() }) self.setNeedsAnimations() @@ -545,7 +532,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } }, selector: #selector(ListViewTimerProxy.timerEvent), userInfo: nil, repeats: false) self.flashNodesDelayTimer = timer - RunLoop.main.add(timer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(timer, forMode: RunLoop.Mode.common) self.updateHeaderItemsFlashing(animated: true) } } @@ -568,7 +555,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } }, selector: #selector(ListViewTimerProxy.timerEvent), userInfo: nil, repeats: false) self.flashScrollIndicatorTimer = timer - RunLoop.main.add(timer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(timer, forMode: RunLoop.Mode.common) } else { self.verticalScrollIndicator?.layer.removeAnimation(forKey: "opacity") self.verticalScrollIndicator?.alpha = 1.0 @@ -1132,9 +1119,9 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture for itemNode in self.itemNodes { if itemNode.isHighlightedInOverlay { lowestOverlayNode = itemNode - itemNode.view.superview?.bringSubview(toFront: itemNode.view) + itemNode.view.superview?.bringSubviewToFront(itemNode.view) if let verticalScrollIndicator = self.verticalScrollIndicator { - verticalScrollIndicator.view.superview?.bringSubview(toFront: verticalScrollIndicator.view) + verticalScrollIndicator.view.superview?.bringSubviewToFront(verticalScrollIndicator.view) } } } @@ -1154,18 +1141,18 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } } else if let itemHighlightOverlayBackground = self.itemHighlightOverlayBackground { self.itemHighlightOverlayBackground = nil - for (_, headerNode) in self.itemHeaderNodes { + for (_, _) in self.itemHeaderNodes { //self.view.bringSubview(toFront: headerNode.view) } //self.view.bringSubview(toFront: itemHighlightOverlayBackground.view) - for itemNode in self.itemNodes { + for _ in self.itemNodes { //self.view.bringSubview(toFront: itemNode.view) } transition.updateAlpha(node: itemHighlightOverlayBackground, alpha: 0.0, completion: { [weak itemHighlightOverlayBackground] _ in itemHighlightOverlayBackground?.removeFromSupernode() }) if let verticalScrollIndicator = self.verticalScrollIndicator { - verticalScrollIndicator.view.superview?.bringSubview(toFront: verticalScrollIndicator.view) + verticalScrollIndicator.view.superview?.bringSubviewToFront(verticalScrollIndicator.view) } } } @@ -1650,12 +1637,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if let strongSelf = self { strongSelf.replayOperations(animated: animated, animateAlpha: options.contains(.AnimateAlpha), animateCrossfade: options.contains(.AnimateCrossfade), synchronous: options.contains(.Synchronous), animateTopItemVerticalOrigin: options.contains(.AnimateTopItemPosition), operations: updatedOperations, requestItemInsertionAnimationsIndices: options.contains(.RequestItemInsertionAnimations) ? insertedIndexSet : Set(), scrollToItem: scrollToItem, additionalScrollDistance: additionalScrollDistance, updateSizeAndInsets: updateSizeAndInsets, stationaryItemIndex: stationaryItemIndex, updateOpaqueState: updateOpaqueState, completion: { if options.contains(.PreferSynchronousDrawing) { - let startTime = CACurrentMediaTime() self?.recursivelyEnsureDisplaySynchronously(true) - let deltaTime = CACurrentMediaTime() - startTime - if false { - print("ListView: waited \(deltaTime * 1000.0) ms for nodes to display") - } } completion() }) @@ -1666,12 +1648,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture let readyWithTimeout = combineLatest(readySignals) |> deliverOnMainQueue |> timeout(0.2, queue: Queue.mainQueue(), alternate: .single([])) - let startTime = CACurrentMediaTime() self.waitingForNodesDisposable.set(readyWithTimeout.start(completed: { - let deltaTime = CACurrentMediaTime() - startTime - if false { - print("ListView: waited \(deltaTime * 1000.0) ms for nodes to load") - } beginReplay() })) } else { @@ -1905,7 +1882,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if nextNode.index == nil && nextNode.subnodes == nil || nextNode.subnodes!.isEmpty { let nextHeight = nextNode.apparentHeight if abs(nextHeight - previousApparentHeight) < CGFloat.ulpOfOne { - if let animation = nextNode.animationForKey("apparentHeight") { + if let _ = nextNode.animationForKey("apparentHeight") { node.apparentHeight = previousApparentHeight offsetHeight = 0.0 @@ -2363,9 +2340,9 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } if hadInserts, let reorderNode = self.reorderNode, reorderNode.supernode != nil { - self.view.bringSubview(toFront: reorderNode.view) + self.view.bringSubviewToFront(reorderNode.view) if let verticalScrollIndicator = self.verticalScrollIndicator { - verticalScrollIndicator.view.superview?.bringSubview(toFront: verticalScrollIndicator.view) + verticalScrollIndicator.view.superview?.bringSubviewToFront(verticalScrollIndicator.view) } } @@ -2535,7 +2512,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture case let .Default(duration): headerNodesTransition = (.animated(duration: max(duration ?? 0.3, updateSizeAndInsets.duration), curve: .easeInOut), false, -completeOffset) let basicAnimation = CABasicAnimation(keyPath: "sublayerTransform") - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = updateSizeAndInsets.duration * UIView.animationDurationFactor() basicAnimation.fromValue = NSValue(caTransform3D: CATransform3DMakeTranslation(0.0, -completeOffset, 0.0)) basicAnimation.toValue = NSValue(caTransform3D: CATransform3DIdentity) @@ -2751,7 +2728,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture springAnimation.toValue = NSValue(caTransform3D: CATransform3DIdentity) springAnimation.isRemovedOnCompletion = true springAnimation.isAdditive = true - springAnimation.fillMode = kCAFillModeForwards + springAnimation.fillMode = CAMediaTimingFillMode.forwards let k = Float(UIView.animationDurationFactor()) var speed: Float = 1.0 @@ -2767,7 +2744,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture reverseSpringAnimation.toValue = NSValue(caTransform3D: CATransform3DIdentity) reverseSpringAnimation.isRemovedOnCompletion = true reverseSpringAnimation.isAdditive = true - reverseSpringAnimation.fillMode = kCAFillModeForwards + reverseSpringAnimation.fillMode = CAMediaTimingFillMode.forwards reverseSpringAnimation.speed = speed * Float(reverseSpringAnimation.duration / duration) @@ -2776,7 +2753,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture case let .Default(duration): if let duration = duration { let basicAnimation = CABasicAnimation(keyPath: "sublayerTransform") - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = duration * UIView.animationDurationFactor() basicAnimation.fromValue = NSValue(caTransform3D: CATransform3DMakeTranslation(0.0, -offset, 0.0)) basicAnimation.toValue = NSValue(caTransform3D: CATransform3DIdentity) @@ -2784,7 +2761,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture basicAnimation.isAdditive = true let reverseBasicAnimation = CABasicAnimation(keyPath: "sublayerTransform") - reverseBasicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + reverseBasicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) reverseBasicAnimation.duration = duration * UIView.animationDurationFactor() reverseBasicAnimation.fromValue = NSValue(caTransform3D: CATransform3DMakeTranslation(0.0, offset, 0.0)) reverseBasicAnimation.toValue = NSValue(caTransform3D: CATransform3DIdentity) @@ -2817,38 +2794,15 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture animation.completion = { _ in for itemNode in temporaryPreviousNodes { itemNode.removeFromSupernode() - if useBackgroundDeallocation { - assertionFailure() - //ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode) - } else { - //ASPerformMainThreadDeallocation(itemNode) - } } for headerNode in temporaryHeaderNodes { headerNode.removeFromSupernode() - if useBackgroundDeallocation { - assertionFailure() - //ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: headerNode) - } else { - //ASPerformMainThreadDeallocation(headerNode) - } } } self.layer.add(animation, forKey: nil) if let verticalScrollIndicator = self.verticalScrollIndicator { verticalScrollIndicator.layer.add(reverseAnimation, forKey: nil) } - } else { - if useBackgroundDeallocation { - assertionFailure() - /*for itemNode in temporaryPreviousNodes { - ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode) - }*/ - } else { - for itemNode in temporaryPreviousNodes { - //ASPerformMainThreadDeallocation(itemNode) - } - } } } @@ -2891,17 +2845,6 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture //print("replayOperations \(delta * 1000.0) ms") } - for (previousNode, _) in previousApparentFrames { - if previousNode.supernode == nil { - if useBackgroundDeallocation { - assertionFailure() - //ASDeallocQueue.sharedDeallocatio.releaseObject(inBackground: previousNode) - } else { - //ASPerformMainThreadDeallocation(previousNode) - } - } - } - completion() } } @@ -2974,7 +2917,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if transition.1 { headerNode.layer.animateBoundsOriginYAdditive(from: offset, to: 0.0, duration: duration, mediaTimingFunction: ContainedViewLayoutTransitionCurve.slide.mediaTimingFunction) } else { - headerNode.layer.animateBoundsOriginYAdditive(from: offset, to: 0.0, duration: duration, mediaTimingFunction: CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)) + headerNode.layer.animateBoundsOriginYAdditive(from: offset, to: 0.0, duration: duration, mediaTimingFunction: CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)) } } } @@ -3122,10 +3065,8 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture updatedAccessoryItemNodeOrigin.x += updatedParentOrigin.x updatedAccessoryItemNodeOrigin.y += updatedParentOrigin.y updatedAccessoryItemNodeOrigin.y -= itemNode.bounds.origin.y - //updatedAccessoryItemNodeOrigin.y += itemNode.transitionOffset - var deltaHeight = itemNode.frame.size.height - nextItemNode.frame.size.height - //deltaHeight = 0.0 + let deltaHeight = itemNode.frame.size.height - nextItemNode.frame.size.height nextAccessoryItemNode.animateTransitionOffset(CGPoint(x: 0.0, y: updatedAccessoryItemNodeOrigin.y - previousAccessoryItemNodeOrigin.y - deltaHeight), beginAt: currentTimestamp, duration: insertionAnimationDuration * UIView.animationDurationFactor(), curve: listViewAnimationCurveSystem) } @@ -3343,12 +3284,6 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture let node = self.itemNodes[i] if node.index == nil && node.apparentHeight <= CGFloat.ulpOfOne { self.removeItemNodeAtIndex(i) - if useBackgroundDeallocation { - assertionFailure() - //ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: node) - } else { - //ASPerformMainThreadDeallocation(node) - } } else { i += 1 } @@ -3645,7 +3580,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } }, selector: #selector(ListViewTimerProxy.timerEvent), userInfo: nil, repeats: false) strongSelf.selectionLongTapDelayTimer = timer - RunLoop.main.add(timer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(timer, forMode: RunLoop.Mode.common) } } break @@ -3656,7 +3591,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } }, selector: #selector(ListViewTimerProxy.timerEvent), userInfo: nil, repeats: false) self.selectionTouchDelayTimer = timer - RunLoop.main.add(timer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(timer, forMode: RunLoop.Mode.common) super.touchesBegan(touches, with: event) @@ -3901,22 +3836,22 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } private func reorderItemNodeToFront(_ itemNode: ListViewItemNode) { - itemNode.view.superview?.bringSubview(toFront: itemNode.view) + itemNode.view.superview?.bringSubviewToFront(itemNode.view) if let itemHighlightOverlayBackground = self.itemHighlightOverlayBackground { - itemHighlightOverlayBackground.view.superview?.bringSubview(toFront: itemHighlightOverlayBackground.view) + itemHighlightOverlayBackground.view.superview?.bringSubviewToFront(itemHighlightOverlayBackground.view) } if let verticalScrollIndicator = self.verticalScrollIndicator { - verticalScrollIndicator.view.superview?.bringSubview(toFront: verticalScrollIndicator.view) + verticalScrollIndicator.view.superview?.bringSubviewToFront(verticalScrollIndicator.view) } } private func reorderHeaderNodeToFront(_ headerNode: ListViewItemHeaderNode) { - headerNode.view.superview?.bringSubview(toFront: headerNode.view) + headerNode.view.superview?.bringSubviewToFront(headerNode.view) if let itemHighlightOverlayBackground = self.itemHighlightOverlayBackground { - itemHighlightOverlayBackground.view.superview?.bringSubview(toFront: itemHighlightOverlayBackground.view) + itemHighlightOverlayBackground.view.superview?.bringSubviewToFront(itemHighlightOverlayBackground.view) } if let verticalScrollIndicator = self.verticalScrollIndicator { - verticalScrollIndicator.view.superview?.bringSubview(toFront: verticalScrollIndicator.view) + verticalScrollIndicator.view.superview?.bringSubviewToFront(verticalScrollIndicator.view) } } @@ -3958,10 +3893,10 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if let (_, frame) = accessibilityFocusedNode { for itemNode in self.itemNodes { if frame.intersects(itemNode.frame) { - UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, itemNode.view) + UIAccessibility.post(notification: UIAccessibility.Notification.layoutChanged, argument: itemNode.view) if let index = itemNode.index { let scrollStatus = "Row \(index + 1) of \(self.items.count)" - UIAccessibilityPostNotification(UIAccessibilityPageScrolledNotification, scrollStatus) + UIAccessibility.post(notification: UIAccessibility.Notification.pageScrolled, argument: scrollStatus) } break } diff --git a/submodules/Display/Display/ListViewAnimation.swift b/submodules/Display/Display/ListViewAnimation.swift index d546703e23..18107a64c2 100644 --- a/submodules/Display/Display/ListViewAnimation.swift +++ b/submodules/Display/Display/ListViewAnimation.swift @@ -97,7 +97,7 @@ public let listViewAnimationCurveLinear: (CGFloat) -> CGFloat = { t in } #if os(iOS) -public func listViewAnimationCurveFromAnimationOptions(animationOptions: UIViewAnimationOptions) -> (CGFloat) -> CGFloat { +public func listViewAnimationCurveFromAnimationOptions(animationOptions: UIView.AnimationOptions) -> (CGFloat) -> CGFloat { if animationOptions.rawValue == UInt(7 << 16) { return listViewAnimationCurveSystem } else { diff --git a/submodules/Display/Display/NativeWindowHostView.swift b/submodules/Display/Display/NativeWindowHostView.swift index a73092686a..56216b37e2 100644 --- a/submodules/Display/Display/NativeWindowHostView.swift +++ b/submodules/Display/Display/NativeWindowHostView.swift @@ -112,7 +112,7 @@ private final class WindowRootViewController: UIViewController, UIViewController self.extendedLayoutIncludesOpaqueBars = true if #available(iOSApplicationExtension 11.0, *) { - self.voiceOverStatusObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIAccessibilityVoiceOverStatusDidChange, object: nil, queue: OperationQueue.main, using: { [weak self] _ in + self.voiceOverStatusObserver = NotificationCenter.default.addObserver(forName: UIAccessibility.voiceOverStatusDidChangeNotification, object: nil, queue: OperationQueue.main, using: { [weak self] _ in if let strongSelf = self { strongSelf.updatePreviewingRegistration() } @@ -130,11 +130,11 @@ private final class WindowRootViewController: UIViewController, UIViewController } } - override func preferredScreenEdgesDeferringSystemGestures() -> UIRectEdge { + override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge { return self.gestureEdges } - override func prefersHomeIndicatorAutoHidden() -> Bool { + override var prefersHomeIndicatorAutoHidden: Bool { return self.preferNavigationUIHidden } diff --git a/submodules/Display/Display/NavigationBackButtonNode.swift b/submodules/Display/Display/NavigationBackButtonNode.swift index 393ba98db8..5b82bbab24 100644 --- a/submodules/Display/Display/NavigationBackButtonNode.swift +++ b/submodules/Display/Display/NavigationBackButtonNode.swift @@ -6,10 +6,10 @@ public class NavigationBackButtonNode: ASControlNode { return UIFont.systemFont(ofSize: 17.0) } - private func attributesForCurrentState() -> [NSAttributedStringKey : AnyObject] { + private func attributesForCurrentState() -> [NSAttributedString.Key : AnyObject] { return [ - NSAttributedStringKey.font: self.fontForCurrentState(), - NSAttributedStringKey.foregroundColor: self.isEnabled ? self.color : self.disabledColor + NSAttributedString.Key.font: self.fontForCurrentState(), + NSAttributedString.Key.foregroundColor: self.isEnabled ? self.color : self.disabledColor ] } @@ -137,7 +137,7 @@ public class NavigationBackButtonNode: ASControlNode { let alpha: CGFloat = !self.isEnabled ? 1.0 : (highlighted ? 0.4 : 1.0) if animated { - UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions.beginFromCurrentState, animations: { () -> Void in + UIView.animate(withDuration: 0.3, delay: 0.0, options: UIView.AnimationOptions.beginFromCurrentState, animations: { () -> Void in self.alpha = alpha }, completion: nil) } diff --git a/submodules/Display/Display/NavigationBar.swift b/submodules/Display/Display/NavigationBar.swift index c8d2420b84..073729ed53 100644 --- a/submodules/Display/Display/NavigationBar.swift +++ b/submodules/Display/Display/NavigationBar.swift @@ -334,7 +334,7 @@ open class NavigationBar: ASDisplayNode { accessibilityElements.append(self.titleNode) } if let titleView = self.titleView, titleView.superview != nil { - titleView.accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(titleView.bounds, titleView) + titleView.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(titleView.bounds, in: titleView) accessibilityElements.append(titleView) } if self.rightButtonNode.supernode != nil { @@ -672,7 +672,7 @@ open class NavigationBar: ASDisplayNode { self.titleNode = ASTextNode() self.titleNode.isAccessibilityElement = true - self.titleNode.accessibilityTraits = UIAccessibilityTraitHeader + self.titleNode.accessibilityTraits = .header self.backButtonNode = NavigationButtonNode() self.badgeNode = NavigationBarBadgeNode(fillColor: self.presentationData.theme.badgeBackgroundColor, strokeColor: self.presentationData.theme.badgeStrokeColor, textColor: self.presentationData.theme.badgeTextColor) @@ -831,7 +831,7 @@ open class NavigationBar: ASDisplayNode { leftTitleInset += backButtonSize.width + backButtonInset + 1.0 let topHitTestSlop = (nominalHeight - backButtonSize.height) * 0.5 - self.backButtonNode.hitTestSlop = UIEdgeInsetsMake(-topHitTestSlop, -27.0, -topHitTestSlop, -8.0) + self.backButtonNode.hitTestSlop = UIEdgeInsets(top: -topHitTestSlop, left: -27.0, bottom: -topHitTestSlop, right: -8.0) if let transitionState = self.transitionState { let progress = transitionState.progress diff --git a/submodules/Display/Display/NavigationButtonNode.swift b/submodules/Display/Display/NavigationButtonNode.swift index f69a5b3f30..5718ab9cbd 100644 --- a/submodules/Display/Display/NavigationButtonNode.swift +++ b/submodules/Display/Display/NavigationButtonNode.swift @@ -10,10 +10,10 @@ private final class NavigationButtonItemNode: ASTextNode { return self.bold ? UIFont.boldSystemFont(ofSize: 17.0) : UIFont.systemFont(ofSize: 17.0) } - private func attributesForCurrentState() -> [NSAttributedStringKey : AnyObject] { + private func attributesForCurrentState() -> [NSAttributedString.Key: AnyObject] { return [ - NSAttributedStringKey.font: self.fontForCurrentState(), - NSAttributedStringKey.foregroundColor: self.isEnabled ? self.color : self.disabledColor + NSAttributedString.Key.font: self.fontForCurrentState(), + NSAttributedString.Key.foregroundColor: self.isEnabled ? self.color : self.disabledColor ] } @@ -144,7 +144,7 @@ private final class NavigationButtonItemNode: ASTextNode { self.hitTestSlop = UIEdgeInsets(top: -16.0, left: -10.0, bottom: -16.0, right: -10.0) self.displaysAsynchronously = false - self.accessibilityTraits = UIAccessibilityTraitButton + self.accessibilityTraits = .button } func updateLayout(_ constrainedSize: CGSize) -> CGSize { diff --git a/submodules/Display/Display/NavigationController.swift b/submodules/Display/Display/NavigationController.swift index 31e57e4815..732c039de4 100644 --- a/submodules/Display/Display/NavigationController.swift +++ b/submodules/Display/Display/NavigationController.swift @@ -296,7 +296,7 @@ open class NavigationController: UINavigationController, ContainableController, self.controllerView.addSubview(self.controllerView.separatorView) } - let navigationBackgroundFrame = CGRect(origin: CGPoint(x: masterData.0.maxX, y: 0.0), size: CGSize(width: lastControllerFrameAndLayout.0.width, height: (layout.statusBarHeight ?? 0.0) + 44.0)) + //let navigationBackgroundFrame = CGRect(origin: CGPoint(x: masterData.0.maxX, y: 0.0), size: CGSize(width: lastControllerFrameAndLayout.0.width, height: (layout.statusBarHeight ?? 0.0) + 44.0)) if let backgroundDetailsMode = self.backgroundDetailsMode { @@ -363,7 +363,7 @@ open class NavigationController: UINavigationController, ContainableController, } } - if let emptyDetailView = self.controllerView.emptyDetailView { + if let _ = self.controllerView.emptyDetailView { // transition.updateFrame(view: navigationBackgroundView, frame: navigationBackgroundFrame) // transition.updateFrame(view: navigationSeparatorView, frame: CGRect(origin: CGPoint(x: navigationBackgroundFrame.minX, y: navigationBackgroundFrame.maxY), size: CGSize(width: navigationBackgroundFrame.width, height: UIScreenPixel))) // if let image = emptyDetailView.image { @@ -796,7 +796,7 @@ open class NavigationController: UINavigationController, ContainableController, @objc func panGesture(_ recognizer: UIPanGestureRecognizer) { switch recognizer.state { - case UIGestureRecognizerState.began: + case .began: guard let layout = self.validLayout else { return } @@ -857,14 +857,14 @@ open class NavigationController: UINavigationController, ContainableController, } self.navigationTransitionCoordinator = navigationTransitionCoordinator } - case UIGestureRecognizerState.changed: + case .changed: if let navigationTransitionCoordinator = self.navigationTransitionCoordinator, !navigationTransitionCoordinator.animatingCompletion { let translation = recognizer.translation(in: self.view).x let progress = max(0.0, min(1.0, translation / self.view.frame.width)) navigationTransitionCoordinator.progress = progress } - case UIGestureRecognizerState.ended: + case .ended: if let navigationTransitionCoordinator = self.navigationTransitionCoordinator, !navigationTransitionCoordinator.animatingCompletion { let velocity = recognizer.velocity(in: self.view).x @@ -1205,7 +1205,7 @@ open class NavigationController: UINavigationController, ContainableController, if flag { controller.view.frame = strongSelf.view.bounds.offsetBy(dx: 0.0, dy: strongSelf.view.bounds.height) strongSelf.view.addSubview(controller.view) - UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions(rawValue: 7 << 16), animations: { + UIView.animate(withDuration: 0.3, delay: 0.0, options: UIView.AnimationOptions(rawValue: 7 << 16), animations: { controller.view.frame = strongSelf.view.bounds }, completion: { _ in if let completion = completion { @@ -1230,7 +1230,7 @@ open class NavigationController: UINavigationController, ContainableController, override open func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { if let controller = self.presentedViewController { if flag { - UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions(rawValue: 7 << 16), animations: { + UIView.animate(withDuration: 0.3, delay: 0.0, options: UIView.AnimationOptions(rawValue: 7 << 16), animations: { controller.view.frame = self.view.bounds.offsetBy(dx: 0.0, dy: self.view.bounds.height) }, completion: { _ in controller.view.removeFromSuperview() diff --git a/submodules/Display/Display/NavigationTitleNode.swift b/submodules/Display/Display/NavigationTitleNode.swift index 5ef72daed8..458bc461ff 100644 --- a/submodules/Display/Display/NavigationTitleNode.swift +++ b/submodules/Display/Display/NavigationTitleNode.swift @@ -39,9 +39,9 @@ public class NavigationTitleNode: ASDisplayNode { } private func setText(_ text: NSString) { - var titleAttributes = [NSAttributedStringKey : AnyObject]() - titleAttributes[NSAttributedStringKey.font] = UIFont.boldSystemFont(ofSize: 17.0) - titleAttributes[NSAttributedStringKey.foregroundColor] = self.color + var titleAttributes = [NSAttributedString.Key : AnyObject]() + titleAttributes[NSAttributedString.Key.font] = UIFont.boldSystemFont(ofSize: 17.0) + titleAttributes[NSAttributedString.Key.foregroundColor] = self.color let titleString = NSAttributedString(string: text as String, attributes: titleAttributes) self.label.attributedText = titleString self.invalidateCalculatedLayout() diff --git a/submodules/Display/Display/NavigationTransitionCoordinator.swift b/submodules/Display/Display/NavigationTransitionCoordinator.swift index 055c9564cd..6254c7defe 100644 --- a/submodules/Display/Display/NavigationTransitionCoordinator.swift +++ b/submodules/Display/Display/NavigationTransitionCoordinator.swift @@ -155,7 +155,7 @@ class NavigationTransitionCoordinator { func animateCancel(_ completion: @escaping () -> ()) { self.currentCompletion = completion - UIView.animate(withDuration: 0.1, delay: 0.0, options: UIViewAnimationOptions(), animations: { () -> Void in + UIView.animate(withDuration: 0.1, delay: 0.0, options: UIView.AnimationOptions(), animations: { () -> Void in self.progress = 0.0 }) { (completed) -> Void in switch self.transition { @@ -235,13 +235,13 @@ class NavigationTransitionCoordinator { } if abs(velocity) < CGFloat.ulpOfOne && abs(self.progress) < CGFloat.ulpOfOne { - UIView.animate(withDuration: 0.5, delay: 0.0, options: UIViewAnimationOptions(rawValue: 7 << 16), animations: { + UIView.animate(withDuration: 0.5, delay: 0.0, options: UIView.AnimationOptions(rawValue: 7 << 16), animations: { self.progress = 1.0 }, completion: { _ in f() }) } else { - UIView.animate(withDuration: Double(max(0.05, min(0.2, abs(distance / velocity)))), delay: 0.0, options: UIViewAnimationOptions(), animations: { () -> Void in + UIView.animate(withDuration: Double(max(0.05, min(0.2, abs(distance / velocity)))), delay: 0.0, options:UIView.AnimationOptions(), animations: { () -> Void in self.progress = 1.0 }) { (completed) -> Void in f() diff --git a/submodules/Display/Display/PeekControllerMenuItemNode.swift b/submodules/Display/Display/PeekControllerMenuItemNode.swift index 9bde87731c..5d4890b1da 100644 --- a/submodules/Display/Display/PeekControllerMenuItemNode.swift +++ b/submodules/Display/Display/PeekControllerMenuItemNode.swift @@ -76,7 +76,7 @@ final class PeekControllerMenuItemNode: HighlightTrackingButtonNode { self.highligthedChanged = { [weak self] highlighted in if let strongSelf = self { if highlighted { - strongSelf.view.superview?.bringSubview(toFront: strongSelf.view) + strongSelf.view.superview?.bringSubviewToFront(strongSelf.view) strongSelf.highlightedBackgroundNode.alpha = 1.0 } else { strongSelf.highlightedBackgroundNode.alpha = 0.0 diff --git a/submodules/Display/Display/PeekControllerNode.swift b/submodules/Display/Display/PeekControllerNode.swift index 89c65cbaeb..9b80c23a40 100644 --- a/submodules/Display/Display/PeekControllerNode.swift +++ b/submodules/Display/Display/PeekControllerNode.swift @@ -220,14 +220,14 @@ final class PeekControllerNode: ViewControllerTracingNode { self.blurView.layer.animateAlpha(from: self.blurView.alpha, to: 0.0, duration: 0.25, removeOnCompletion: false) let offset = CGPoint(x: rect.midX - self.containerNode.position.x, y: rect.midY - self.containerNode.position.y) - self.containerNode.layer.animatePosition(from: CGPoint(), to: offset, duration: 0.25, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, additive: true, force: true, completion: { _ in + self.containerNode.layer.animatePosition(from: CGPoint(), to: offset, duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, force: true, completion: { _ in completion() }) self.containerNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false) self.containerNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.25, removeOnCompletion: false) if let topAccessoryNode = self.topAccessoryNode { - topAccessoryNode.layer.animatePosition(from: CGPoint(), to: offset, duration: 0.25, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, additive: true, force: true, completion: { _ in + topAccessoryNode.layer.animatePosition(from: CGPoint(), to: offset, duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, force: true, completion: { _ in completion() }) topAccessoryNode.layer.animateAlpha(from: topAccessoryNode.alpha, to: 0.0, duration: 0.2, removeOnCompletion: false) @@ -235,7 +235,7 @@ final class PeekControllerNode: ViewControllerTracingNode { } if let menuNode = self.menuNode { - menuNode.layer.animatePosition(from: menuNode.position, to: CGPoint(x: menuNode.position.x, y: self.bounds.size.height + menuNode.bounds.size.height / 2.0), duration: 0.25, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false) + menuNode.layer.animatePosition(from: menuNode.position, to: CGPoint(x: menuNode.position.x, y: self.bounds.size.height + menuNode.bounds.size.height / 2.0), duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false) } } diff --git a/submodules/Display/Display/PresentationContext.swift b/submodules/Display/Display/PresentationContext.swift index 9a8367a7bc..6421425520 100644 --- a/submodules/Display/Display/PresentationContext.swift +++ b/submodules/Display/Display/PresentationContext.swift @@ -307,7 +307,7 @@ public final class PresentationContext { } private func notifyAccessibilityScreenChanged() { - UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil) + UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: nil) } func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { diff --git a/submodules/Display/Display/StatusBar.swift b/submodules/Display/Display/StatusBar.swift index 31da12342b..7fa7814950 100644 --- a/submodules/Display/Display/StatusBar.swift +++ b/submodules/Display/Display/StatusBar.swift @@ -178,14 +178,14 @@ public final class StatusBar: ASDisplayNode { self.inCallBackgroundNode.layer.backgroundColor = inCallBackgroundColor.cgColor if animated { - self.inCallBackgroundNode.layer.animate(from: UIColor.clear.cgColor, to: inCallBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.3) + self.inCallBackgroundNode.layer.animate(from: UIColor.clear.cgColor, to: inCallBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.3) } } else { self.inCallLabel.removeFromSupernode() self.inCallBackgroundNode.layer.backgroundColor = UIColor.clear.cgColor if animated { - self.inCallBackgroundNode.layer.animate(from: inCallBackgroundColor.cgColor, to: UIColor.clear.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.3) + self.inCallBackgroundNode.layer.animate(from: inCallBackgroundColor.cgColor, to: UIColor.clear.cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.3) } } } diff --git a/submodules/Display/Display/StatusBarManager.swift b/submodules/Display/Display/StatusBarManager.swift index 3aee140873..b051951bfd 100644 --- a/submodules/Display/Display/StatusBarManager.swift +++ b/submodules/Display/Display/StatusBarManager.swift @@ -61,7 +61,7 @@ private func displayHiddenAnimation() -> CAAnimation { let animation = CABasicAnimation(keyPath: "transform.translation.y") animation.fromValue = NSNumber(value: Float(-40.0)) animation.toValue = NSNumber(value: Float(-40.0)) - animation.fillMode = kCAFillModeBoth + animation.fillMode = .both animation.duration = 1.0 animation.speed = 0.0 animation.isAdditive = true diff --git a/submodules/Display/Display/StatusBarProxyNode.swift b/submodules/Display/Display/StatusBarProxyNode.swift index ab1b02f81c..82472121ce 100644 --- a/submodules/Display/Display/StatusBarProxyNode.swift +++ b/submodules/Display/Display/StatusBarProxyNode.swift @@ -126,7 +126,7 @@ private class StatusBarItemNode: ASDisplayNode { formatter?.locale = Locale.current if let string = formatter?.string(from: Date()) { - let attributedString = NSAttributedString(string: string, attributes: [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 12.0), NSAttributedStringKey.foregroundColor: color]) + let attributedString = NSAttributedString(string: string, attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 12.0), NSAttributedString.Key.foregroundColor: color]) let line = CTLineCreateWithAttributedString(attributedString) @@ -482,7 +482,7 @@ class StatusBarProxyNode: ASDisplayNode { self.timer = Timer(timeInterval: 5.0, target: StatusBarProxyNodeTimerTarget { [weak self] in self?.updateItems() }, selector: #selector(StatusBarProxyNodeTimerTarget.tick), userInfo: nil, repeats: true) - RunLoop.main.add(self.timer!, forMode: .commonModes) + RunLoop.main.add(self.timer!, forMode: .common) } else { self.timer?.invalidate() self.timer = nil diff --git a/submodules/Display/Display/TabBarController.swift b/submodules/Display/Display/TabBarController.swift index c46eb45d07..feacc20ef5 100644 --- a/submodules/Display/Display/TabBarController.swift +++ b/submodules/Display/Display/TabBarController.swift @@ -233,10 +233,10 @@ open class TabBarController: ViewController { self.tabBarControllerNode.tabBarNode.selectedIndex = self.selectedIndex if let currentController = self.currentController { - currentController.willMove(toParentViewController: nil) + currentController.willMove(toParent: nil) self.tabBarControllerNode.currentControllerNode = nil - currentController.removeFromParentViewController() - currentController.didMove(toParentViewController: nil) + currentController.removeFromParent() + currentController.didMove(toParent: nil) self.currentController = nil } @@ -247,11 +247,11 @@ open class TabBarController: ViewController { var displayNavigationBar = false if let currentController = self.currentController { - currentController.willMove(toParentViewController: self) + currentController.willMove(toParent: self) self.tabBarControllerNode.currentControllerNode = currentController.displayNode currentController.navigationBar?.isHidden = true - self.addChildViewController(currentController) - currentController.didMove(toParentViewController: self) + self.addChild(currentController) + currentController.didMove(toParent: self) currentController.navigationBar?.layoutSuspended = true currentController.navigationItem.setTarget(self.navigationItem) diff --git a/submodules/Display/Display/TabBarNode.swift b/submodules/Display/Display/TabBarNode.swift index 1e112e5baf..9e2f37fda4 100644 --- a/submodules/Display/Display/TabBarNode.swift +++ b/submodules/Display/Display/TabBarNode.swift @@ -10,7 +10,7 @@ import DisplayPrivate private let separatorHeight: CGFloat = 1.0 / UIScreen.main.scale private func tabBarItemImage(_ image: UIImage?, title: String, backgroundColor: UIColor, tintColor: UIColor, horizontal: Bool, imageMode: Bool) -> (UIImage, CGFloat) { let font = horizontal ? Font.regular(13.0) : Font.medium(10.0) - let titleSize = (title as NSString).boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin], attributes: [NSAttributedStringKey.font: font], context: nil).size + let titleSize = (title as NSString).boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin], attributes: [NSAttributedString.Key.font: font], context: nil).size let imageSize: CGSize if let image = image { @@ -76,9 +76,9 @@ private func tabBarItemImage(_ image: UIImage?, title: String, backgroundColor: if !imageMode { if horizontal { - (title as NSString).draw(at: CGPoint(x: imageSize.width + horizontalSpacing, y: floor((size.height - titleSize.height) / 2.0) - 2.0), withAttributes: [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: tintColor]) + (title as NSString).draw(at: CGPoint(x: imageSize.width + horizontalSpacing, y: floor((size.height - titleSize.height) / 2.0) - 2.0), withAttributes: [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: tintColor]) } else { - (title as NSString).draw(at: CGPoint(x: floorToScreenPixels((size.width - titleSize.width) / 2.0), y: size.height - titleSize.height - 2.0), withAttributes: [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: tintColor]) + (title as NSString).draw(at: CGPoint(x: floorToScreenPixels((size.width - titleSize.width) / 2.0), y: size.height - titleSize.height - 2.0), withAttributes: [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: tintColor]) } } @@ -143,7 +143,7 @@ private final class TabBarNodeContainer { self.imageNode = imageNode self.imageNode.isAccessibilityElement = true - self.imageNode.accessibilityTraits = UIAccessibilityTraitButton + self.imageNode.accessibilityTraits = .button self.badgeContainerNode = ASDisplayNode() self.badgeContainerNode.isUserInteractionEnabled = false diff --git a/submodules/Display/Display/TapLongTapOrDoubleTapGestureRecognizer.swift b/submodules/Display/Display/TapLongTapOrDoubleTapGestureRecognizer.swift index 8f6771b93f..5e4b78bea3 100644 --- a/submodules/Display/Display/TapLongTapOrDoubleTapGestureRecognizer.swift +++ b/submodules/Display/Display/TapLongTapOrDoubleTapGestureRecognizer.swift @@ -24,14 +24,14 @@ private class TapLongTapOrDoubleTapGestureRecognizerTimerTarget: NSObject { } } -enum TapLongTapOrDoubleTapGesture { +public enum TapLongTapOrDoubleTapGesture { case tap case doubleTap case longTap case hold } -enum TapLongTapOrDoubleTapGestureRecognizerAction { +public enum TapLongTapOrDoubleTapGestureRecognizerAction { case waitForDoubleTap case waitForSingleTap case waitForHold(timeout: Double, acceptTap: Bool) @@ -44,12 +44,12 @@ public final class TapLongTapOrDoubleTapGestureRecognizer: UIGestureRecognizer, private var tapCount: Int = 0 private var timer: Foundation.Timer? - private(set) var lastRecognizedGestureAndLocation: (TapLongTapOrDoubleTapGesture, CGPoint)? + public private(set) var lastRecognizedGestureAndLocation: (TapLongTapOrDoubleTapGesture, CGPoint)? - var tapActionAtPoint: ((CGPoint) -> TapLongTapOrDoubleTapGestureRecognizerAction)? - var highlight: ((CGPoint?) -> Void)? + public var tapActionAtPoint: ((CGPoint) -> TapLongTapOrDoubleTapGestureRecognizerAction)? + public var highlight: ((CGPoint?) -> Void)? - var hapticFeedback: HapticFeedback? + public var hapticFeedback: HapticFeedback? private var highlightPoint: CGPoint? @@ -156,13 +156,13 @@ public final class TapLongTapOrDoubleTapGestureRecognizer: UIGestureRecognizer, self.timer?.invalidate() let timer = Timer(timeInterval: 0.3, target: TapLongTapOrDoubleTapGestureRecognizerTimerTarget(target: self), selector: #selector(TapLongTapOrDoubleTapGestureRecognizerTimerTarget.longTapEvent), userInfo: nil, repeats: false) self.timer = timer - RunLoop.main.add(timer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(timer, forMode: .common) case let .waitForHold(timeout, _): self.hapticFeedback = HapticFeedback() self.hapticFeedback?.prepareTap() let timer = Timer(timeInterval: timeout, target: TapLongTapOrDoubleTapGestureRecognizerTimerTarget(target: self), selector: #selector(TapLongTapOrDoubleTapGestureRecognizerTimerTarget.holdEvent), userInfo: nil, repeats: false) self.timer = timer - RunLoop.main.add(timer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(timer, forMode: .common) case .fail: self.state = .failed } @@ -227,7 +227,7 @@ public final class TapLongTapOrDoubleTapGestureRecognizer: UIGestureRecognizer, self.state = .began let timer = Timer(timeInterval: 0.2, target: TapLongTapOrDoubleTapGestureRecognizerTimerTarget(target: self), selector: #selector(TapLongTapOrDoubleTapGestureRecognizerTimerTarget.tapEvent), userInfo: nil, repeats: false) self.timer = timer - RunLoop.main.add(timer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(timer, forMode: .common) case let .waitForHold(_, acceptTap): if let (touchLocation, _) = self.touchLocationAndTimestamp, acceptTap { if self.state != .began { diff --git a/submodules/Display/Display/TextAlertController.swift b/submodules/Display/Display/TextAlertController.swift index 7b4d6cc62a..6e9628db98 100644 --- a/submodules/Display/Display/TextAlertController.swift +++ b/submodules/Display/Display/TextAlertController.swift @@ -124,7 +124,7 @@ public final class TextAlertContentNode: AlertContentNode { private var validLayout: CGSize? - public var textAttributeAction: (NSAttributedStringKey, (Any) -> Void)? { + public var textAttributeAction: (NSAttributedString.Key, (Any) -> Void)? { didSet { if let (attribute, textAttributeAction) = self.textAttributeAction { self.textNode.highlightAttributeAction = { attributes in @@ -218,12 +218,12 @@ public final class TextAlertContentNode: AlertContentNode { if let titleNode = self.titleNode, let attributedText = titleNode.attributedText { let updatedText = NSMutableAttributedString(attributedString: attributedText) - updatedText.addAttribute(NSAttributedStringKey.foregroundColor, value: theme.primaryColor, range: NSRange(location: 0, length: updatedText.length)) + updatedText.addAttribute(NSAttributedString.Key.foregroundColor, value: theme.primaryColor, range: NSRange(location: 0, length: updatedText.length)) titleNode.attributedText = updatedText } if let attributedText = self.textNode.attributedText { let updatedText = NSMutableAttributedString(attributedString: attributedText) - updatedText.addAttribute(NSAttributedStringKey.foregroundColor, value: theme.primaryColor, range: NSRange(location: 0, length: updatedText.length)) + updatedText.addAttribute(NSAttributedString.Key.foregroundColor, value: theme.primaryColor, range: NSRange(location: 0, length: updatedText.length)) self.textNode.attributedText = updatedText } diff --git a/submodules/Display/Display/TextNode.swift b/submodules/Display/Display/TextNode.swift index a00c22c472..cf44a8e18c 100644 --- a/submodules/Display/Display/TextNode.swift +++ b/submodules/Display/Display/TextNode.swift @@ -206,7 +206,7 @@ public final class TextNodeLayout: NSObject { } } - public func attributesAtPoint(_ point: CGPoint) -> (Int, [NSAttributedStringKey: Any])? { + public func attributesAtPoint(_ point: CGPoint) -> (Int, [NSAttributedString.Key: Any])? { if let attributedString = self.attributedString { let transformedPoint = CGPoint(x: point.x - self.insets.left, y: point.y - self.insets.top) var lineIndex = -1 @@ -336,7 +336,7 @@ public final class TextNodeLayout: NSObject { public func attributeSubstring(name: String, index: Int) -> String? { if let attributedString = self.attributedString { var range = NSRange() - let _ = attributedString.attribute(NSAttributedStringKey(rawValue: name), at: index, effectiveRange: &range) + let _ = attributedString.attribute(NSAttributedString.Key(rawValue: name), at: index, effectiveRange: &range) if range.length != 0 { return (attributedString.string as NSString).substring(with: range) } @@ -349,7 +349,7 @@ public final class TextNodeLayout: NSObject { return [] } var result: [(Any, CGRect)] = [] - attributedString.enumerateAttribute(NSAttributedStringKey(rawValue: name), in: NSRange(location: 0, length: attributedString.length), options: []) { (value, range, _) in + attributedString.enumerateAttribute(NSAttributedString.Key(rawValue: name), in: NSRange(location: 0, length: attributedString.length), options: []) { (value, range, _) in if let value = value, range.length != 0 { var coveringRect = CGRect() for line in self.lines { @@ -390,7 +390,7 @@ public final class TextNodeLayout: NSObject { public func lineAndAttributeRects(name: String, at index: Int) -> [(CGRect, CGRect)]? { if let attributedString = self.attributedString { var range = NSRange() - let _ = attributedString.attribute(NSAttributedStringKey(rawValue: name), at: index, effectiveRange: &range) + let _ = attributedString.attribute(NSAttributedString.Key(rawValue: name), at: index, effectiveRange: &range) if range.length != 0 { var rects: [(CGRect, CGRect)] = [] for line in self.lines { @@ -468,7 +468,7 @@ private final class TextAccessibilityOverlayNodeView: UIView { let element = AccessibilityAreaNode() element.accessibilityLabel = value as? String ?? "" element.frame = rect - element.accessibilityTraits = UIAccessibilityTraitLink + element.accessibilityTraits = .link element.activate = { [weak self] in self?.openUrl(value as? String ?? "") return true @@ -543,7 +543,7 @@ public class TextNode: ASDisplayNode { self.clipsToBounds = false } - public func attributesAtPoint(_ point: CGPoint) -> (Int, [NSAttributedStringKey: Any])? { + public func attributesAtPoint(_ point: CGPoint) -> (Int, [NSAttributedString.Key: Any])? { if let cachedLayout = self.cachedLayout { return cachedLayout.attributesAtPoint(point) } else { @@ -581,7 +581,7 @@ public class TextNode: ASDisplayNode { let font: CTFont if stringLength != 0 { - if let stringFont = attributedString.attribute(NSAttributedStringKey.font, at: 0, effectiveRange: nil) { + if let stringFont = attributedString.attribute(NSAttributedString.Key.font, at: 0, effectiveRange: nil) { font = stringFont as! CTFont } else { font = defaultFont @@ -686,9 +686,9 @@ public class TextNode: ASDisplayNode { if CTLineGetTypographicBounds(originalLine, nil, nil, nil) - CTLineGetTrailingWhitespaceWidth(originalLine) < Double(constrainedSize.width) { coreTextLine = originalLine } else { - var truncationTokenAttributes: [NSAttributedStringKey : AnyObject] = [:] - truncationTokenAttributes[NSAttributedStringKey.font] = font - truncationTokenAttributes[NSAttributedStringKey(rawValue: kCTForegroundColorFromContextAttributeName as String)] = true as NSNumber + var truncationTokenAttributes: [NSAttributedString.Key : AnyObject] = [:] + truncationTokenAttributes[NSAttributedString.Key.font] = font + truncationTokenAttributes[NSAttributedString.Key(rawValue: kCTForegroundColorFromContextAttributeName as String)] = true as NSNumber let tokenString = "\u{2026}" let truncatedTokenString = NSAttributedString(string: tokenString, attributes: truncationTokenAttributes) let truncationToken = CTLineCreateWithAttributedString(truncatedTokenString) @@ -699,12 +699,12 @@ public class TextNode: ASDisplayNode { var headIndent: CGFloat = 0.0 attributedString.enumerateAttributes(in: NSMakeRange(lineRange.location, lineRange.length), options: []) { attributes, range, _ in - if let _ = attributes[NSAttributedStringKey.strikethroughStyle] { + if let _ = attributes[NSAttributedString.Key.strikethroughStyle] { let lowerX = floor(CTLineGetOffsetForStringIndex(coreTextLine, range.location, nil)) let upperX = ceil(CTLineGetOffsetForStringIndex(coreTextLine, range.location + range.length, nil)) let x = lowerX < upperX ? lowerX : upperX strikethroughs.append(TextNodeStrikethrough(frame: CGRect(x: x, y: 0.0, width: abs(upperX - lowerX), height: fontLineHeight))) - } else if let paragraphStyle = attributes[NSAttributedStringKey.paragraphStyle] as? NSParagraphStyle { + } else if let paragraphStyle = attributes[NSAttributedString.Key.paragraphStyle] as? NSParagraphStyle { headIndent = paragraphStyle.headIndent } @@ -744,12 +744,12 @@ public class TextNode: ASDisplayNode { var headIndent: CGFloat = 0.0 attributedString.enumerateAttributes(in: NSMakeRange(lineRange.location, lineRange.length), options: []) { attributes, range, _ in - if let _ = attributes[NSAttributedStringKey.strikethroughStyle] { + if let _ = attributes[NSAttributedString.Key.strikethroughStyle] { let lowerX = floor(CTLineGetOffsetForStringIndex(coreTextLine, range.location, nil)) let upperX = ceil(CTLineGetOffsetForStringIndex(coreTextLine, range.location + range.length, nil)) let x = lowerX < upperX ? lowerX : upperX strikethroughs.append(TextNodeStrikethrough(frame: CGRect(x: x, y: 0.0, width: abs(upperX - lowerX), height: fontLineHeight))) - } else if let paragraphStyle = attributes[NSAttributedStringKey.paragraphStyle] as? NSParagraphStyle { + } else if let paragraphStyle = attributes[NSAttributedString.Key.paragraphStyle] as? NSParagraphStyle { headIndent = paragraphStyle.headIndent } } diff --git a/submodules/Display/Display/UITracingLayerView.swift b/submodules/Display/Display/UITracingLayerView.swift index 7834962799..4949f056b9 100644 --- a/submodules/Display/Display/UITracingLayerView.swift +++ b/submodules/Display/Display/UITracingLayerView.swift @@ -14,7 +14,7 @@ open class UITracingLayerView: UIView { self.setNeedsLayout() } - override open var autoresizingMask: UIViewAutoresizing { + override open var autoresizingMask: UIView.AutoresizingMask { get { return [] } set(value) { diff --git a/submodules/Display/Display/UniversalTapRecognizer.swift b/submodules/Display/Display/UniversalTapRecognizer.swift index a98268147b..7e01fa0835 100644 --- a/submodules/Display/Display/UniversalTapRecognizer.swift +++ b/submodules/Display/Display/UniversalTapRecognizer.swift @@ -39,6 +39,6 @@ class UniversalTapRecognizer: UITapGestureRecognizer { } }), selector: #selector(TimerTargetWrapper.timerEvent), userInfo: nil, repeats: false) self.timer = timer - RunLoop.main.add(timer, forMode: .commonModes) + RunLoop.main.add(timer, forMode: .common) } } diff --git a/submodules/Display/Display/ViewController.swift b/submodules/Display/Display/ViewController.swift index 6c465231de..3d7dc74efb 100644 --- a/submodules/Display/Display/ViewController.swift +++ b/submodules/Display/Display/ViewController.swift @@ -109,7 +109,7 @@ open class ViewControllerPresentationArguments { } } - override open func prefersHomeIndicatorAutoHidden() -> Bool { + override open var prefersHomeIndicatorAutoHidden: Bool { return self.preferNavigationUIHidden } diff --git a/submodules/Display/Display/WindowContent.swift b/submodules/Display/Display/WindowContent.swift index 724128f6bc..3adce10dbf 100644 --- a/submodules/Display/Display/WindowContent.swift +++ b/submodules/Display/Display/WindowContent.swift @@ -446,9 +446,9 @@ public class Window1 { self.presentationContext.containerLayoutUpdated(containedLayoutForWindowLayout(self.windowLayout, hasOnScreenNavigation: self.hostView.hasOnScreenNavigation), transition: .immediate) self.overlayPresentationContext.containerLayoutUpdated(containedLayoutForWindowLayout(self.windowLayout, hasOnScreenNavigation: self.hostView.hasOnScreenNavigation), transition: .immediate) - self.statusBarChangeObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationWillChangeStatusBarFrame, object: nil, queue: OperationQueue.main, using: { [weak self] notification in + self.statusBarChangeObserver = NotificationCenter.default.addObserver(forName: UIApplication.willChangeStatusBarFrameNotification, object: nil, queue: OperationQueue.main, using: { [weak self] notification in if let strongSelf = self { - let statusBarHeight: CGFloat = max(20.0, (notification.userInfo?[UIApplicationStatusBarFrameUserInfoKey] as? NSValue)?.cgRectValue.height ?? 20.0) + let statusBarHeight: CGFloat = max(20.0, (notification.userInfo?[UIApplication.statusBarFrameUserInfoKey] as? NSValue)?.cgRectValue.height ?? 20.0) let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .easeInOut) strongSelf.updateLayout { $0.update(statusBarHeight: statusBarHeight, transition: transition, overrideTransition: false) } @@ -460,11 +460,11 @@ public class Window1 { return } let keyboardHeight = max(0.0, strongSelf.keyboardManager?.getCurrentKeyboardHeight() ?? 0.0) - var duration: Double = (notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.0 + var duration: Double = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.0 if duration > Double.ulpOfOne { duration = 0.5 } - let curve: UInt = (notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue ?? 7 + let curve: UInt = (notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue ?? 7 let transitionCurve: ContainedViewLayoutTransitionCurve if curve == 7 { @@ -477,9 +477,9 @@ public class Window1 { } }) - self.keyboardFrameChangeObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil, queue: nil, using: { [weak self] notification in + self.keyboardFrameChangeObserver = NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillChangeFrameNotification, object: nil, queue: nil, using: { [weak self] notification in if let strongSelf = self { - let keyboardFrame: CGRect = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue ?? CGRect() + let keyboardFrame: CGRect = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue ?? CGRect() let screenHeight: CGFloat @@ -494,11 +494,11 @@ public class Window1 { } let keyboardHeight = max(0.0, screenHeight - keyboardFrame.minY) - var duration: Double = (notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.0 + var duration: Double = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.0 if duration > Double.ulpOfOne { duration = 0.5 } - let curve: UInt = (notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue ?? 7 + let curve: UInt = (notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue ?? 7 let transitionCurve: ContainedViewLayoutTransitionCurve if curve == 7 { @@ -512,7 +512,7 @@ public class Window1 { }) if #available(iOSApplicationExtension 11.0, *) { - self.keyboardTypeChangeObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.UITextInputCurrentInputModeDidChange, object: nil, queue: OperationQueue.main, using: { [weak self] notification in + self.keyboardTypeChangeObserver = NotificationCenter.default.addObserver(forName: UITextInputMode.currentInputModeDidChangeNotification, object: nil, queue: OperationQueue.main, using: { [weak self] notification in if let strongSelf = self, let initialInputHeight = strongSelf.windowLayout.inputHeight, let firstResponder = getFirstResponderAndAccessoryHeight(strongSelf.hostView.eventView).0 { if firstResponder.textInputMode?.primaryLanguage != nil { return @@ -540,7 +540,7 @@ public class Window1 { } if #available(iOSApplicationExtension 11.0, *) { - self.voiceOverStatusObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIAccessibilityVoiceOverStatusDidChange, object: nil, queue: OperationQueue.main, using: { [weak self] _ in + self.voiceOverStatusObserver = NotificationCenter.default.addObserver(forName: UIAccessibility.voiceOverStatusDidChangeNotification, object: nil, queue: OperationQueue.main, using: { [weak self] _ in if let strongSelf = self { strongSelf.updateLayout { $0.update(inVoiceOver: UIAccessibility.isVoiceOverRunning) } } diff --git a/submodules/Display/Display_Xcode.xcodeproj/project.pbxproj b/submodules/Display/Display_Xcode.xcodeproj/project.pbxproj index b7dae52ecb..2cf93d5eda 100644 --- a/submodules/Display/Display_Xcode.xcodeproj/project.pbxproj +++ b/submodules/Display/Display_Xcode.xcodeproj/project.pbxproj @@ -102,6 +102,7 @@ D05CC3251B695B0700E235A3 /* NavigationBarProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = D05CC3231B695B0700E235A3 /* NavigationBarProxy.m */; }; D05CC3271B69725400E235A3 /* NavigationBackArrowLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D05CC3261B69725400E235A3 /* NavigationBackArrowLight@2x.png */; }; D05CC3291B69750D00E235A3 /* InteractiveTransitionGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05CC3281B69750D00E235A3 /* InteractiveTransitionGestureRecognizer.swift */; }; + D060185F22F35E7400796784 /* ShakeAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060185E22F35E7400796784 /* ShakeAnimation.swift */; }; D06B76DB20592A97006E9EEA /* LayoutSizes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06B76DA20592A97006E9EEA /* LayoutSizes.swift */; }; D06D37A220779C82009219B6 /* VolumeControlStatusBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06D37A120779C82009219B6 /* VolumeControlStatusBar.swift */; }; D06EE8451B7140FF00837186 /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06EE8441B7140FF00837186 /* Font.swift */; }; @@ -281,6 +282,7 @@ D05CC3231B695B0700E235A3 /* NavigationBarProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NavigationBarProxy.m; sourceTree = ""; }; D05CC3261B69725400E235A3 /* NavigationBackArrowLight@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "NavigationBackArrowLight@2x.png"; sourceTree = ""; }; D05CC3281B69750D00E235A3 /* InteractiveTransitionGestureRecognizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InteractiveTransitionGestureRecognizer.swift; sourceTree = ""; }; + D060185E22F35E7400796784 /* ShakeAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShakeAnimation.swift; sourceTree = ""; }; D06B76DA20592A97006E9EEA /* LayoutSizes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutSizes.swift; sourceTree = ""; }; D06D37A120779C82009219B6 /* VolumeControlStatusBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumeControlStatusBar.swift; sourceTree = ""; }; D06EE8441B7140FF00837186 /* Font.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Font.swift; sourceTree = ""; }; @@ -586,6 +588,7 @@ D05CC3001B6955D500E235A3 /* Utils */ = { isa = PBXGroup; children = ( + D060185E22F35E7400796784 /* ShakeAnimation.swift */, D0750C7522B2934800BE5F6E /* ImageNode.swift */, D0750C7222B2931900BE5F6E /* TransformImageArguments.swift */, D0750C7122B2931900BE5F6E /* TransformImageNode.swift */, @@ -985,6 +988,7 @@ D03AA4DD202DB1840056C405 /* PeekControllerGestureRecognizer.swift in Sources */, D007019A2029CAE2006B9E34 /* TooltipControllerNode.swift in Sources */, D05CC3291B69750D00E235A3 /* InteractiveTransitionGestureRecognizer.swift in Sources */, + D060185F22F35E7400796784 /* ShakeAnimation.swift in Sources */, D077B8E91F4637040046D27A /* NavigationBarBadge.swift in Sources */, D0CE67921F7DA11700FFB557 /* ActionSheetTheme.swift in Sources */, D0A134642034DE580059716A /* TabBarTapRecognizer.swift in Sources */, @@ -1108,7 +1112,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = DebugFork; }; @@ -1240,7 +1244,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = DebugHockeyapp; }; @@ -1269,7 +1273,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = ReleaseHockeyapp; }; @@ -1370,7 +1374,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = DebugAppStore; }; @@ -1452,7 +1456,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = ReleaseAppStore; }; @@ -1534,7 +1538,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = ReleaseHockeyappInternal; }; @@ -1624,7 +1628,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = DebugAppStoreLLC; }; @@ -1706,7 +1710,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = ReleaseAppStoreLLC; }; From 49777d8834552e4b6ec427bfb8a1ba2e98db777e Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:16:04 +0300 Subject: [PATCH 28/41] Move ShakeAnimation to Display --- .../TelegramUI => Display/Display}/ShakeAnimation.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename submodules/{TelegramUI/TelegramUI => Display/Display}/ShakeAnimation.swift (89%) diff --git a/submodules/TelegramUI/TelegramUI/ShakeAnimation.swift b/submodules/Display/Display/ShakeAnimation.swift similarity index 89% rename from submodules/TelegramUI/TelegramUI/ShakeAnimation.swift rename to submodules/Display/Display/ShakeAnimation.swift index 75ef6b0d6f..1e36696312 100644 --- a/submodules/TelegramUI/TelegramUI/ShakeAnimation.swift +++ b/submodules/Display/Display/ShakeAnimation.swift @@ -1,8 +1,8 @@ import Foundation import UIKit -extension CALayer { - func addShakeAnimation(amplitude: CGFloat = 3.0, duration: Double = 0.3, count: Int = 4, decay: Bool = false) { +public extension CALayer { + public func addShakeAnimation(amplitude: CGFloat = 3.0, duration: Double = 0.3, count: Int = 4, decay: Bool = false) { let k = Float(UIView.animationDurationFactor()) var speed: Float = 1.0 if k != 0 && k != 1 { From 17223c9cfb2743bd19bddeb1866114572d98e748 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:18:20 +0300 Subject: [PATCH 29/41] Refactor ItemListUI --- submodules/ItemListUI/Info.plist | 22 + .../project.pbxproj | 675 ++++++++++++++++++ .../xcschemes/ItemListUI.xcscheme | 80 +++ .../Sources}/ItemListController.swift | 172 ++--- .../ItemListControllerEmptyStateItem.swift | 14 + .../Sources}/ItemListControllerNode.swift | 75 +- .../Sources}/ItemListControllerSearch.swift | 23 +- ...ItemListControllerSegmentedTitleView.swift | 18 +- .../ItemListEditableDeleteControlNode.swift | 12 +- .../ItemListEditableReorderControlNode.swift | 8 +- .../Sources}/ItemListItem.swift | 85 +-- ...emListLoadingIndicatorEmptyStateItem.swift | 17 +- .../Sources}/ItemListRevealOptionsNode.swift | 136 ++-- .../ItemListSelectableControlNode.swift | 7 +- submodules/ItemListUI/Sources/ItemListUI.h | 19 + .../Sources/Items}/ItemListActionItem.swift | 44 +- .../Items}/ItemListActivityTextItem.swift | 27 +- .../Sources/Items}/ItemListCheckboxItem.swift | 30 +- .../Items}/ItemListDisclosureItem.swift | 44 +- .../Sources/Items}/ItemListEditableItem.swift | 62 +- .../Items}/ItemListMultilineInputItem.swift | 51 +- .../Items}/ItemListMultilineTextItem.swift | 57 +- .../Sources/Items}/ItemListSwitchItem.swift | 35 +- .../Sources/Items}/ItemListTextItem.swift | 35 +- .../Items}/ItemListTextWithLabelItem.swift | 56 +- .../ItemListControllerEmptyStateItem.swift | 15 - 26 files changed, 1299 insertions(+), 520 deletions(-) create mode 100644 submodules/ItemListUI/Info.plist create mode 100644 submodules/ItemListUI/ItemListUI_Xcode.xcodeproj/project.pbxproj create mode 100644 submodules/ItemListUI/ItemListUI_Xcode.xcodeproj/xcshareddata/xcschemes/ItemListUI.xcscheme rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources}/ItemListController.swift (80%) create mode 100644 submodules/ItemListUI/Sources/ItemListControllerEmptyStateItem.swift rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources}/ItemListControllerNode.swift (89%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources}/ItemListControllerSearch.swift (57%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources}/ItemListControllerSegmentedTitleView.swift (80%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources}/ItemListEditableDeleteControlNode.swift (76%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources}/ItemListEditableReorderControlNode.swift (79%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources}/ItemListItem.swift (60%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources}/ItemListLoadingIndicatorEmptyStateItem.swift (68%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources}/ItemListRevealOptionsNode.swift (83%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources}/ItemListSelectableControlNode.swift (74%) create mode 100644 submodules/ItemListUI/Sources/ItemListUI.h rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources/Items}/ItemListActionItem.swift (86%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources/Items}/ItemListActivityTextItem.swift (74%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources/Items}/ItemListCheckboxItem.swift (87%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources/Items}/ItemListDisclosureItem.swift (90%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources/Items}/ItemListEditableItem.swift (89%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources/Items}/ItemListMultilineInputItem.swift (84%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources/Items}/ItemListMultilineTextItem.swift (87%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources/Items}/ItemListSwitchItem.swift (90%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources/Items}/ItemListTextItem.swift (77%) rename submodules/{TelegramUI/TelegramUI => ItemListUI/Sources/Items}/ItemListTextWithLabelItem.swift (88%) delete mode 100644 submodules/TelegramUI/TelegramUI/ItemListControllerEmptyStateItem.swift diff --git a/submodules/ItemListUI/Info.plist b/submodules/ItemListUI/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/ItemListUI/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/ItemListUI/ItemListUI_Xcode.xcodeproj/project.pbxproj b/submodules/ItemListUI/ItemListUI_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..7703e9af2e --- /dev/null +++ b/submodules/ItemListUI/ItemListUI_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,675 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D060182122F35C2300796784 /* ProgressNavigationButtonNode.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060182022F35C2300796784 /* ProgressNavigationButtonNode.framework */; }; + D060185322F35E1F00796784 /* ItemListMultilineInputItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060184922F35E1E00796784 /* ItemListMultilineInputItem.swift */; }; + D060185422F35E1F00796784 /* ItemListTextWithLabelItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060184A22F35E1E00796784 /* ItemListTextWithLabelItem.swift */; }; + D060185522F35E1F00796784 /* ItemListActivityTextItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060184B22F35E1E00796784 /* ItemListActivityTextItem.swift */; }; + D060185622F35E1F00796784 /* ItemListActionItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060184C22F35E1E00796784 /* ItemListActionItem.swift */; }; + D060185722F35E1F00796784 /* ItemListSwitchItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060184D22F35E1E00796784 /* ItemListSwitchItem.swift */; }; + D060185822F35E1F00796784 /* ItemListLoadingIndicatorEmptyStateItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060184E22F35E1E00796784 /* ItemListLoadingIndicatorEmptyStateItem.swift */; }; + D060185922F35E1F00796784 /* ItemListEditableItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060184F22F35E1E00796784 /* ItemListEditableItem.swift */; }; + D060185A22F35E1F00796784 /* ItemListDisclosureItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060185022F35E1E00796784 /* ItemListDisclosureItem.swift */; }; + D060185B22F35E1F00796784 /* ItemListMultilineTextItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060185122F35E1E00796784 /* ItemListMultilineTextItem.swift */; }; + D060185C22F35E1F00796784 /* ItemListCheckboxItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060185222F35E1F00796784 /* ItemListCheckboxItem.swift */; }; + D060186122F35F6C00796784 /* ItemListRevealOptionsNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060186022F35F6B00796784 /* ItemListRevealOptionsNode.swift */; }; + D06018A022F3618B00796784 /* SwitchNode.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060189F22F3618B00796784 /* SwitchNode.framework */; }; + D06018A222F3619000796784 /* AnimationUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018A122F3619000796784 /* AnimationUI.framework */; }; + D06018BB22F3663900796784 /* ItemListEditableReorderControlNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06018B822F3663800796784 /* ItemListEditableReorderControlNode.swift */; }; + D06018BC22F3663900796784 /* ItemListSelectableControlNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06018B922F3663800796784 /* ItemListSelectableControlNode.swift */; }; + D06018BD22F3663900796784 /* ItemListEditableDeleteControlNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06018BA22F3663900796784 /* ItemListEditableDeleteControlNode.swift */; }; + D06018E322F366F200796784 /* CheckNode.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06018E222F366F200796784 /* CheckNode.framework */; }; + D0D3282422F3205E00D07EE2 /* ItemListUI.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D3282222F3205E00D07EE2 /* ItemListUI.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0D3286522F3366600D07EE2 /* ItemListControllerEmptyStateItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3286022F3366500D07EE2 /* ItemListControllerEmptyStateItem.swift */; }; + D0D3286622F3366600D07EE2 /* ItemListControllerSegmentedTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3286122F3366500D07EE2 /* ItemListControllerSegmentedTitleView.swift */; }; + D0D3286722F3366600D07EE2 /* ItemListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3286222F3366500D07EE2 /* ItemListController.swift */; }; + D0D3286822F3366600D07EE2 /* ItemListControllerSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3286322F3366500D07EE2 /* ItemListControllerSearch.swift */; }; + D0D3286922F3366600D07EE2 /* ItemListControllerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3286422F3366500D07EE2 /* ItemListControllerNode.swift */; }; + D0D3286C22F3367300D07EE2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3286B22F3367300D07EE2 /* UIKit.framework */; }; + D0D3286E22F3367700D07EE2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3286D22F3367700D07EE2 /* Foundation.framework */; }; + D0D3287022F3367D00D07EE2 /* AsyncDisplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3286F22F3367D00D07EE2 /* AsyncDisplayKit.framework */; }; + D0D3287222F3368300D07EE2 /* Display.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3287122F3368300D07EE2 /* Display.framework */; }; + D0D3287422F3368C00D07EE2 /* AccountContext.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3287322F3368C00D07EE2 /* AccountContext.framework */; }; + D0D3287622F3369200D07EE2 /* TelegramPresentationData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3287522F3369200D07EE2 /* TelegramPresentationData.framework */; }; + D0D3289822F3449800D07EE2 /* MergeLists.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3289722F3449800D07EE2 /* MergeLists.framework */; }; + D0D3289A22F345C500D07EE2 /* ItemListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3289922F345C500D07EE2 /* ItemListItem.swift */; }; + D0D328A522F346C200D07EE2 /* ItemListTextItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D328A422F346C200D07EE2 /* ItemListTextItem.swift */; }; + D0D328DE22F34A0D00D07EE2 /* TextFormat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D328DD22F34A0D00D07EE2 /* TextFormat.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D060182022F35C2300796784 /* ProgressNavigationButtonNode.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = ProgressNavigationButtonNode.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060184922F35E1E00796784 /* ItemListMultilineInputItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListMultilineInputItem.swift; sourceTree = ""; }; + D060184A22F35E1E00796784 /* ItemListTextWithLabelItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListTextWithLabelItem.swift; sourceTree = ""; }; + D060184B22F35E1E00796784 /* ItemListActivityTextItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListActivityTextItem.swift; sourceTree = ""; }; + D060184C22F35E1E00796784 /* ItemListActionItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListActionItem.swift; sourceTree = ""; }; + D060184D22F35E1E00796784 /* ItemListSwitchItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListSwitchItem.swift; sourceTree = ""; }; + D060184E22F35E1E00796784 /* ItemListLoadingIndicatorEmptyStateItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListLoadingIndicatorEmptyStateItem.swift; sourceTree = ""; }; + D060184F22F35E1E00796784 /* ItemListEditableItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListEditableItem.swift; sourceTree = ""; }; + D060185022F35E1E00796784 /* ItemListDisclosureItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListDisclosureItem.swift; sourceTree = ""; }; + D060185122F35E1E00796784 /* ItemListMultilineTextItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListMultilineTextItem.swift; sourceTree = ""; }; + D060185222F35E1F00796784 /* ItemListCheckboxItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListCheckboxItem.swift; sourceTree = ""; }; + D060186022F35F6B00796784 /* ItemListRevealOptionsNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListRevealOptionsNode.swift; sourceTree = ""; }; + D060189F22F3618B00796784 /* SwitchNode.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwitchNode.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D06018A122F3619000796784 /* AnimationUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AnimationUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D06018B822F3663800796784 /* ItemListEditableReorderControlNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListEditableReorderControlNode.swift; sourceTree = ""; }; + D06018B922F3663800796784 /* ItemListSelectableControlNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListSelectableControlNode.swift; sourceTree = ""; }; + D06018BA22F3663900796784 /* ItemListEditableDeleteControlNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListEditableDeleteControlNode.swift; sourceTree = ""; }; + D06018E222F366F200796784 /* CheckNode.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CheckNode.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3281F22F3205E00D07EE2 /* ItemListUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ItemListUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3282222F3205E00D07EE2 /* ItemListUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ItemListUI.h; sourceTree = ""; }; + D0D3282322F3205E00D07EE2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D0D3286022F3366500D07EE2 /* ItemListControllerEmptyStateItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListControllerEmptyStateItem.swift; sourceTree = ""; }; + D0D3286122F3366500D07EE2 /* ItemListControllerSegmentedTitleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListControllerSegmentedTitleView.swift; sourceTree = ""; }; + D0D3286222F3366500D07EE2 /* ItemListController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListController.swift; sourceTree = ""; }; + D0D3286322F3366500D07EE2 /* ItemListControllerSearch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListControllerSearch.swift; sourceTree = ""; }; + D0D3286422F3366500D07EE2 /* ItemListControllerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListControllerNode.swift; sourceTree = ""; }; + D0D3286B22F3367300D07EE2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D0D3286D22F3367700D07EE2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D0D3286F22F3367D00D07EE2 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3287122F3368300D07EE2 /* Display.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Display.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3287322F3368C00D07EE2 /* AccountContext.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AccountContext.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3287522F3369200D07EE2 /* TelegramPresentationData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TelegramPresentationData.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3289722F3449800D07EE2 /* MergeLists.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MergeLists.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3289922F345C500D07EE2 /* ItemListItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListItem.swift; sourceTree = ""; }; + D0D328A422F346C200D07EE2 /* ItemListTextItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListTextItem.swift; sourceTree = ""; }; + D0D328DD22F34A0D00D07EE2 /* TextFormat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TextFormat.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D0D3281C22F3205E00D07EE2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D06018E322F366F200796784 /* CheckNode.framework in Frameworks */, + D06018A222F3619000796784 /* AnimationUI.framework in Frameworks */, + D06018A022F3618B00796784 /* SwitchNode.framework in Frameworks */, + D060182122F35C2300796784 /* ProgressNavigationButtonNode.framework in Frameworks */, + D0D328DE22F34A0D00D07EE2 /* TextFormat.framework in Frameworks */, + D0D3289822F3449800D07EE2 /* MergeLists.framework in Frameworks */, + D0D3287622F3369200D07EE2 /* TelegramPresentationData.framework in Frameworks */, + D0D3287422F3368C00D07EE2 /* AccountContext.framework in Frameworks */, + D0D3287222F3368300D07EE2 /* Display.framework in Frameworks */, + D0D3287022F3367D00D07EE2 /* AsyncDisplayKit.framework in Frameworks */, + D0D3286E22F3367700D07EE2 /* Foundation.framework in Frameworks */, + D0D3286C22F3367300D07EE2 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D060185D22F35E2200796784 /* Items */ = { + isa = PBXGroup; + children = ( + D060184C22F35E1E00796784 /* ItemListActionItem.swift */, + D060184B22F35E1E00796784 /* ItemListActivityTextItem.swift */, + D060185222F35E1F00796784 /* ItemListCheckboxItem.swift */, + D060185022F35E1E00796784 /* ItemListDisclosureItem.swift */, + D060184F22F35E1E00796784 /* ItemListEditableItem.swift */, + D060184922F35E1E00796784 /* ItemListMultilineInputItem.swift */, + D060185122F35E1E00796784 /* ItemListMultilineTextItem.swift */, + D060184D22F35E1E00796784 /* ItemListSwitchItem.swift */, + D060184A22F35E1E00796784 /* ItemListTextWithLabelItem.swift */, + D0D328A422F346C200D07EE2 /* ItemListTextItem.swift */, + ); + path = Items; + sourceTree = ""; + }; + D0D3281522F3205E00D07EE2 = { + isa = PBXGroup; + children = ( + D0D3282322F3205E00D07EE2 /* Info.plist */, + D0D3282122F3205E00D07EE2 /* Sources */, + D0D3282022F3205E00D07EE2 /* Products */, + D0D3286A22F3367300D07EE2 /* Frameworks */, + ); + sourceTree = ""; + }; + D0D3282022F3205E00D07EE2 /* Products */ = { + isa = PBXGroup; + children = ( + D0D3281F22F3205E00D07EE2 /* ItemListUI.framework */, + ); + name = Products; + sourceTree = ""; + }; + D0D3282122F3205E00D07EE2 /* Sources */ = { + isa = PBXGroup; + children = ( + D060185D22F35E2200796784 /* Items */, + D060184E22F35E1E00796784 /* ItemListLoadingIndicatorEmptyStateItem.swift */, + D0D3286222F3366500D07EE2 /* ItemListController.swift */, + D0D3286022F3366500D07EE2 /* ItemListControllerEmptyStateItem.swift */, + D0D3286422F3366500D07EE2 /* ItemListControllerNode.swift */, + D0D3286322F3366500D07EE2 /* ItemListControllerSearch.swift */, + D0D3286122F3366500D07EE2 /* ItemListControllerSegmentedTitleView.swift */, + D0D3289922F345C500D07EE2 /* ItemListItem.swift */, + D060186022F35F6B00796784 /* ItemListRevealOptionsNode.swift */, + D06018BA22F3663900796784 /* ItemListEditableDeleteControlNode.swift */, + D06018B822F3663800796784 /* ItemListEditableReorderControlNode.swift */, + D06018B922F3663800796784 /* ItemListSelectableControlNode.swift */, + D0D3282222F3205E00D07EE2 /* ItemListUI.h */, + ); + path = Sources; + sourceTree = ""; + }; + D0D3286A22F3367300D07EE2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D06018E222F366F200796784 /* CheckNode.framework */, + D06018A122F3619000796784 /* AnimationUI.framework */, + D060189F22F3618B00796784 /* SwitchNode.framework */, + D060182022F35C2300796784 /* ProgressNavigationButtonNode.framework */, + D0D328DD22F34A0D00D07EE2 /* TextFormat.framework */, + D0D3289722F3449800D07EE2 /* MergeLists.framework */, + D0D3287522F3369200D07EE2 /* TelegramPresentationData.framework */, + D0D3287322F3368C00D07EE2 /* AccountContext.framework */, + D0D3287122F3368300D07EE2 /* Display.framework */, + D0D3286F22F3367D00D07EE2 /* AsyncDisplayKit.framework */, + D0D3286D22F3367700D07EE2 /* Foundation.framework */, + D0D3286B22F3367300D07EE2 /* UIKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D0D3281A22F3205E00D07EE2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D0D3282422F3205E00D07EE2 /* ItemListUI.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D0D3281E22F3205E00D07EE2 /* ItemListUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = D0D3282722F3205E00D07EE2 /* Build configuration list for PBXNativeTarget "ItemListUI" */; + buildPhases = ( + D0D3281A22F3205E00D07EE2 /* Headers */, + D0D3281B22F3205E00D07EE2 /* Sources */, + D0D3281C22F3205E00D07EE2 /* Frameworks */, + D0D3281D22F3205E00D07EE2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ItemListUI; + productName = ItemListUI; + productReference = D0D3281F22F3205E00D07EE2 /* ItemListUI.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D0D3281622F3205E00D07EE2 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D0D3281E22F3205E00D07EE2 = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1010; + }; + }; + }; + buildConfigurationList = D0D3281922F3205E00D07EE2 /* Build configuration list for PBXProject "ItemListUI_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D0D3281522F3205E00D07EE2; + productRefGroup = D0D3282022F3205E00D07EE2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D0D3281E22F3205E00D07EE2 /* ItemListUI */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D0D3281D22F3205E00D07EE2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D0D3281B22F3205E00D07EE2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D060185322F35E1F00796784 /* ItemListMultilineInputItem.swift in Sources */, + D06018BB22F3663900796784 /* ItemListEditableReorderControlNode.swift in Sources */, + D060185522F35E1F00796784 /* ItemListActivityTextItem.swift in Sources */, + D060186122F35F6C00796784 /* ItemListRevealOptionsNode.swift in Sources */, + D06018BC22F3663900796784 /* ItemListSelectableControlNode.swift in Sources */, + D060185822F35E1F00796784 /* ItemListLoadingIndicatorEmptyStateItem.swift in Sources */, + D0D3286522F3366600D07EE2 /* ItemListControllerEmptyStateItem.swift in Sources */, + D060185622F35E1F00796784 /* ItemListActionItem.swift in Sources */, + D060185922F35E1F00796784 /* ItemListEditableItem.swift in Sources */, + D060185A22F35E1F00796784 /* ItemListDisclosureItem.swift in Sources */, + D060185422F35E1F00796784 /* ItemListTextWithLabelItem.swift in Sources */, + D0D3286722F3366600D07EE2 /* ItemListController.swift in Sources */, + D0D3286822F3366600D07EE2 /* ItemListControllerSearch.swift in Sources */, + D060185722F35E1F00796784 /* ItemListSwitchItem.swift in Sources */, + D0D3286622F3366600D07EE2 /* ItemListControllerSegmentedTitleView.swift in Sources */, + D060185B22F35E1F00796784 /* ItemListMultilineTextItem.swift in Sources */, + D0D3286922F3366600D07EE2 /* ItemListControllerNode.swift in Sources */, + D0D328A522F346C200D07EE2 /* ItemListTextItem.swift in Sources */, + D06018BD22F3663900796784 /* ItemListEditableDeleteControlNode.swift in Sources */, + D0D3289A22F345C500D07EE2 /* ItemListItem.swift in Sources */, + D060185C22F35E1F00796784 /* ItemListCheckboxItem.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D0D3282522F3205E00D07EE2 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D0D3282622F3205E00D07EE2 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D0D3282822F3205E00D07EE2 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ItemListUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D0D3282922F3205E00D07EE2 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ItemListUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D0D3282A22F3208400D07EE2 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D0D3282B22F3208400D07EE2 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ItemListUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D0D3282C22F3209200D07EE2 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D0D3282D22F3209200D07EE2 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ItemListUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D0D3281922F3205E00D07EE2 /* Build configuration list for PBXProject "ItemListUI_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0D3282522F3205E00D07EE2 /* DebugAppStoreLLC */, + D0D3282A22F3208400D07EE2 /* DebugHockeyapp */, + D0D3282622F3205E00D07EE2 /* ReleaseAppStoreLLC */, + D0D3282C22F3209200D07EE2 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D0D3282722F3205E00D07EE2 /* Build configuration list for PBXNativeTarget "ItemListUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0D3282822F3205E00D07EE2 /* DebugAppStoreLLC */, + D0D3282B22F3208400D07EE2 /* DebugHockeyapp */, + D0D3282922F3205E00D07EE2 /* ReleaseAppStoreLLC */, + D0D3282D22F3209200D07EE2 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D0D3281622F3205E00D07EE2 /* Project object */; +} diff --git a/submodules/ItemListUI/ItemListUI_Xcode.xcodeproj/xcshareddata/xcschemes/ItemListUI.xcscheme b/submodules/ItemListUI/ItemListUI_Xcode.xcodeproj/xcshareddata/xcschemes/ItemListUI.xcscheme new file mode 100644 index 0000000000..b00cddab4d --- /dev/null +++ b/submodules/ItemListUI/ItemListUI_Xcode.xcodeproj/xcshareddata/xcschemes/ItemListUI.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/submodules/TelegramUI/TelegramUI/ItemListController.swift b/submodules/ItemListUI/Sources/ItemListController.swift similarity index 80% rename from submodules/TelegramUI/TelegramUI/ItemListController.swift rename to submodules/ItemListUI/Sources/ItemListController.swift index 8dd5727153..10048b4693 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListController.swift +++ b/submodules/ItemListUI/Sources/ItemListController.swift @@ -4,101 +4,70 @@ import Display import SwiftSignalKit import TelegramCore import TelegramPresentationData +import AccountContext +import ProgressNavigationButtonNode -enum ItemListNavigationButtonStyle { +public enum ItemListNavigationButtonStyle { case regular case bold case activity - var barButtonItemStyle: UIBarButtonItemStyle { + public var barButtonItemStyle: UIBarButtonItem.Style { switch self { - case .regular, .activity: - return .plain - case .bold: - return .done + case .regular, .activity: + return .plain + case .bold: + return .done } } } -enum ItemListNavigationButtonContentIcon { +public enum ItemListNavigationButtonContentIcon { case search case add } -enum ItemListNavigationButtonContent: Equatable { +public enum ItemListNavigationButtonContent: Equatable { case none case text(String) case icon(ItemListNavigationButtonContentIcon) +} + +public struct ItemListNavigationButton { + public let content: ItemListNavigationButtonContent + public let style: ItemListNavigationButtonStyle + public let enabled: Bool + public let action: () -> Void - static func ==(lhs: ItemListNavigationButtonContent, rhs: ItemListNavigationButtonContent) -> Bool { - switch lhs { - case .none: - if case .none = rhs { - return true - } else { - return false - } - case let .text(value): - if case .text(value) = rhs { - return true - } else { - return false - } - case let .icon(value): - if case .icon(value) = rhs { - return true - } else { - return false - } - } + public init(content: ItemListNavigationButtonContent, style: ItemListNavigationButtonStyle, enabled: Bool, action: @escaping () -> Void) { + self.content = content + self.style = style + self.enabled = enabled + self.action = action } } -struct ItemListNavigationButton { - let content: ItemListNavigationButtonContent - let style: ItemListNavigationButtonStyle - let enabled: Bool - let action: () -> Void -} - -struct ItemListBackButton: Equatable { - let title: String +public struct ItemListBackButton: Equatable { + public let title: String - static func ==(lhs: ItemListBackButton, rhs: ItemListBackButton) -> Bool { - return lhs.title == rhs.title + public init(title: String) { + self.title = title } } -enum ItemListControllerTitle: Equatable { +public enum ItemListControllerTitle: Equatable { case text(String) case sectionControl([String], Int) - - static func ==(lhs: ItemListControllerTitle, rhs: ItemListControllerTitle) -> Bool { - switch lhs { - case let .text(text): - if case .text(text) = rhs { - return true - } else { - return false - } - case let .sectionControl(lhsSection, lhsIndex): - if case let .sectionControl(rhsSection, rhsIndex) = rhs, lhsSection == rhsSection, lhsIndex == rhsIndex { - return true - } else { - return false - } - } - } } -final class ItemListControllerTabBarItem: Equatable { +public final class ItemListControllerTabBarItem: Equatable { let title: String let image: UIImage? let selectedImage: UIImage? let tintImages: Bool let badgeValue: String? - init(title: String, image: UIImage?, selectedImage: UIImage?, tintImages: Bool = true, badgeValue: String? = nil) { + public init(title: String, image: UIImage?, selectedImage: UIImage?, tintImages: Bool = true, badgeValue: String? = nil) { self.title = title self.image = image self.selectedImage = selectedImage @@ -106,12 +75,12 @@ final class ItemListControllerTabBarItem: Equatable { self.badgeValue = badgeValue } - static func ==(lhs: ItemListControllerTabBarItem, rhs: ItemListControllerTabBarItem) -> Bool { + public static func ==(lhs: ItemListControllerTabBarItem, rhs: ItemListControllerTabBarItem) -> Bool { return lhs.title == rhs.title && lhs.image === rhs.image && lhs.selectedImage === rhs.selectedImage && lhs.tintImages == rhs.tintImages && lhs.badgeValue == rhs.badgeValue } } -struct ItemListControllerState { +public struct ItemListControllerState { let theme: PresentationTheme let title: ItemListControllerTitle let leftNavigationButton: ItemListNavigationButton? @@ -121,7 +90,7 @@ struct ItemListControllerState { let tabBarItem: ItemListControllerTabBarItem? let animateChanges: Bool - init(theme: PresentationTheme, title: ItemListControllerTitle, leftNavigationButton: ItemListNavigationButton?, rightNavigationButton: ItemListNavigationButton?, secondaryRightNavigationButton: ItemListNavigationButton? = nil, backNavigationButton: ItemListBackButton?, tabBarItem: ItemListControllerTabBarItem? = nil, animateChanges: Bool = true) { + public init(theme: PresentationTheme, title: ItemListControllerTitle, leftNavigationButton: ItemListNavigationButton?, rightNavigationButton: ItemListNavigationButton?, secondaryRightNavigationButton: ItemListNavigationButton? = nil, backNavigationButton: ItemListBackButton?, tabBarItem: ItemListControllerTabBarItem? = nil, animateChanges: Bool = true) { self.theme = theme self.title = title self.leftNavigationButton = leftNavigationButton @@ -133,7 +102,7 @@ struct ItemListControllerState { } } -class ItemListController: ViewController, KeyShortcutResponder, PresentableController { +open class ItemListController: ViewController, KeyShortcutResponder, PresentableController { private let state: Signal<(ItemListControllerState, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError> private var leftNavigationButtonTitleAndStyle: (ItemListNavigationButtonContent, ItemListNavigationButtonStyle)? @@ -149,20 +118,20 @@ class ItemListController: ViewController, KeyShortcutR private var validLayout: ContainerViewLayout? private var didPlayPresentationAnimation = false - private(set) var didAppearOnce = false - var didAppear: ((Bool) -> Void)? + public private(set) var didAppearOnce = false + public var didAppear: ((Bool) -> Void)? private var isDismissed = false - var titleControlValueChanged: ((Int) -> Void)? + public var titleControlValueChanged: ((Int) -> Void)? private var tabBarItemDisposable: Disposable? private let _ready = Promise() - override var ready: Promise { + override open var ready: Promise { return self._ready } - var experimentalSnapScrollToItem: Bool = false { + public var experimentalSnapScrollToItem: Bool = false { didSet { if self.isNodeLoaded { (self.displayNode as! ItemListControllerNode).listNode.experimentalSnapScrollToItem = self.experimentalSnapScrollToItem @@ -170,7 +139,7 @@ class ItemListController: ViewController, KeyShortcutR } } - var enableInteractiveDismiss = false { + public var enableInteractiveDismiss = false { didSet { if self.isNodeLoaded { (self.displayNode as! ItemListControllerNode).enableInteractiveDismiss = self.enableInteractiveDismiss @@ -178,7 +147,7 @@ class ItemListController: ViewController, KeyShortcutR } } - var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> Void)? { + public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> Void)? { didSet { if self.isNodeLoaded { (self.displayNode as! ItemListControllerNode).visibleEntriesUpdated = self.visibleEntriesUpdated @@ -186,7 +155,7 @@ class ItemListController: ViewController, KeyShortcutR } } - var visibleBottomContentOffsetChanged: ((ListViewVisibleContentOffset) -> Void)? { + public var visibleBottomContentOffsetChanged: ((ListViewVisibleContentOffset) -> Void)? { didSet { if self.isNodeLoaded { (self.displayNode as! ItemListControllerNode).visibleBottomContentOffsetChanged = self.visibleBottomContentOffsetChanged @@ -194,14 +163,15 @@ class ItemListController: ViewController, KeyShortcutR } } - var contentOffsetChanged: ((ListViewVisibleContentOffset, Bool) -> Void)? { + public var contentOffsetChanged: ((ListViewVisibleContentOffset, Bool) -> Void)? { didSet { if self.isNodeLoaded { (self.displayNode as! ItemListControllerNode).contentOffsetChanged = self.contentOffsetChanged } } } - var contentScrollingEnded: ((ListView) -> Bool)? { + + public var contentScrollingEnded: ((ListView) -> Bool)? { didSet { if self.isNodeLoaded { (self.displayNode as! ItemListControllerNode).contentScrollingEnded = self.contentScrollingEnded @@ -209,7 +179,7 @@ class ItemListController: ViewController, KeyShortcutR } } - var searchActivated: ((Bool) -> Void)? { + public var searchActivated: ((Bool) -> Void)? { didSet { if self.isNodeLoaded { (self.displayNode as! ItemListControllerNode).searchActivated = self.searchActivated @@ -217,9 +187,9 @@ class ItemListController: ViewController, KeyShortcutR } } - var willScrollToTop: (() -> Void)? + public var willScrollToTop: (() -> Void)? - var reorderEntry: ((Int, Int, [Entry]) -> Void)? { + public var reorderEntry: ((Int, Int, [Entry]) -> Void)? { didSet { if self.isNodeLoaded { (self.displayNode as! ItemListControllerNode).reorderEntry = self.reorderEntry @@ -227,22 +197,22 @@ class ItemListController: ViewController, KeyShortcutR } } - var previewItemWithTag: ((ItemListItemTag) -> UIViewController?)? - var commitPreview: ((UIViewController) -> Void)? + public var previewItemWithTag: ((ItemListItemTag) -> UIViewController?)? + public var commitPreview: ((UIViewController) -> Void)? - var willDisappear: ((Bool) -> Void)? - var didDisappear: ((Bool) -> Void)? + public var willDisappear: ((Bool) -> Void)? + public var didDisappear: ((Bool) -> Void)? - convenience init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal? = nil) { - self.init(sharedContext: context.sharedContext, state: state, tabBarItem: tabBarItem) + convenience public init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal? = nil) { + self.init(sharedContext: context.genericSharedContext, state: state, tabBarItem: tabBarItem) } - convenience init(sharedContext: SharedAccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal? = nil) { + convenience public init(sharedContext: SharedAccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal? = nil) { let presentationData = sharedContext.currentPresentationData.with { $0 } self.init(theme: presentationData.theme, strings: presentationData.strings, updatedPresentationData: sharedContext.presentationData |> map { ($0.theme, $0.strings) }, state: state, tabBarItem: tabBarItem) } - init(theme: PresentationTheme, strings: PresentationStrings, updatedPresentationData: Signal<(theme: PresentationTheme, strings: PresentationStrings), NoError>, state: Signal<(ItemListControllerState, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal?) { + public init(theme: PresentationTheme, strings: PresentationStrings, updatedPresentationData: Signal<(theme: PresentationTheme, strings: PresentationStrings), NoError>, state: Signal<(ItemListControllerState, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>, tabBarItem: Signal?) { self.state = state self.theme = theme @@ -276,7 +246,7 @@ class ItemListController: ViewController, KeyShortcutR } } - required init(coder aDecoder: NSCoder) { + required public init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -284,7 +254,7 @@ class ItemListController: ViewController, KeyShortcutR self.tabBarItemDisposable?.dispose() } - override func loadDisplayNode() { + override open func loadDisplayNode() { let previousControllerState = Atomic(value: nil) let nodeState = self.state |> deliverOnMainQueue @@ -458,7 +428,7 @@ class ItemListController: ViewController, KeyShortcutR self._ready.set((self.displayNode as! ItemListControllerNode).ready) } - override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { + override open func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { super.containerLayoutUpdated(layout, transition: transition) self.validLayout = layout @@ -478,13 +448,13 @@ class ItemListController: ViewController, KeyShortcutR self.navigationButtonActions.secondaryRight?() } - override func viewDidAppear(_ animated: Bool) { + override open func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.viewDidAppear(completion: {}) } - func viewDidAppear(completion: @escaping () -> Void) { + public func viewDidAppear(completion: @escaping () -> Void) { (self.displayNode as! ItemListControllerNode).listNode.preloadPages = true if let presentationArguments = self.presentationArguments as? ViewControllerPresentationArguments, !self.didPlayPresentationAnimation { @@ -506,26 +476,26 @@ class ItemListController: ViewController, KeyShortcutR self.didAppear?(firstTime) } - override func viewWillDisappear(_ animated: Bool) { + override open func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.willDisappear?(animated) } - override func viewDidDisappear(_ animated: Bool) { + override open func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) self.didDisappear?(animated) } - override func dismiss(completion: (() -> Void)? = nil) { + override open func dismiss(completion: (() -> Void)? = nil) { if !self.isDismissed { self.isDismissed = true (self.displayNode as! ItemListControllerNode).animateOut(completion: completion) } } - func frameForItemNode(_ predicate: (ListViewItemNode) -> Bool) -> CGRect? { + public func frameForItemNode(_ predicate: (ListViewItemNode) -> Bool) -> CGRect? { var result: CGRect? (self.displayNode as! ItemListControllerNode).listNode.forEachItemNode { itemNode in if let itemNode = itemNode as? ListViewItemNode { @@ -537,7 +507,7 @@ class ItemListController: ViewController, KeyShortcutR return result } - func forEachItemNode(_ f: (ListViewItemNode) -> Void) { + public func forEachItemNode(_ f: (ListViewItemNode) -> Void) { (self.displayNode as! ItemListControllerNode).listNode.forEachItemNode { itemNode in if let itemNode = itemNode as? ListViewItemNode { f(itemNode) @@ -545,15 +515,15 @@ class ItemListController: ViewController, KeyShortcutR } } - func ensureItemNodeVisible(_ itemNode: ListViewItemNode) { + public func ensureItemNodeVisible(_ itemNode: ListViewItemNode) { (self.displayNode as! ItemListControllerNode).listNode.ensureItemNodeVisible(itemNode) } - func afterLayout(_ f: @escaping () -> Void) { + public func afterLayout(_ f: @escaping () -> Void) { (self.displayNode as! ItemListControllerNode).afterLayout(f) } - func previewingController(from sourceView: UIView, for location: CGPoint) -> (UIViewController, CGRect)? { + public func previewingController(from sourceView: UIView, for location: CGPoint) -> (UIViewController, CGRect)? { guard let layout = self.validLayout else { return nil } @@ -590,16 +560,16 @@ class ItemListController: ViewController, KeyShortcutR } } - func clearItemNodesHighlight(animated: Bool = false) { + public func clearItemNodesHighlight(animated: Bool = false) { (self.displayNode as! ItemListControllerNode).listNode.clearHighlightAnimated(animated) } - func previewingCommit(_ viewControllerToCommit: UIViewController) { + public func previewingCommit(_ viewControllerToCommit: UIViewController) { self.commitPreview?(viewControllerToCommit) } public var keyShortcuts: [KeyShortcut] { - return [KeyShortcut(input: UIKeyInputEscape, action: { [weak self] in + return [KeyShortcut(input: UIKeyCommand.inputEscape, action: { [weak self] in if !(self?.navigationController?.topViewController is TabBarController) { _ = self?.navigationBar?.executeBack() } diff --git a/submodules/ItemListUI/Sources/ItemListControllerEmptyStateItem.swift b/submodules/ItemListUI/Sources/ItemListControllerEmptyStateItem.swift new file mode 100644 index 0000000000..711b097a6a --- /dev/null +++ b/submodules/ItemListUI/Sources/ItemListControllerEmptyStateItem.swift @@ -0,0 +1,14 @@ +import Foundation +import UIKit +import AsyncDisplayKit +import Display + +public protocol ItemListControllerEmptyStateItem { + func isEqual(to: ItemListControllerEmptyStateItem) -> Bool + func node(current: ItemListControllerEmptyStateItemNode?) -> ItemListControllerEmptyStateItemNode +} + +open class ItemListControllerEmptyStateItemNode: ASDisplayNode { + open func updateLayout(layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { + } +} diff --git a/submodules/TelegramUI/TelegramUI/ItemListControllerNode.swift b/submodules/ItemListUI/Sources/ItemListControllerNode.swift similarity index 89% rename from submodules/TelegramUI/TelegramUI/ItemListControllerNode.swift rename to submodules/ItemListUI/Sources/ItemListControllerNode.swift index 6d0b25e53c..71a54c2aee 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListControllerNode.swift +++ b/submodules/ItemListUI/Sources/ItemListControllerNode.swift @@ -5,10 +5,11 @@ import Display import SwiftSignalKit import TelegramCore import TelegramPresentationData +import MergeLists -typealias ItemListSectionId = Int32 +public typealias ItemListSectionId = Int32 -protocol ItemListNodeEntry: Comparable, Identifiable { +public protocol ItemListNodeEntry: Comparable, Identifiable { associatedtype ItemGenerationArguments var section: ItemListSectionId { get } @@ -17,7 +18,7 @@ protocol ItemListNodeEntry: Comparable, Identifiable { func item(_ arguments: ItemGenerationArguments) -> ListViewItem } -extension ItemListNodeEntry { +public extension ItemListNodeEntry { var tag: ItemListItemTag? { return nil } } @@ -37,7 +38,7 @@ private func preparedItemListNodeEntryTransition(from return ItemListNodeEntryTransition(deletions: deletions, insertions: insertions, updates: updates) } -enum ItemListStyle { +public enum ItemListStyle { case plain case blocks } @@ -59,7 +60,7 @@ private struct ItemListNodeTransition { let scrollEnabled: Bool } -struct ItemListNodeState { +public struct ItemListNodeState { let entries: [Entry] let style: ItemListStyle let emptyStateItem: ItemListControllerEmptyStateItem? @@ -71,7 +72,7 @@ struct ItemListNodeState { let ensureVisibleItemTag: ItemListItemTag? let initialScrollToItem: ListViewScrollToItem? - init(entries: [Entry], style: ItemListStyle, focusItemTag: ItemListItemTag? = nil, ensureVisibleItemTag: ItemListItemTag? = nil, emptyStateItem: ItemListControllerEmptyStateItem? = nil, searchItem: ItemListControllerSearch? = nil, initialScrollToItem: ListViewScrollToItem? = nil, crossfadeState: Bool = false, animateChanges: Bool = true, scrollEnabled: Bool = true) { + public init(entries: [Entry], style: ItemListStyle, focusItemTag: ItemListItemTag? = nil, ensureVisibleItemTag: ItemListItemTag? = nil, emptyStateItem: ItemListControllerEmptyStateItem? = nil, searchItem: ItemListControllerSearch? = nil, initialScrollToItem: ListViewScrollToItem? = nil, crossfadeState: Bool = false, animateChanges: Bool = true, scrollEnabled: Bool = true) { self.entries = entries self.style = style self.emptyStateItem = emptyStateItem @@ -93,21 +94,21 @@ private final class ItemListNodeOpaqueState { } } -final class ItemListNodeVisibleEntries: Sequence { +public final class ItemListNodeVisibleEntries: Sequence { let iterate: () -> Entry? init(iterate: @escaping () -> Entry?) { self.iterate = iterate } - func makeIterator() -> AnyIterator { + public func makeIterator() -> AnyIterator { return AnyIterator { () -> Entry? in return self.iterate() } } } -final class ItemListControllerNodeView: UITracingLayerView, PreviewingHostView { +public final class ItemListControllerNodeView: UITracingLayerView, PreviewingHostView { var onLayout: (() -> Void)? init(controller: ItemListController?) { @@ -120,7 +121,7 @@ final class ItemListControllerNodeView: UITracingLayer fatalError("init(coder:) has not been implemented") } - override func layoutSubviews() { + override public func layoutSubviews() { super.layoutSubviews() self.onLayout?() @@ -129,7 +130,7 @@ final class ItemListControllerNodeView: UITracingLayer private var inHitTest = false var hitTestImpl: ((CGPoint, UIEvent?) -> UIView?)? - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if self.inHitTest { return super.hitTest(point, with: event) } else { @@ -140,7 +141,7 @@ final class ItemListControllerNodeView: UITracingLayer } } - var previewingDelegate: PreviewingHostViewDelegate? { + public var previewingDelegate: PreviewingHostViewDelegate? { return PreviewingHostViewDelegate(controllerForLocation: { [weak self] sourceView, point in return self?.controller?.previewingController(from: sourceView, for: point) }, commitController: { [weak self] controller in @@ -151,16 +152,16 @@ final class ItemListControllerNodeView: UITracingLayer weak var controller: ItemListController? } -class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate { +open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate { private var _ready = ValuePromise() - public var ready: Signal { + open var ready: Signal { return self._ready.get() } private var didSetReady = false private let navigationBar: NavigationBar - let listNode: ListView + public let listNode: ListView private var emptyStateItem: ItemListControllerEmptyStateItem? private var emptyStateNode: ItemListControllerEmptyStateItemNode? @@ -180,23 +181,23 @@ class ItemListControllerNode: ASDisplayNode, UIScrollV private var afterLayoutActions: [() -> Void] = [] - let updateNavigationOffset: (CGFloat) -> Void - var dismiss: (() -> Void)? + public let updateNavigationOffset: (CGFloat) -> Void + public var dismiss: (() -> Void)? - var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> Void)? - var visibleBottomContentOffsetChanged: ((ListViewVisibleContentOffset) -> Void)? - var contentOffsetChanged: ((ListViewVisibleContentOffset, Bool) -> Void)? - var contentScrollingEnded: ((ListView) -> Bool)? - var searchActivated: ((Bool) -> Void)? - var reorderEntry: ((Int, Int, [Entry]) -> Void)? - var requestLayout: ((ContainedViewLayoutTransition) -> Void)? + public var visibleEntriesUpdated: ((ItemListNodeVisibleEntries) -> Void)? + public var visibleBottomContentOffsetChanged: ((ListViewVisibleContentOffset) -> Void)? + public var contentOffsetChanged: ((ListViewVisibleContentOffset, Bool) -> Void)? + public var contentScrollingEnded: ((ListView) -> Bool)? + public var searchActivated: ((Bool) -> Void)? + public var reorderEntry: ((Int, Int, [Entry]) -> Void)? + public var requestLayout: ((ContainedViewLayoutTransition) -> Void)? - var enableInteractiveDismiss = false { + public var enableInteractiveDismiss = false { didSet { } } - init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, state: Signal<(PresentationTheme, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>) { + public init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, state: Signal<(PresentationTheme, (ItemListNodeState, Entry.ItemGenerationArguments)), NoError>) { self.navigationBar = navigationBar self.updateNavigationOffset = updateNavigationOffset @@ -287,7 +288,7 @@ class ItemListControllerNode: ASDisplayNode, UIScrollV self.transitionDisposable.dispose() } - override func didLoad() { + override open func didLoad() { super.didLoad() (self.view as? ItemListControllerNodeView)?.onLayout = { [weak self] in @@ -308,14 +309,14 @@ class ItemListControllerNode: ASDisplayNode, UIScrollV } } - func animateIn(completion: (() -> Void)? = nil) { + open func animateIn(completion: (() -> Void)? = nil) { self.layer.animatePosition(from: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), to: self.layer.position, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, completion: { _ in completion?() }) } - func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { [weak self] _ in + open func animateOut(completion: (() -> Void)? = nil) { + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in if let strongSelf = self { strongSelf.dismiss?() } @@ -323,7 +324,7 @@ class ItemListControllerNode: ASDisplayNode, UIScrollV }) } - func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { + open func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { var duration: Double = 0.0 var curve: UInt = 0 switch transition { @@ -601,15 +602,15 @@ class ItemListControllerNode: ASDisplayNode, UIScrollV } } - func scrollToTop() { + open func scrollToTop() { self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) self.searchNode?.scrollToTop() } - func scrollViewDidScroll(_ scrollView: UIScrollView) { + open func scrollViewDidScroll(_ scrollView: UIScrollView) { let distanceFromEquilibrium = scrollView.contentOffset.y - scrollView.contentSize.height / 3.0 - let transition = 1.0 - min(1.0, max(0.0, abs(distanceFromEquilibrium) / 50.0)) + //let transition = 1.0 - min(1.0, max(0.0, abs(distanceFromEquilibrium) / 50.0)) self.updateNavigationOffset(-distanceFromEquilibrium) @@ -618,7 +619,7 @@ class ItemListControllerNode: ASDisplayNode, UIScrollV }*/ } - func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { + open func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { targetContentOffset.pointee = scrollView.contentOffset let scrollVelocity = scrollView.panGestureRecognizer.velocity(in: scrollView) @@ -628,7 +629,7 @@ class ItemListControllerNode: ASDisplayNode, UIScrollV } } - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + override open func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if let searchNode = self.searchNode { if let result = searchNode.hitTest(point, with: event) { return result @@ -638,7 +639,7 @@ class ItemListControllerNode: ASDisplayNode, UIScrollV return super.hitTest(point, with: event) } - func afterLayout(_ f: @escaping () -> Void) { + open func afterLayout(_ f: @escaping () -> Void) { self.afterLayoutActions.append(f) self.view.setNeedsLayout() } diff --git a/submodules/TelegramUI/TelegramUI/ItemListControllerSearch.swift b/submodules/ItemListUI/Sources/ItemListControllerSearch.swift similarity index 57% rename from submodules/TelegramUI/TelegramUI/ItemListControllerSearch.swift rename to submodules/ItemListUI/Sources/ItemListControllerSearch.swift index ab34e05133..2c0cdd9746 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListControllerSearch.swift +++ b/submodules/ItemListUI/Sources/ItemListControllerSearch.swift @@ -3,40 +3,37 @@ import UIKit import AsyncDisplayKit import Display -protocol ItemListControllerSearchNavigationContentNode { +public protocol ItemListControllerSearchNavigationContentNode { func activate() func deactivate() func setQueryUpdated(_ f: @escaping (String) -> Void) } -protocol ItemListControllerSearch { +public protocol ItemListControllerSearch { func isEqual(to: ItemListControllerSearch) -> Bool func titleContentNode(current: (NavigationBarContentNode & ItemListControllerSearchNavigationContentNode)?) -> NavigationBarContentNode & ItemListControllerSearchNavigationContentNode func node(current: ItemListControllerSearchNode?, titleContentNode: (NavigationBarContentNode & ItemListControllerSearchNavigationContentNode)?) -> ItemListControllerSearchNode } -class ItemListControllerSearchNode: ASDisplayNode { - func activate() { - self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut) +open class ItemListControllerSearchNode: ASDisplayNode { + open func activate() { + self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue) } - func deactivate() { - self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { [weak self] _ in + open func deactivate() { + self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in self?.removeFromSupernode() }) } - func scrollToTop() { - + open func scrollToTop() { } - func queryUpdated(_ query: String) { - + open func queryUpdated(_ query: String) { } - func updateLayout(layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { - + open func updateLayout(layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { } } diff --git a/submodules/TelegramUI/TelegramUI/ItemListControllerSegmentedTitleView.swift b/submodules/ItemListUI/Sources/ItemListControllerSegmentedTitleView.swift similarity index 80% rename from submodules/TelegramUI/TelegramUI/ItemListControllerSegmentedTitleView.swift rename to submodules/ItemListUI/Sources/ItemListControllerSegmentedTitleView.swift index f62f0667d9..1cff70bd53 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListControllerSegmentedTitleView.swift +++ b/submodules/ItemListUI/Sources/ItemListControllerSegmentedTitleView.swift @@ -1,8 +1,8 @@ import Foundation import UIKit -final class ItemListControllerSegmentedTitleView: UIView { - var segments: [String] { +public final class ItemListControllerSegmentedTitleView: UIView { + public var segments: [String] { didSet { if self.segments != oldValue { self.control.removeAllSegments() @@ -16,7 +16,7 @@ final class ItemListControllerSegmentedTitleView: UIView { } } - var index: Int { + public var index: Int { didSet { self.control.selectedSegmentIndex = self.index } @@ -24,15 +24,15 @@ final class ItemListControllerSegmentedTitleView: UIView { private let control: UISegmentedControl - var indexUpdated: ((Int) -> Void)? + public var indexUpdated: ((Int) -> Void)? - var color: UIColor { + public var color: UIColor { didSet { self.control.tintColor = self.color } } - init(segments: [String], index: Int, color: UIColor) { + public init(segments: [String], index: Int, color: UIColor) { self.segments = segments self.index = index self.color = color @@ -47,11 +47,11 @@ final class ItemListControllerSegmentedTitleView: UIView { self.control.addTarget(self, action: #selector(indexChanged), for: .valueChanged) } - required init?(coder aDecoder: NSCoder) { + required public init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - override func layoutSubviews() { + override public func layoutSubviews() { super.layoutSubviews() let size = self.bounds.size @@ -61,7 +61,7 @@ final class ItemListControllerSegmentedTitleView: UIView { self.control.frame = CGRect(origin: CGPoint(x: floor((size.width - controlSize.width) / 2.0), y: floor((size.height - controlSize.height) / 2.0)), size: controlSize) } - @objc func indexChanged() { + @objc private func indexChanged() { self.indexUpdated?(self.control.selectedSegmentIndex) } } diff --git a/submodules/TelegramUI/TelegramUI/ItemListEditableDeleteControlNode.swift b/submodules/ItemListUI/Sources/ItemListEditableDeleteControlNode.swift similarity index 76% rename from submodules/TelegramUI/TelegramUI/ItemListEditableDeleteControlNode.swift rename to submodules/ItemListUI/Sources/ItemListEditableDeleteControlNode.swift index 1cb87549f5..92a88917fa 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListEditableDeleteControlNode.swift +++ b/submodules/ItemListUI/Sources/ItemListEditableDeleteControlNode.swift @@ -4,11 +4,11 @@ import AsyncDisplayKit import Display import TelegramPresentationData -final class ItemListEditableControlNode: ASDisplayNode { - var tapped: (() -> Void)? +public final class ItemListEditableControlNode: ASDisplayNode { + public var tapped: (() -> Void)? private let iconNode: ASImageNode - override init() { + override public init() { self.iconNode = ASImageNode() self.iconNode.isLayerBacked = true @@ -17,13 +17,13 @@ final class ItemListEditableControlNode: ASDisplayNode { self.addSubnode(self.iconNode) } - override func didLoad() { + override public func didLoad() { super.didLoad() self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) } - static func asyncLayout(_ node: ItemListEditableControlNode?) -> (_ height: CGFloat, _ theme: PresentationTheme, _ hidden: Bool) -> (CGSize, () -> ItemListEditableControlNode) { + public static func asyncLayout(_ node: ItemListEditableControlNode?) -> (_ height: CGFloat, _ theme: PresentationTheme, _ hidden: Bool) -> (CGSize, () -> ItemListEditableControlNode) { return { height, theme, hidden in let image = PresentationResourcesItemList.itemListDeleteIndicatorIcon(theme) @@ -45,7 +45,7 @@ final class ItemListEditableControlNode: ASDisplayNode { } } - @objc func tapGesture(_ recognizer: UITapGestureRecognizer) { + @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) { if case .ended = recognizer.state { self.tapped?() } diff --git a/submodules/TelegramUI/TelegramUI/ItemListEditableReorderControlNode.swift b/submodules/ItemListUI/Sources/ItemListEditableReorderControlNode.swift similarity index 79% rename from submodules/TelegramUI/TelegramUI/ItemListEditableReorderControlNode.swift rename to submodules/ItemListUI/Sources/ItemListEditableReorderControlNode.swift index ac8ff6ed17..5c2c5d6c13 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListEditableReorderControlNode.swift +++ b/submodules/ItemListUI/Sources/ItemListEditableReorderControlNode.swift @@ -4,11 +4,11 @@ import AsyncDisplayKit import Display import TelegramPresentationData -final class ItemListEditableReorderControlNode: ASDisplayNode { - var tapped: (() -> Void)? +public final class ItemListEditableReorderControlNode: ASDisplayNode { + public var tapped: (() -> Void)? private let iconNode: ASImageNode - override init() { + override public init() { self.iconNode = ASImageNode() self.iconNode.displayWithoutProcessing = true self.iconNode.displaysAsynchronously = false @@ -19,7 +19,7 @@ final class ItemListEditableReorderControlNode: ASDisplayNode { self.addSubnode(self.iconNode) } - static func asyncLayout(_ node: ItemListEditableReorderControlNode?) -> (_ height: CGFloat, _ theme: PresentationTheme) -> (CGSize, (Bool) -> ItemListEditableReorderControlNode) { + public static func asyncLayout(_ node: ItemListEditableReorderControlNode?) -> (_ height: CGFloat, _ theme: PresentationTheme) -> (CGSize, (Bool) -> ItemListEditableReorderControlNode) { return { height, theme in let image = PresentationResourcesItemList.itemListReorderIndicatorIcon(theme) diff --git a/submodules/TelegramUI/TelegramUI/ItemListItem.swift b/submodules/ItemListUI/Sources/ItemListItem.swift similarity index 60% rename from submodules/TelegramUI/TelegramUI/ItemListItem.swift rename to submodules/ItemListUI/Sources/ItemListItem.swift index 6ace1c8d6d..9f77101298 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListItem.swift +++ b/submodules/ItemListUI/Sources/ItemListItem.swift @@ -2,57 +2,62 @@ import Foundation import UIKit import Display -protocol ItemListItemTag { +public protocol ItemListItemTag { func isEqual(to other: ItemListItemTag) -> Bool } -protocol ItemListItem { +public protocol ItemListItem { var sectionId: ItemListSectionId { get } var tag: ItemListItemTag? { get } var isAlwaysPlain: Bool { get } var requestsNoInset: Bool { get } } -extension ItemListItem { - var isAlwaysPlain: Bool { +public extension ItemListItem { + public var isAlwaysPlain: Bool { return false } - var tag: ItemListItemTag? { + public var tag: ItemListItemTag? { return nil } - var requestsNoInset: Bool { + public var requestsNoInset: Bool { return false } } -protocol ItemListItemNode { +public protocol ItemListItemNode { var tag: ItemListItemTag? { get } } -protocol ItemListItemFocusableNode { +public protocol ItemListItemFocusableNode { func focus() } -enum ItemListInsetWithOtherSection { +public enum ItemListInsetWithOtherSection { case none case full case reduced } -enum ItemListNeighbor { +public enum ItemListNeighbor { case none case otherSection(ItemListInsetWithOtherSection) case sameSection(alwaysPlain: Bool) } -struct ItemListNeighbors { - var top: ItemListNeighbor - var bottom: ItemListNeighbor +public struct ItemListNeighbors { + public var top: ItemListNeighbor + public var bottom: ItemListNeighbor + + public init(top: ItemListNeighbor, bottom: ItemListNeighbor) { + self.top = top + self.bottom = bottom + } } -func itemListNeighbors(item: ItemListItem, topItem: ItemListItem?, bottomItem: ItemListItem?) -> ItemListNeighbors { +public func itemListNeighbors(item: ItemListItem, topItem: ItemListItem?, bottomItem: ItemListItem?) -> ItemListNeighbors { let topNeighbor: ItemListNeighbor if let topItem = topItem { if topItem.sectionId != item.sectionId { @@ -90,50 +95,50 @@ func itemListNeighbors(item: ItemListItem, topItem: ItemListItem?, bottomItem: I } else { bottomNeighbor = .none } - + return ItemListNeighbors(top: topNeighbor, bottom: bottomNeighbor) } -func itemListNeighborsPlainInsets(_ neighbors: ItemListNeighbors) -> UIEdgeInsets { +public func itemListNeighborsPlainInsets(_ neighbors: ItemListNeighbors) -> UIEdgeInsets { var insets = UIEdgeInsets() switch neighbors.top { - case .otherSection: - insets.top += 22.0 - case .none, .sameSection: - break + case .otherSection: + insets.top += 22.0 + case .none, .sameSection: + break } switch neighbors.bottom { - case .none: - insets.bottom += 22.0 - case .otherSection, .sameSection: - break + case .none: + insets.bottom += 22.0 + case .otherSection, .sameSection: + break } return insets } -func itemListNeighborsGroupedInsets(_ neighbors: ItemListNeighbors) -> UIEdgeInsets { +public func itemListNeighborsGroupedInsets(_ neighbors: ItemListNeighbors) -> UIEdgeInsets { let topInset: CGFloat switch neighbors.top { + case .none: + topInset = UIScreenPixel + 35.0 + case .sameSection: + topInset = 0.0 + case let .otherSection(otherInset): + switch otherInset { case .none: - topInset = UIScreenPixel + 35.0 - case .sameSection: topInset = 0.0 - case let .otherSection(otherInset): - switch otherInset { - case .none: - topInset = 0.0 - case .full: - topInset = UIScreenPixel + 35.0 - case .reduced: - topInset = UIScreenPixel + 16.0 - } + case .full: + topInset = UIScreenPixel + 35.0 + case .reduced: + topInset = UIScreenPixel + 16.0 + } } let bottomInset: CGFloat switch neighbors.bottom { - case .sameSection, .otherSection: - bottomInset = 0.0 - case .none: - bottomInset = UIScreenPixel + 35.0 + case .sameSection, .otherSection: + bottomInset = 0.0 + case .none: + bottomInset = UIScreenPixel + 35.0 } return UIEdgeInsets(top: topInset, left: 0.0, bottom: bottomInset, right: 0.0) } diff --git a/submodules/TelegramUI/TelegramUI/ItemListLoadingIndicatorEmptyStateItem.swift b/submodules/ItemListUI/Sources/ItemListLoadingIndicatorEmptyStateItem.swift similarity index 68% rename from submodules/TelegramUI/TelegramUI/ItemListLoadingIndicatorEmptyStateItem.swift rename to submodules/ItemListUI/Sources/ItemListLoadingIndicatorEmptyStateItem.swift index 0d2cadb157..3f69c19ae1 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListLoadingIndicatorEmptyStateItem.swift +++ b/submodules/ItemListUI/Sources/ItemListLoadingIndicatorEmptyStateItem.swift @@ -3,19 +3,20 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import ActivityIndicator -final class ItemListLoadingIndicatorEmptyStateItem: ItemListControllerEmptyStateItem { +public final class ItemListLoadingIndicatorEmptyStateItem: ItemListControllerEmptyStateItem { let theme: PresentationTheme - init(theme: PresentationTheme) { + public init(theme: PresentationTheme) { self.theme = theme } - func isEqual(to: ItemListControllerEmptyStateItem) -> Bool { + public func isEqual(to: ItemListControllerEmptyStateItem) -> Bool { return to is ItemListLoadingIndicatorEmptyStateItem } - func node(current: ItemListControllerEmptyStateItemNode?) -> ItemListControllerEmptyStateItemNode { + public func node(current: ItemListControllerEmptyStateItemNode?) -> ItemListControllerEmptyStateItemNode { if let current = current as? ItemListLoadingIndicatorEmptyStateItemNode { current.theme = self.theme return current @@ -25,8 +26,8 @@ final class ItemListLoadingIndicatorEmptyStateItem: ItemListControllerEmptyState } } -final class ItemListLoadingIndicatorEmptyStateItemNode: ItemListControllerEmptyStateItemNode { - var theme: PresentationTheme { +public final class ItemListLoadingIndicatorEmptyStateItemNode: ItemListControllerEmptyStateItemNode { + public var theme: PresentationTheme { didSet { self.indicator.type = .custom(self.theme.list.itemAccentColor, 40.0, 2.0, false) } @@ -35,7 +36,7 @@ final class ItemListLoadingIndicatorEmptyStateItemNode: ItemListControllerEmptyS private var validLayout: (ContainerViewLayout, CGFloat)? - init(theme: PresentationTheme) { + public init(theme: PresentationTheme) { self.theme = theme self.indicator = ActivityIndicator(type: .custom(theme.list.itemAccentColor, 22.0, 2.0, false)) @@ -44,7 +45,7 @@ final class ItemListLoadingIndicatorEmptyStateItemNode: ItemListControllerEmptyS self.addSubnode(self.indicator) } - override func updateLayout(layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { + override public func updateLayout(layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { self.validLayout = (layout, navigationBarHeight) var insets = layout.insets(options: [.statusBar]) diff --git a/submodules/TelegramUI/TelegramUI/ItemListRevealOptionsNode.swift b/submodules/ItemListUI/Sources/ItemListRevealOptionsNode.swift similarity index 83% rename from submodules/TelegramUI/TelegramUI/ItemListRevealOptionsNode.swift rename to submodules/ItemListUI/Sources/ItemListRevealOptionsNode.swift index 790f759bbb..f426a1a418 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListRevealOptionsNode.swift +++ b/submodules/ItemListUI/Sources/ItemListRevealOptionsNode.swift @@ -2,44 +2,53 @@ import Foundation import UIKit import AsyncDisplayKit import Display +import AnimationUI -enum ItemListRevealOptionIcon: Equatable { +public enum ItemListRevealOptionIcon: Equatable { case none case image(image: UIImage) case animation(animation: String, scale: CGFloat, offset: CGFloat, keysToColor: [String]?, flip: Bool) public static func ==(lhs: ItemListRevealOptionIcon, rhs: ItemListRevealOptionIcon) -> Bool { switch lhs { - case .none: - if case .none = rhs { - return true - } else { - return false - } - case let .image(lhsImage): - if case let .image(rhsImage) = rhs, lhsImage == rhsImage { - return true - } else { - return false - } - case let .animation(lhsAnimation, lhsScale, lhsOffset, lhsKeysToColor, lhsFlip): - if case let .animation(rhsAnimation, rhsScale, rhsOffset, rhsKeysToColor, rhsFlip) = rhs, lhsAnimation == rhsAnimation, lhsScale == rhsScale, lhsOffset == rhsOffset, lhsKeysToColor == rhsKeysToColor, lhsFlip == rhsFlip { - return true - } else { - return false - } + case .none: + if case .none = rhs { + return true + } else { + return false + } + case let .image(lhsImage): + if case let .image(rhsImage) = rhs, lhsImage == rhsImage { + return true + } else { + return false + } + case let .animation(lhsAnimation, lhsScale, lhsOffset, lhsKeysToColor, lhsFlip): + if case let .animation(rhsAnimation, rhsScale, rhsOffset, rhsKeysToColor, rhsFlip) = rhs, lhsAnimation == rhsAnimation, lhsScale == rhsScale, lhsOffset == rhsOffset, lhsKeysToColor == rhsKeysToColor, lhsFlip == rhsFlip { + return true + } else { + return false + } } } } -struct ItemListRevealOption: Equatable { - let key: Int32 - let title: String - let icon: ItemListRevealOptionIcon - let color: UIColor - let textColor: UIColor +public struct ItemListRevealOption: Equatable { + public let key: Int32 + public let title: String + public let icon: ItemListRevealOptionIcon + public let color: UIColor + public let textColor: UIColor - static func ==(lhs: ItemListRevealOption, rhs: ItemListRevealOption) -> Bool { + public init(key: Int32, title: String, icon: ItemListRevealOptionIcon, color: UIColor, textColor: UIColor) { + self.key = key + self.title = title + self.icon = icon + self.color = color + self.textColor = textColor + } + + public static func ==(lhs: ItemListRevealOption, rhs: ItemListRevealOption) -> Bool { if lhs.key != rhs.key { return false } @@ -86,33 +95,33 @@ private final class ItemListRevealOptionNode: ASDisplayNode { self.titleNode.attributedText = NSAttributedString(string: title, font: icon == .none ? titleFontWithoutIcon : titleFontWithIcon, textColor: textColor) switch icon { - case let .image(image): - let iconNode = ASImageNode() - iconNode.image = generateTintedImage(image: image, color: textColor) - self.iconNode = iconNode - self.animationNode = nil + case let .image(image): + let iconNode = ASImageNode() + iconNode.image = generateTintedImage(image: image, color: textColor) + self.iconNode = iconNode + self.animationNode = nil - case let .animation(animation, scale, offset, keysToColor, flip): - self.iconNode = nil - var colors: [String: UIColor] = [:] - if let keysToColor = keysToColor { - for key in keysToColor { - colors[key] = color - } + case let .animation(animation, scale, offset, keysToColor, flip): + self.iconNode = nil + var colors: [String: UIColor] = [:] + if let keysToColor = keysToColor { + for key in keysToColor { + colors[key] = color } - self.animationNode = AnimationNode(animation: animation, colors: colors, scale: scale) - if flip { - self.animationNode!.transform = CATransform3DMakeScale(1.0, -1.0, 1.0) - } - self.animationNodeOffset = offset - self.animationNodeFlip = flip - break + } + self.animationNode = AnimationNode(animation: animation, colors: colors, scale: scale) + if flip { + self.animationNode!.transform = CATransform3DMakeScale(1.0, -1.0, 1.0) + } + self.animationNodeOffset = offset + self.animationNodeFlip = flip + break - case .none: - self.iconNode = nil - self.animationNode = nil + case .none: + self.iconNode = nil + self.animationNode = nil } - + super.init() self.addSubnode(self.backgroundNode) @@ -129,7 +138,7 @@ private final class ItemListRevealOptionNode: ASDisplayNode { func setHighlighted(_ highlighted: Bool) { if highlighted { self.insertSubnode(self.highlightNode, aboveSubnode: self.backgroundNode) - self.highlightNode.layer.animate(from: 0.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "opacity", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.3) + self.highlightNode.layer.animate(from: 0.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "opacity", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.3) self.highlightNode.alpha = 1.0 } else { self.highlightNode.removeFromSupernode() @@ -177,10 +186,10 @@ private final class ItemListRevealOptionNode: ASDisplayNode { let titleSize = self.titleNode.calculatedSize var contentRect = CGRect(origin: CGPoint(), size: baseSize) switch alignment { - case .left: - contentRect.origin.x = 0.0 - case .right: - contentRect.origin.x = extendedWidth - contentRect.width + case .left: + contentRect.origin.x = 0.0 + case .right: + contentRect.origin.x = extendedWidth - contentRect.width } if let animationNode = self.animationNode, let imageSize = animationNode.preferredSize() { @@ -251,7 +260,7 @@ private final class ItemListRevealOptionNode: ASDisplayNode { } } -final class ItemListRevealOptionsNode: ASDisplayNode { +public final class ItemListRevealOptionsNode: ASDisplayNode { private let optionSelected: (ItemListRevealOption) -> Void private let tapticAction: () -> Void @@ -262,14 +271,14 @@ final class ItemListRevealOptionsNode: ASDisplayNode { private var revealOffset: CGFloat = 0.0 private var sideInset: CGFloat = 0.0 - init(optionSelected: @escaping (ItemListRevealOption) -> Void, tapticAction: @escaping () -> Void) { + public init(optionSelected: @escaping (ItemListRevealOption) -> Void, tapticAction: @escaping () -> Void) { self.optionSelected = optionSelected self.tapticAction = tapticAction super.init() } - override func didLoad() { + override public func didLoad() { super.didLoad() let gestureRecognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))) @@ -290,7 +299,7 @@ final class ItemListRevealOptionsNode: ASDisplayNode { self.view.addGestureRecognizer(gestureRecognizer) } - func setOptions(_ options: [ItemListRevealOption], isLeft: Bool) { + public func setOptions(_ options: [ItemListRevealOption], isLeft: Bool) { if self.options != options || self.isLeft != isLeft { self.options = options self.isLeft = isLeft @@ -313,7 +322,7 @@ final class ItemListRevealOptionsNode: ASDisplayNode { } } - override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { + override public func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { var maxWidth: CGFloat = 0.0 for node in self.optionNodes { let nodeSize = node.measure(constrainedSize) @@ -322,7 +331,7 @@ final class ItemListRevealOptionsNode: ASDisplayNode { return CGSize(width: maxWidth * CGFloat(self.optionNodes.count), height: constrainedSize.height) } - func updateRevealOffset(offset: CGFloat, sideInset: CGFloat, transition: ContainedViewLayoutTransition) { + public func updateRevealOffset(offset: CGFloat, sideInset: CGFloat, transition: ContainedViewLayoutTransition) { self.revealOffset = offset self.sideInset = sideInset self.updateNodesLayout(transition: transition) @@ -363,7 +372,6 @@ final class ItemListRevealOptionsNode: ASDisplayNode { while i >= 0 && i < self.optionNodes.count { let node = self.optionNodes[i] let nodeWidth = i == (self.optionNodes.count - 1) ? lastNodeWidth : basicNodeWidth - let defaultAlignment: ItemListRevealOptionAlignment = self.isLeft ? .right : .left var nodeTransition = transition var isExpanded = false if (self.isLeft && i == 0) || (!self.isLeft && i == self.optionNodes.count - 1) { @@ -401,7 +409,7 @@ final class ItemListRevealOptionsNode: ASDisplayNode { transition.updateFrame(node: node, frame: CGRect(origin: CGPoint(x: nodeLeftOffset, y: 0.0), size: CGSize(width: extendedWidth, height: size.height)), completion: { _ in completionCount -= 1 intermediateCompletion() - + }) var nodeAlignment: ItemListRevealOptionAlignment @@ -425,7 +433,7 @@ final class ItemListRevealOptionsNode: ASDisplayNode { } } - @objc func tapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { + @objc private func tapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { if case .ended = recognizer.state, let gesture = recognizer.lastRecognizedGestureAndLocation?.0, case .tap = gesture { let location = recognizer.location(in: self.view) var selectedOption: Int? @@ -449,7 +457,7 @@ final class ItemListRevealOptionsNode: ASDisplayNode { } } - func isDisplayingExtendedAction() -> Bool { + public func isDisplayingExtendedAction() -> Bool { return self.optionNodes.contains(where: { $0.isExpanded }) } } diff --git a/submodules/TelegramUI/TelegramUI/ItemListSelectableControlNode.swift b/submodules/ItemListUI/Sources/ItemListSelectableControlNode.swift similarity index 74% rename from submodules/TelegramUI/TelegramUI/ItemListSelectableControlNode.swift rename to submodules/ItemListUI/Sources/ItemListSelectableControlNode.swift index 0964cd7ecd..e8dfcefe5e 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListSelectableControlNode.swift +++ b/submodules/ItemListUI/Sources/ItemListSelectableControlNode.swift @@ -2,11 +2,12 @@ import Foundation import UIKit import AsyncDisplayKit import Display +import CheckNode -final class ItemListSelectableControlNode: ASDisplayNode { +public final class ItemListSelectableControlNode: ASDisplayNode { private let checkNode: CheckNode - init(strokeColor: UIColor, fillColor: UIColor, foregroundColor: UIColor) { + public init(strokeColor: UIColor, fillColor: UIColor, foregroundColor: UIColor) { self.checkNode = CheckNode(strokeColor: strokeColor, fillColor: fillColor, foregroundColor: foregroundColor, style: .plain) self.checkNode.isUserInteractionEnabled = false @@ -15,7 +16,7 @@ final class ItemListSelectableControlNode: ASDisplayNode { self.addSubnode(self.checkNode) } - static func asyncLayout(_ node: ItemListSelectableControlNode?) -> (_ strokeColor: UIColor, _ fillColor: UIColor, _ foregroundColor: UIColor, _ selected: Bool, _ compact: Bool) -> (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode) { + public static func asyncLayout(_ node: ItemListSelectableControlNode?) -> (_ strokeColor: UIColor, _ fillColor: UIColor, _ foregroundColor: UIColor, _ selected: Bool, _ compact: Bool) -> (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode) { return { strokeColor, fillColor, foregroundColor, selected, compact in let resultNode: ItemListSelectableControlNode if let node = node { diff --git a/submodules/ItemListUI/Sources/ItemListUI.h b/submodules/ItemListUI/Sources/ItemListUI.h new file mode 100644 index 0000000000..6bea7bc2a3 --- /dev/null +++ b/submodules/ItemListUI/Sources/ItemListUI.h @@ -0,0 +1,19 @@ +// +// ItemListUI.h +// ItemListUI +// +// Created by Peter on 8/1/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for ItemListUI. +FOUNDATION_EXPORT double ItemListUIVersionNumber; + +//! Project version string for ItemListUI. +FOUNDATION_EXPORT const unsigned char ItemListUIVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/TelegramUI/TelegramUI/ItemListActionItem.swift b/submodules/ItemListUI/Sources/Items/ItemListActionItem.swift similarity index 86% rename from submodules/TelegramUI/TelegramUI/ItemListActionItem.swift rename to submodules/ItemListUI/Sources/Items/ItemListActionItem.swift index 398d3e3d05..b29cbafe1b 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListActionItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListActionItem.swift @@ -5,31 +5,31 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData -enum ItemListActionKind { +public enum ItemListActionKind { case generic case destructive case neutral case disabled } -enum ItemListActionAlignment { +public enum ItemListActionAlignment { case natural case center } -class ItemListActionItem: ListViewItem, ItemListItem { +public class ItemListActionItem: ListViewItem, ItemListItem { let theme: PresentationTheme let title: String let kind: ItemListActionKind let alignment: ItemListActionAlignment - let sectionId: ItemListSectionId + public let sectionId: ItemListSectionId let style: ItemListStyle - let action: () -> Void + public let action: () -> Void let longTapAction: (() -> Void)? let clearHighlightAutomatically: Bool - let tag: Any? + public let tag: Any? - init(theme: PresentationTheme, title: String, kind: ItemListActionKind, alignment: ItemListActionAlignment, sectionId: ItemListSectionId, style: ItemListStyle, action: @escaping () -> Void, longTapAction: (() -> Void)? = nil, clearHighlightAutomatically: Bool = true, tag: Any? = nil) { + public init(theme: PresentationTheme, title: String, kind: ItemListActionKind, alignment: ItemListActionAlignment, sectionId: ItemListSectionId, style: ItemListStyle, action: @escaping () -> Void, longTapAction: (() -> Void)? = nil, clearHighlightAutomatically: Bool = true, tag: Any? = nil) { self.theme = theme self.title = title self.kind = kind @@ -42,7 +42,7 @@ class ItemListActionItem: ListViewItem, ItemListItem { self.tag = tag } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListActionItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -58,7 +58,7 @@ class ItemListActionItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListActionItemNode { let makeLayout = nodeValue.asyncLayout() @@ -75,9 +75,9 @@ class ItemListActionItem: ListViewItem, ItemListItem { } } - var selectable: Bool = true + public var selectable: Bool = true - func selected(listView: ListView){ + public func selected(listView: ListView){ if self.clearHighlightAutomatically { listView.clearHighlightAnimated(true) } @@ -87,7 +87,7 @@ class ItemListActionItem: ListViewItem, ItemListItem { private let titleFont = Font.regular(17.0) -class ItemListActionItemNode: ListViewItemNode, ItemListItemNode { +public class ItemListActionItemNode: ListViewItemNode, ItemListItemNode { private let backgroundNode: ASDisplayNode private let topStripeNode: ASDisplayNode private let bottomStripeNode: ASDisplayNode @@ -99,11 +99,11 @@ class ItemListActionItemNode: ListViewItemNode, ItemListItemNode { private var item: ItemListActionItem? - var tag: ItemListItemTag? { + public var tag: ItemListItemTag? { return self.item?.tag as? ItemListItemTag } - init() { + public init() { self.backgroundNode = ASDisplayNode() self.backgroundNode.isLayerBacked = true self.backgroundNode.backgroundColor = .white @@ -131,7 +131,7 @@ class ItemListActionItemNode: ListViewItemNode, ItemListItemNode { self.addSubnode(self.activateArea) } - func asyncLayout() -> (_ item: ItemListActionItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { + public func asyncLayout() -> (_ item: ItemListActionItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { let makeTitleLayout = TextNode.asyncLayout(self.titleNode) let currentItem = self.item @@ -185,10 +185,10 @@ class ItemListActionItemNode: ListViewItemNode, ItemListItemNode { strongSelf.activateArea.frame = CGRect(origin: CGPoint(x: params.leftInset, y: 0.0), size: CGSize(width: params.width - params.leftInset - params.rightInset, height: layout.contentSize.height)) strongSelf.activateArea.accessibilityLabel = item.title - var accessibilityTraits: UIAccessibilityTraits = UIAccessibilityTraitButton + var accessibilityTraits: UIAccessibilityTraits = .button switch item.kind { case .disabled: - accessibilityTraits |= UIAccessibilityTraitNotEnabled + accessibilityTraits.insert(.notEnabled) default: break } @@ -262,7 +262,7 @@ class ItemListActionItemNode: ListViewItemNode, ItemListItemNode { } } - override func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { + override public func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { super.setHighlighted(highlighted, at: point, animated: animated) if highlighted && self.item?.kind != ItemListActionKind.disabled { @@ -300,19 +300,19 @@ class ItemListActionItemNode: ListViewItemNode, ItemListItemNode { } } - override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { + override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } - override func longTapped() { + override public func longTapped() { self.item?.longTapAction?() } - override var canBeLongTapped: Bool { + override public var canBeLongTapped: Bool { return self.item?.longTapAction != nil } } diff --git a/submodules/TelegramUI/TelegramUI/ItemListActivityTextItem.swift b/submodules/ItemListUI/Sources/Items/ItemListActivityTextItem.swift similarity index 74% rename from submodules/TelegramUI/TelegramUI/ItemListActivityTextItem.swift rename to submodules/ItemListUI/Sources/Items/ItemListActivityTextItem.swift index 360e1f4a1c..260e05dc3a 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListActivityTextItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListActivityTextItem.swift @@ -4,23 +4,24 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ActivityIndicator -class ItemListActivityTextItem: ListViewItem, ItemListItem { +public class ItemListActivityTextItem: ListViewItem, ItemListItem { let displayActivity: Bool let theme: PresentationTheme let text: NSAttributedString - let sectionId: ItemListSectionId + public let sectionId: ItemListSectionId - let isAlwaysPlain: Bool = true + public let isAlwaysPlain: Bool = true - init(displayActivity: Bool, theme: PresentationTheme, text: NSAttributedString, sectionId: ItemListSectionId) { + public init(displayActivity: Bool, theme: PresentationTheme, text: NSAttributedString, sectionId: ItemListSectionId) { self.displayActivity = displayActivity self.theme = theme self.text = text self.sectionId = sectionId } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListActivityTextItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -36,7 +37,7 @@ class ItemListActivityTextItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { guard let nodeValue = node() as? ItemListActivityTextItemNode else { assertionFailure() @@ -59,13 +60,13 @@ class ItemListActivityTextItem: ListViewItem, ItemListItem { private let titleFont = Font.regular(14.0) -class ItemListActivityTextItemNode: ListViewItemNode { +public class ItemListActivityTextItemNode: ListViewItemNode { private let titleNode: TextNode private let activityIndicator: ActivityIndicator private var item: ItemListActivityTextItem? - init() { + public init() { self.titleNode = TextNode() self.titleNode.isUserInteractionEnabled = false self.titleNode.contentMode = .left @@ -79,7 +80,7 @@ class ItemListActivityTextItemNode: ListViewItemNode { self.addSubnode(self.activityIndicator) } - func asyncLayout() -> (_ item: ItemListActivityTextItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { + public func asyncLayout() -> (_ item: ItemListActivityTextItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { let makeTitleLayout = TextNode.asyncLayout(self.titleNode) return { item, params, neighbors in @@ -94,8 +95,8 @@ class ItemListActivityTextItemNode: ListViewItemNode { let titleString = NSMutableAttributedString(attributedString: item.text) let hasFont = titleString.attribute(.font, at: 0, effectiveRange: nil) != nil if !hasFont { - titleString.removeAttribute(NSAttributedStringKey.font, range: NSMakeRange(0, titleString.length)) - titleString.addAttributes([NSAttributedStringKey.font: titleFont], range: NSMakeRange(0, titleString.length)) + titleString.removeAttribute(NSAttributedString.Key.font, range: NSMakeRange(0, titleString.length)) + titleString.addAttributes([NSAttributedString.Key.font: titleFont], range: NSMakeRange(0, titleString.length)) } let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleString, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - 20.0 - 22.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: TextNodeCutout(topLeft: CGSize(width: activityWidth, height: 4.0)), insets: UIEdgeInsets())) @@ -129,11 +130,11 @@ class ItemListActivityTextItemNode: ListViewItemNode { } } - override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { + override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } } diff --git a/submodules/TelegramUI/TelegramUI/ItemListCheckboxItem.swift b/submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift similarity index 87% rename from submodules/TelegramUI/TelegramUI/ItemListCheckboxItem.swift rename to submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift index bf2627c198..baa49f05a4 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListCheckboxItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift @@ -5,27 +5,27 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData -enum ItemListCheckboxItemStyle { +public enum ItemListCheckboxItemStyle { case left case right } -enum ItemListCheckboxItemColor { +public enum ItemListCheckboxItemColor { case accent case secondary } -class ItemListCheckboxItem: ListViewItem, ItemListItem { +public class ItemListCheckboxItem: ListViewItem, ItemListItem { let theme: PresentationTheme let title: String let style: ItemListCheckboxItemStyle let color: ItemListCheckboxItemColor let checked: Bool let zeroSeparatorInsets: Bool - let sectionId: ItemListSectionId + public let sectionId: ItemListSectionId let action: () -> Void - init(theme: PresentationTheme, title: String, style: ItemListCheckboxItemStyle, color: ItemListCheckboxItemColor = .accent, checked: Bool, zeroSeparatorInsets: Bool, sectionId: ItemListSectionId, action: @escaping () -> Void) { + public init(theme: PresentationTheme, title: String, style: ItemListCheckboxItemStyle, color: ItemListCheckboxItemColor = .accent, checked: Bool, zeroSeparatorInsets: Bool, sectionId: ItemListSectionId, action: @escaping () -> Void) { self.theme = theme self.title = title self.style = style @@ -36,7 +36,7 @@ class ItemListCheckboxItem: ListViewItem, ItemListItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListCheckboxItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -52,7 +52,7 @@ class ItemListCheckboxItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListCheckboxItemNode { let makeLayout = nodeValue.asyncLayout() @@ -69,9 +69,9 @@ class ItemListCheckboxItem: ListViewItem, ItemListItem { } } - var selectable: Bool = true + public var selectable: Bool = true - func selected(listView: ListView){ + public func selected(listView: ListView){ listView.clearHighlightAnimated(true) self.action() } @@ -79,7 +79,7 @@ class ItemListCheckboxItem: ListViewItem, ItemListItem { private let titleFont = Font.regular(17.0) -class ItemListCheckboxItemNode: ListViewItemNode { +public class ItemListCheckboxItemNode: ListViewItemNode { private let backgroundNode: ASDisplayNode private let topStripeNode: ASDisplayNode private let bottomStripeNode: ASDisplayNode @@ -92,7 +92,7 @@ class ItemListCheckboxItemNode: ListViewItemNode { private var item: ItemListCheckboxItem? - init() { + public init() { self.backgroundNode = ASDisplayNode() self.backgroundNode.isLayerBacked = true @@ -129,7 +129,7 @@ class ItemListCheckboxItemNode: ListViewItemNode { } } - func asyncLayout() -> (_ item: ItemListCheckboxItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { + public func asyncLayout() -> (_ item: ItemListCheckboxItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { let makeTitleLayout = TextNode.asyncLayout(self.titleNode) let currentItem = self.item @@ -243,7 +243,7 @@ class ItemListCheckboxItemNode: ListViewItemNode { } } - override func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { + override public func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { super.setHighlighted(highlighted, at: point, animated: animated) if highlighted { @@ -281,11 +281,11 @@ class ItemListCheckboxItemNode: ListViewItemNode { } } - override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { + override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } } diff --git a/submodules/TelegramUI/TelegramUI/ItemListDisclosureItem.swift b/submodules/ItemListUI/Sources/Items/ItemListDisclosureItem.swift similarity index 90% rename from submodules/TelegramUI/TelegramUI/ItemListDisclosureItem.swift rename to submodules/ItemListUI/Sources/Items/ItemListDisclosureItem.swift index 8f480b8912..bfcda62617 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListDisclosureItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListDisclosureItem.swift @@ -5,17 +5,17 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData -enum ItemListDisclosureItemTitleColor { +public enum ItemListDisclosureItemTitleColor { case primary case accent } -enum ItemListDisclosureStyle { +public enum ItemListDisclosureStyle { case arrow case none } -enum ItemListDisclosureLabelStyle { +public enum ItemListDisclosureLabelStyle { case text case detailText case multilineDetailText @@ -23,7 +23,7 @@ enum ItemListDisclosureLabelStyle { case color(UIColor) } -class ItemListDisclosureItem: ListViewItem, ItemListItem { +public class ItemListDisclosureItem: ListViewItem, ItemListItem { let theme: PresentationTheme let icon: UIImage? let title: String @@ -31,14 +31,14 @@ class ItemListDisclosureItem: ListViewItem, ItemListItem { let enabled: Bool let label: String let labelStyle: ItemListDisclosureLabelStyle - let sectionId: ItemListSectionId + public let sectionId: ItemListSectionId let style: ItemListStyle let disclosureStyle: ItemListDisclosureStyle let action: (() -> Void)? let clearHighlightAutomatically: Bool - let tag: ItemListItemTag? + public let tag: ItemListItemTag? - init(theme: PresentationTheme, icon: UIImage? = nil, title: String, enabled: Bool = true, titleColor: ItemListDisclosureItemTitleColor = .primary, label: String, labelStyle: ItemListDisclosureLabelStyle = .text, sectionId: ItemListSectionId, style: ItemListStyle, disclosureStyle: ItemListDisclosureStyle = .arrow, action: (() -> Void)?, clearHighlightAutomatically: Bool = true, tag: ItemListItemTag? = nil) { + public init(theme: PresentationTheme, icon: UIImage? = nil, title: String, enabled: Bool = true, titleColor: ItemListDisclosureItemTitleColor = .primary, label: String, labelStyle: ItemListDisclosureLabelStyle = .text, sectionId: ItemListSectionId, style: ItemListStyle, disclosureStyle: ItemListDisclosureStyle = .arrow, action: (() -> Void)?, clearHighlightAutomatically: Bool = true, tag: ItemListItemTag? = nil) { self.theme = theme self.icon = icon self.title = title @@ -54,7 +54,7 @@ class ItemListDisclosureItem: ListViewItem, ItemListItem { self.tag = tag } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListDisclosureItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -70,7 +70,7 @@ class ItemListDisclosureItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListDisclosureItemNode { let makeLayout = nodeValue.asyncLayout() @@ -87,9 +87,9 @@ class ItemListDisclosureItem: ListViewItem, ItemListItem { } } - var selectable: Bool = true + public var selectable: Bool = true - func selected(listView: ListView){ + public func selected(listView: ListView){ if self.clearHighlightAutomatically { listView.clearHighlightAnimated(true) } @@ -103,7 +103,7 @@ private let titleFont = Font.regular(17.0) private let badgeFont = Font.regular(15.0) private let detailFont = Font.regular(13.0) -class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode { +public class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode { private let backgroundNode: ASDisplayNode private let topStripeNode: ASDisplayNode private let bottomStripeNode: ASDisplayNode @@ -120,7 +120,7 @@ class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode { private var item: ItemListDisclosureItem? - override var canBeSelected: Bool { + override public var canBeSelected: Bool { if let item = self.item, let _ = item.action { return true } else { @@ -128,11 +128,11 @@ class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode { } } - var tag: ItemListItemTag? { + public var tag: ItemListItemTag? { return self.item?.tag } - init() { + public init() { self.backgroundNode = ASDisplayNode() self.backgroundNode.isLayerBacked = true self.backgroundNode.backgroundColor = .white @@ -178,7 +178,7 @@ class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode { self.addSubnode(self.activateArea) } - func asyncLayout() -> (_ item: ItemListDisclosureItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { + public func asyncLayout() -> (_ item: ItemListDisclosureItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { let makeTitleLayout = TextNode.asyncLayout(self.titleNode) let makeLabelLayout = TextNode.asyncLayout(self.labelNode) @@ -308,9 +308,9 @@ class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode { strongSelf.activateArea.accessibilityLabel = item.title strongSelf.activateArea.accessibilityValue = item.label if item.enabled { - strongSelf.activateArea.accessibilityTraits = 0 + strongSelf.activateArea.accessibilityTraits = [] } else { - strongSelf.activateArea.accessibilityTraits = UIAccessibilityTraitNotEnabled + strongSelf.activateArea.accessibilityTraits = .notEnabled } if let icon = item.icon { @@ -447,7 +447,7 @@ class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode { } } - override func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { + override public func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { super.setHighlighted(highlighted, at: point, animated: animated) if highlighted && (self.item?.enabled ?? false) { @@ -485,15 +485,15 @@ class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode { } } - override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { + override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } - override func animateAdded(_ currentTimestamp: Double, duration: Double) { + override public func animateAdded(_ currentTimestamp: Double, duration: Double) { self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } } diff --git a/submodules/TelegramUI/TelegramUI/ItemListEditableItem.swift b/submodules/ItemListUI/Sources/Items/ItemListEditableItem.swift similarity index 89% rename from submodules/TelegramUI/TelegramUI/ItemListEditableItem.swift rename to submodules/ItemListUI/Sources/Items/ItemListEditableItem.swift index 026cb16ab2..efd9e4e4c2 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListEditableItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListEditableItem.swift @@ -3,37 +3,37 @@ import UIKit import Display import AsyncDisplayKit -final class ItemListRevealOptionsGestureRecognizer: UIPanGestureRecognizer { - var validatedGesture = false - var firstLocation: CGPoint = CGPoint() +public final class ItemListRevealOptionsGestureRecognizer: UIPanGestureRecognizer { + public var validatedGesture = false + public var firstLocation: CGPoint = CGPoint() - var allowAnyDirection = false - var lastVelocity: CGPoint = CGPoint() + public var allowAnyDirection = false + public var lastVelocity: CGPoint = CGPoint() - override init(target: Any?, action: Selector?) { + override public init(target: Any?, action: Selector?) { super.init(target: target, action: action) self.maximumNumberOfTouches = 1 } - override func reset() { + override public func reset() { super.reset() self.validatedGesture = false } - func becomeCancelled() { + public func becomeCancelled() { self.state = .cancelled } - override func touchesBegan(_ touches: Set, with event: UIEvent) { + override public func touchesBegan(_ touches: Set, with event: UIEvent) { super.touchesBegan(touches, with: event) let touch = touches.first! self.firstLocation = touch.location(in: self.view) } - override func touchesMoved(_ touches: Set, with event: UIEvent) { + override public func touchesMoved(_ touches: Set, with event: UIEvent) { let location = touches.first!.location(in: self.view) let translation = CGPoint(x: location.x - self.firstLocation.x, y: location.y - self.firstLocation.y) @@ -54,7 +54,7 @@ final class ItemListRevealOptionsGestureRecognizer: UIPanGestureRecognizer { } } -class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelegate { +open class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelegate { private var validLayout: (CGSize, CGFloat, CGFloat)? private var leftRevealNode: ItemListRevealOptionsNode? @@ -62,7 +62,7 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega private var revealOptions: (left: [ItemListRevealOption], right: [ItemListRevealOption]) = ([], []) private var initialRevealOffset: CGFloat = 0.0 - private(set) var revealOffset: CGFloat = 0.0 + public private(set) var revealOffset: CGFloat = 0.0 private var recognizer: ItemListRevealOptionsGestureRecognizer? private var tapRecognizer: UITapGestureRecognizer? @@ -70,19 +70,19 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega private var allowAnyDirection = false - var isDisplayingRevealedOptions: Bool { + public var isDisplayingRevealedOptions: Bool { return !self.revealOffset.isZero } - override var canBeSelected: Bool { + override open var canBeSelected: Bool { return !self.isDisplayingRevealedOptions } - override init(layerBacked: Bool, dynamicBounce: Bool, rotated: Bool, seeThrough: Bool) { + override public init(layerBacked: Bool, dynamicBounce: Bool, rotated: Bool, seeThrough: Bool) { super.init(layerBacked: layerBacked, dynamicBounce: dynamicBounce, rotated: rotated, seeThrough: seeThrough) } - override func didLoad() { + override open func didLoad() { super.didLoad() let recognizer = ItemListRevealOptionsGestureRecognizer(target: self, action: #selector(self.revealGesture(_:))) @@ -98,7 +98,7 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega self.view.disablesInteractiveTransitionGestureRecognizer = self.allowAnyDirection } - func setRevealOptions(_ options: (left: [ItemListRevealOption], right: [ItemListRevealOption])) { + open func setRevealOptions(_ options: (left: [ItemListRevealOption], right: [ItemListRevealOption])) { if self.revealOptions == options { return } @@ -143,7 +143,7 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega } } - override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { + override open func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { if let recognizer = self.recognizer, gestureRecognizer == self.tapRecognizer { return abs(self.revealOffset) > 0.0 && !recognizer.validatedGesture } else { @@ -151,7 +151,7 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega } } - func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { + open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { if let recognizer = self.recognizer, otherGestureRecognizer == recognizer { return true } else { @@ -159,14 +159,14 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega } } - @objc func revealTapGesture(_ recognizer: UITapGestureRecognizer) { + @objc private func revealTapGesture(_ recognizer: UITapGestureRecognizer) { if case .ended = recognizer.state { self.updateRevealOffsetInternal(offset: 0.0, transition: .animated(duration: 0.3, curve: .spring)) self.revealOptionsInteractivelyClosed() } } - @objc func revealGesture(_ recognizer: ItemListRevealOptionsGestureRecognizer) { + @objc private func revealGesture(_ recognizer: ItemListRevealOptionsGestureRecognizer) { guard let (size, _, _) = self.validLayout else { return } @@ -336,7 +336,7 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega } } - func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) { + public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) { self.validLayout = (size, leftInset, rightInset) if let leftRevealNode = self.leftRevealNode { @@ -352,7 +352,7 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega } } - func updateRevealOffsetInternal(offset: CGFloat, transition: ContainedViewLayoutTransition, completion: (() -> Void)? = nil) { + open func updateRevealOffsetInternal(offset: CGFloat, transition: ContainedViewLayoutTransition, completion: (() -> Void)? = nil) { self.revealOffset = offset guard let (size, leftInset, rightInset) = self.validLayout else { return @@ -425,19 +425,19 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega self.updateRevealOffset(offset: offset, transition: transition) } - func updateRevealOffset(offset: CGFloat, transition: ContainedViewLayoutTransition) { + open func updateRevealOffset(offset: CGFloat, transition: ContainedViewLayoutTransition) { } - func revealOptionsInteractivelyOpened() { + open func revealOptionsInteractivelyOpened() { } - func revealOptionsInteractivelyClosed() { + open func revealOptionsInteractivelyClosed() { } - func setRevealOptionsOpened(_ value: Bool, animated: Bool) { + open func setRevealOptionsOpened(_ value: Bool, animated: Bool) { if value != !self.revealOffset.isZero { if !self.revealOffset.isZero { self.recognizer?.becomeCancelled() @@ -463,7 +463,7 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega } } - func animateRevealOptionsFill(completion: (() -> Void)? = nil) { + open func animateRevealOptionsFill(completion: (() -> Void)? = nil) { if let validLayout = self.validLayout { self.layer.allowsGroupOpacity = true self.updateRevealOffsetInternal(offset: -validLayout.0.width - 74.0, transition: .animated(duration: 0.2, curve: .spring), completion: { @@ -473,14 +473,14 @@ class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerDelega } } - func revealOptionSelected(_ option: ItemListRevealOption, animated: Bool) { + open func revealOptionSelected(_ option: ItemListRevealOption, animated: Bool) { } - override var preventsTouchesToOtherItems: Bool { + override open var preventsTouchesToOtherItems: Bool { return self.isDisplayingRevealedOptions } - override func touchesToOtherItemsPrevented() { + override open func touchesToOtherItemsPrevented() { if self.isDisplayingRevealedOptions { self.setRevealOptionsOpened(false, animated: true) } diff --git a/submodules/TelegramUI/TelegramUI/ItemListMultilineInputItem.swift b/submodules/ItemListUI/Sources/Items/ItemListMultilineInputItem.swift similarity index 84% rename from submodules/TelegramUI/TelegramUI/ItemListMultilineInputItem.swift rename to submodules/ItemListUI/Sources/Items/ItemListMultilineInputItem.swift index 12dd2fd505..271f2a0a56 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListMultilineInputItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListMultilineInputItem.swift @@ -5,23 +5,28 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData -struct ItemListMultilineInputItemTextLimit { - let value: Int - let display: Bool +public struct ItemListMultilineInputItemTextLimit { + public let value: Int + public let display: Bool + + public init(value: Int, display: Bool) { + self.value = value + self.display = display + } } -class ItemListMultilineInputItem: ListViewItem, ItemListItem { +public class ItemListMultilineInputItem: ListViewItem, ItemListItem { let theme: PresentationTheme let text: String let placeholder: String - let sectionId: ItemListSectionId + public let sectionId: ItemListSectionId let style: ItemListStyle let action: () -> Void let textUpdated: (String) -> Void - let tag: ItemListItemTag? + public let tag: ItemListItemTag? let maxLength: ItemListMultilineInputItemTextLimit? - init(theme: PresentationTheme, text: String, placeholder: String, maxLength: ItemListMultilineInputItemTextLimit?, sectionId: ItemListSectionId, style: ItemListStyle, textUpdated: @escaping (String) -> Void, tag: ItemListItemTag? = nil, action: @escaping () -> Void) { + public init(theme: PresentationTheme, text: String, placeholder: String, maxLength: ItemListMultilineInputItemTextLimit?, sectionId: ItemListSectionId, style: ItemListStyle, textUpdated: @escaping (String) -> Void, tag: ItemListItemTag? = nil, action: @escaping () -> Void) { self.theme = theme self.text = text self.placeholder = placeholder @@ -33,7 +38,7 @@ class ItemListMultilineInputItem: ListViewItem, ItemListItem { self.action = action } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListMultilineInputItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -49,7 +54,7 @@ class ItemListMultilineInputItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListMultilineInputItemNode { let makeLayout = nodeValue.asyncLayout() @@ -69,7 +74,7 @@ class ItemListMultilineInputItem: ListViewItem, ItemListItem { private let titleFont = Font.regular(17.0) -class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNodeDelegate, ItemListItemNode, ItemListItemFocusableNode { +public class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNodeDelegate, ItemListItemNode, ItemListItemFocusableNode { private let backgroundNode: ASDisplayNode private let topStripeNode: ASDisplayNode private let bottomStripeNode: ASDisplayNode @@ -83,11 +88,11 @@ class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNodeDelega private var item: ItemListMultilineInputItem? private var layoutParams: ListViewItemLayoutParams? - var tag: ItemListItemTag? { + public var tag: ItemListItemTag? { return self.item?.tag } - init() { + public init() { self.backgroundNode = ASDisplayNode() self.backgroundNode.isLayerBacked = true @@ -112,20 +117,20 @@ class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNodeDelega } - override func didLoad() { + override public func didLoad() { super.didLoad() var textColor: UIColor = .black if let item = self.item { textColor = item.theme.list.itemPrimaryTextColor } - self.textNode.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(17.0), NSAttributedStringKey.foregroundColor.rawValue: textColor] + self.textNode.typingAttributes = [NSAttributedString.Key.font.rawValue: Font.regular(17.0), NSAttributedString.Key.foregroundColor.rawValue: textColor] self.textNode.clipsToBounds = true self.textNode.delegate = self self.textNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0) } - func asyncLayout() -> (_ item: ItemListMultilineInputItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { + public func asyncLayout() -> (_ item: ItemListMultilineInputItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { let makeTextLayout = TextNode.asyncLayout(self.measureTextNode) let makeLimitTextLayout = TextNode.asyncLayout(self.limitTextNode) @@ -202,7 +207,7 @@ class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNodeDelega strongSelf.backgroundNode.backgroundColor = itemBackgroundColor if strongSelf.isNodeLoaded { - strongSelf.textNode.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(17.0), NSAttributedStringKey.foregroundColor.rawValue: item.theme.list.itemPrimaryTextColor] + strongSelf.textNode.typingAttributes = [NSAttributedString.Key.font.rawValue: Font.regular(17.0), NSAttributedString.Key.foregroundColor.rawValue: item.theme.list.itemPrimaryTextColor] } } @@ -264,15 +269,15 @@ class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNodeDelega } } - override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { + override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } - override func animateFrameTransition(_ progress: CGFloat, _ currentValue: CGFloat) { + override public func animateFrameTransition(_ progress: CGFloat, _ currentValue: CGFloat) { super.animateFrameTransition(progress, currentValue) guard let params = self.layoutParams else { @@ -293,7 +298,7 @@ class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNodeDelega self.textClippingNode.frame = CGRect(origin: CGPoint(x: leftInset, y: textTopInset), size: CGSize(width: max(0.0, params.width - leftInset - params.rightInset), height: max(0.0, contentSize.height - textTopInset - textBottomInset))) } - func editableTextNodeDidUpdateText(_ editableTextNode: ASEditableTextNode) { + public func editableTextNodeDidUpdateText(_ editableTextNode: ASEditableTextNode) { if let item = self.item { if let text = self.textNode.attributedText { let updatedText = text.string @@ -308,7 +313,7 @@ class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNodeDelega } } - func editableTextNodeShouldPaste(_ editableTextNode: ASEditableTextNode) -> Bool { + public func editableTextNodeShouldPaste(_ editableTextNode: ASEditableTextNode) -> Bool { if let _ = self.item { let text: String? = UIPasteboard.general.string if let _ = text { @@ -318,13 +323,13 @@ class ItemListMultilineInputItemNode: ListViewItemNode, ASEditableTextNodeDelega return false } - func focus() { + public func focus() { if !self.textNode.textView.isFirstResponder { self.textNode.textView.becomeFirstResponder() } } - func animateError() { + public func animateError() { self.textNode.layer.addShakeAnimation() } } diff --git a/submodules/TelegramUI/TelegramUI/ItemListMultilineTextItem.swift b/submodules/ItemListUI/Sources/Items/ItemListMultilineTextItem.swift similarity index 87% rename from submodules/TelegramUI/TelegramUI/ItemListMultilineTextItem.swift rename to submodules/ItemListUI/Sources/Items/ItemListMultilineTextItem.swift index 2b85440197..72f3e11cfb 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListMultilineTextItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListMultilineTextItem.swift @@ -4,23 +4,14 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import TextFormat +import AccountContext -enum TextLinkItemActionType { - case tap - case longTap -} - -enum TextLinkItem { - case url(String) - case mention(String) - case hashtag(String?, String) -} - -class ItemListMultilineTextItem: ListViewItem, ItemListItem { +public class ItemListMultilineTextItem: ListViewItem, ItemListItem { let theme: PresentationTheme let text: String let enabledEntityTypes: EnabledEntityTypes - let sectionId: ItemListSectionId + public let sectionId: ItemListSectionId let style: ItemListStyle let action: (() -> Void)? let longTapAction: (() -> Void)? @@ -28,9 +19,9 @@ class ItemListMultilineTextItem: ListViewItem, ItemListItem { let tag: Any? - let selectable: Bool + public let selectable: Bool - init(theme: PresentationTheme, text: String, enabledEntityTypes: EnabledEntityTypes, sectionId: ItemListSectionId, style: ItemListStyle, action: (() -> Void)? = nil, longTapAction: (() -> Void)? = nil, linkItemAction: ((TextLinkItemActionType, TextLinkItem) -> Void)? = nil, tag: Any? = nil) { + public init(theme: PresentationTheme, text: String, enabledEntityTypes: EnabledEntityTypes, sectionId: ItemListSectionId, style: ItemListStyle, action: (() -> Void)? = nil, longTapAction: (() -> Void)? = nil, linkItemAction: ((TextLinkItemActionType, TextLinkItem) -> Void)? = nil, tag: Any? = nil) { self.theme = theme self.text = text self.enabledEntityTypes = enabledEntityTypes @@ -44,7 +35,7 @@ class ItemListMultilineTextItem: ListViewItem, ItemListItem { self.selectable = action != nil } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListMultilineTextItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -60,7 +51,7 @@ class ItemListMultilineTextItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListMultilineTextItemNode { let makeLayout = nodeValue.asyncLayout() @@ -77,7 +68,7 @@ class ItemListMultilineTextItem: ListViewItem, ItemListItem { } } - func selected(listView: ListView){ + public func selected(listView: ListView){ listView.clearHighlightAnimated(true) self.action?() } @@ -89,7 +80,7 @@ private let titleItalicFont = Font.italic(17.0) private let titleBoldItalicFont = Font.semiboldItalic(17.0) private let titleFixedFont = Font.regular(17.0) -class ItemListMultilineTextItemNode: ListViewItemNode { +public class ItemListMultilineTextItemNode: ListViewItemNode { private let backgroundNode: ASDisplayNode private let topStripeNode: ASDisplayNode private let bottomStripeNode: ASDisplayNode @@ -102,15 +93,15 @@ class ItemListMultilineTextItemNode: ListViewItemNode { private var item: ItemListMultilineTextItem? - var tag: Any? { + public var tag: Any? { return self.item?.tag } - override var canBeLongTapped: Bool { + override public var canBeLongTapped: Bool { return true } - init() { + public init() { self.backgroundNode = ASDisplayNode() self.backgroundNode.isLayerBacked = true self.backgroundNode.backgroundColor = .white @@ -137,7 +128,7 @@ class ItemListMultilineTextItemNode: ListViewItemNode { self.addSubnode(self.activateArea) } - override func didLoad() { + override public func didLoad() { super.didLoad() let recognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapGesture(_:))) @@ -155,7 +146,7 @@ class ItemListMultilineTextItemNode: ListViewItemNode { self.view.addGestureRecognizer(recognizer) } - func asyncLayout() -> (_ item: ItemListMultilineTextItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { + public func asyncLayout() -> (_ item: ItemListMultilineTextItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { let makeTextLayout = TextNode.asyncLayout(self.textNode) let currentItem = self.item @@ -273,7 +264,7 @@ class ItemListMultilineTextItemNode: ListViewItemNode { } } - override func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { + override public func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { super.setHighlighted(highlighted, at: point, animated: animated) if highlighted && self.linkItemAtPoint(point) == nil { @@ -311,15 +302,15 @@ class ItemListMultilineTextItemNode: ListViewItemNode { } } - override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { + override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } - @objc func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { + @objc private func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { switch recognizer.state { case .ended: if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { @@ -340,11 +331,11 @@ class ItemListMultilineTextItemNode: ListViewItemNode { private func linkItemAtPoint(_ point: CGPoint) -> TextLinkItem? { let textNodeFrame = self.textNode.frame if let (_, attributes) = self.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { return .url(url) - } else if let peerName = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let peerName = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { return .mention(peerName) - } else if let hashtag = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { + } else if let hashtag = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { return .hashtag(hashtag.peerName, hashtag.hashtag) } else { return nil @@ -353,7 +344,7 @@ class ItemListMultilineTextItemNode: ListViewItemNode { return nil } - override func longTapped() { + override public func longTapped() { self.item?.longTapAction?() } @@ -371,7 +362,7 @@ class ItemListMultilineTextItemNode: ListViewItemNode { TelegramTextAttributes.Hashtag ] for name in possibleNames { - if let _ = attributes[NSAttributedStringKey(rawValue: name)] { + if let _ = attributes[NSAttributedString.Key(rawValue: name)] { rects = self.textNode.attributeRects(name: name, at: index) break } diff --git a/submodules/TelegramUI/TelegramUI/ItemListSwitchItem.swift b/submodules/ItemListUI/Sources/Items/ItemListSwitchItem.swift similarity index 90% rename from submodules/TelegramUI/TelegramUI/ItemListSwitchItem.swift rename to submodules/ItemListUI/Sources/Items/ItemListSwitchItem.swift index 2394aa2e57..a7113d6474 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListSwitchItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListSwitchItem.swift @@ -4,13 +4,14 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import SwitchNode -enum ItemListSwitchItemNodeType { +public enum ItemListSwitchItemNodeType { case regular case icon } -class ItemListSwitchItem: ListViewItem, ItemListItem { +public class ItemListSwitchItem: ListViewItem, ItemListItem { let theme: PresentationTheme let title: String let value: Bool @@ -18,12 +19,12 @@ class ItemListSwitchItem: ListViewItem, ItemListItem { let enableInteractiveChanges: Bool let enabled: Bool let maximumNumberOfLines: Int - let sectionId: ItemListSectionId + public let sectionId: ItemListSectionId let style: ItemListStyle let updated: (Bool) -> Void - let tag: ItemListItemTag? + public let tag: ItemListItemTag? - init(theme: PresentationTheme, title: String, value: Bool, type: ItemListSwitchItemNodeType = .regular, enableInteractiveChanges: Bool = true, enabled: Bool = true, maximumNumberOfLines: Int = 1, sectionId: ItemListSectionId, style: ItemListStyle, updated: @escaping (Bool) -> Void, tag: ItemListItemTag? = nil) { + public init(theme: PresentationTheme, title: String, value: Bool, type: ItemListSwitchItemNodeType = .regular, enableInteractiveChanges: Bool = true, enabled: Bool = true, maximumNumberOfLines: Int = 1, sectionId: ItemListSectionId, style: ItemListStyle, updated: @escaping (Bool) -> Void, tag: ItemListItemTag? = nil) { self.theme = theme self.title = title self.value = value @@ -37,7 +38,7 @@ class ItemListSwitchItem: ListViewItem, ItemListItem { self.tag = tag } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListSwitchItemNode(type: self.type) let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -53,7 +54,7 @@ class ItemListSwitchItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListSwitchItemNode { let makeLayout = nodeValue.asyncLayout() @@ -108,7 +109,7 @@ extension SwitchNode: ItemListSwitchNodeImpl { extension IconSwitchNode: ItemListSwitchNodeImpl { } -class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode { +public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode { private let backgroundNode: ASDisplayNode private let topStripeNode: ASDisplayNode private let bottomStripeNode: ASDisplayNode @@ -123,7 +124,7 @@ class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode { private var item: ItemListSwitchItem? - var tag: ItemListItemTag? { + public var tag: ItemListItemTag? { return self.item?.tag } @@ -174,7 +175,7 @@ class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode { } } - override func didLoad() { + override public func didLoad() { super.didLoad() (self.switchNode.view as? UISwitch)?.addTarget(self, action: #selector(self.switchValueChanged(_:)), for: .valueChanged) @@ -241,7 +242,7 @@ class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode { var accessibilityTraits = UIAccessibilityTraits() if item.enabled { } else { - accessibilityTraits |= UIAccessibilityTraitNotEnabled + accessibilityTraits.insert(.notEnabled) } strongSelf.activateArea.accessibilityTraits = accessibilityTraits @@ -351,7 +352,7 @@ class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode { } } - override func accessibilityActivate() -> Bool { + override public func accessibilityActivate() -> Bool { guard let item = self.item else { return false } @@ -368,7 +369,7 @@ class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode { return true } - override func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { + override public func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { super.setHighlighted(highlighted, at: point, animated: animated) if highlighted { @@ -406,22 +407,22 @@ class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode { } } - override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { + override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } - @objc func switchValueChanged(_ switchView: UISwitch) { + @objc private func switchValueChanged(_ switchView: UISwitch) { if let item = self.item { let value = switchView.isOn item.updated(value) } } - @objc func tapGesture(_ recognizer: UITapGestureRecognizer) { + @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) { if let item = self.item, let switchView = self.switchNode.view as? UISwitch, case .ended = recognizer.state { let value = switchView.isOn item.updated(!value) diff --git a/submodules/TelegramUI/TelegramUI/ItemListTextItem.swift b/submodules/ItemListUI/Sources/Items/ItemListTextItem.swift similarity index 77% rename from submodules/TelegramUI/TelegramUI/ItemListTextItem.swift rename to submodules/ItemListUI/Sources/Items/ItemListTextItem.swift index 50a7802d77..5840ca926c 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListTextItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListTextItem.swift @@ -4,25 +4,26 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import TextFormat -enum ItemListTextItemText { +public enum ItemListTextItemText { case plain(String) case markdown(String) } -enum ItemListTextItemLinkAction { +public enum ItemListTextItemLinkAction { case tap(String) } -class ItemListTextItem: ListViewItem, ItemListItem { +public class ItemListTextItem: ListViewItem, ItemListItem { let theme: PresentationTheme let text: ItemListTextItemText - let sectionId: ItemListSectionId + public let sectionId: ItemListSectionId let linkAction: ((ItemListTextItemLinkAction) -> Void)? let style: ItemListStyle - let isAlwaysPlain: Bool = true + public let isAlwaysPlain: Bool = true - init(theme: PresentationTheme, text: ItemListTextItemText, sectionId: ItemListSectionId, linkAction: ((ItemListTextItemLinkAction) -> Void)? = nil, style: ItemListStyle = .blocks) { + public init(theme: PresentationTheme, text: ItemListTextItemText, sectionId: ItemListSectionId, linkAction: ((ItemListTextItemLinkAction) -> Void)? = nil, style: ItemListStyle = .blocks) { self.theme = theme self.text = text self.sectionId = sectionId @@ -30,7 +31,7 @@ class ItemListTextItem: ListViewItem, ItemListItem { self.style = style } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListTextItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -46,7 +47,7 @@ class ItemListTextItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { guard let nodeValue = node() as? ItemListTextItemNode else { assertionFailure() @@ -70,20 +71,20 @@ class ItemListTextItem: ListViewItem, ItemListItem { private let titleFont = Font.regular(14.0) private let titleBoldFont = Font.semibold(14.0) -class ItemListTextItemNode: ListViewItemNode { +public class ItemListTextItemNode: ListViewItemNode { private let titleNode: TextNode private let activateArea: AccessibilityAreaNode private var item: ItemListTextItem? - init() { + public init() { self.titleNode = TextNode() self.titleNode.isUserInteractionEnabled = false self.titleNode.contentMode = .left self.titleNode.contentsScale = UIScreen.main.scale self.activateArea = AccessibilityAreaNode() - self.activateArea.accessibilityTraits = UIAccessibilityTraitStaticText + self.activateArea.accessibilityTraits = .staticText super.init(layerBacked: false, dynamicBounce: false) @@ -91,7 +92,7 @@ class ItemListTextItemNode: ListViewItemNode { self.addSubnode(self.activateArea) } - override func didLoad() { + override public func didLoad() { super.didLoad() let recognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapGesture(_:))) @@ -101,7 +102,7 @@ class ItemListTextItemNode: ListViewItemNode { self.view.addGestureRecognizer(recognizer) } - func asyncLayout() -> (_ item: ItemListTextItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { + public func asyncLayout() -> (_ item: ItemListTextItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { let makeTitleLayout = TextNode.asyncLayout(self.titleNode) return { item, params, neighbors in @@ -143,15 +144,15 @@ class ItemListTextItemNode: ListViewItemNode { } } - override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { + override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } - @objc func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { + @objc private func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { switch recognizer.state { case .ended: if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { @@ -160,7 +161,7 @@ class ItemListTextItemNode: ListViewItemNode { let titleFrame = self.titleNode.frame if let item = self.item, titleFrame.contains(location) { if let (_, attributes) = self.titleNode.attributesAtPoint(CGPoint(x: location.x - titleFrame.minX, y: location.y - titleFrame.minY)) { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { item.linkAction?(.tap(url)) } } diff --git a/submodules/TelegramUI/TelegramUI/ItemListTextWithLabelItem.swift b/submodules/ItemListUI/Sources/Items/ItemListTextWithLabelItem.swift similarity index 88% rename from submodules/TelegramUI/TelegramUI/ItemListTextWithLabelItem.swift rename to submodules/ItemListUI/Sources/Items/ItemListTextWithLabelItem.swift index c21de0574d..3d12ca8e31 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListTextWithLabelItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListTextWithLabelItem.swift @@ -4,31 +4,33 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import TextFormat +import AccountContext -enum ItemListTextWithLabelItemTextColor { +public enum ItemListTextWithLabelItemTextColor { case primary case accent case highlighted } -final class ItemListTextWithLabelItem: ListViewItem, ItemListItem { +public final class ItemListTextWithLabelItem: ListViewItem, ItemListItem { let theme: PresentationTheme - let label: String - let text: String + public let label: String + public let text: String let style: ItemListStyle let labelColor: ItemListTextWithLabelItemTextColor let textColor: ItemListTextWithLabelItemTextColor let enabledEntityTypes: EnabledEntityTypes let multiline: Bool let selected: Bool? - let sectionId: ItemListSectionId + public let sectionId: ItemListSectionId let action: (() -> Void)? let longTapAction: (() -> Void)? let linkItemAction: ((TextLinkItemActionType, TextLinkItem) -> Void)? - let tag: Any? + public let tag: Any? - init(theme: PresentationTheme, label: String, text: String, style: ItemListStyle = .plain, labelColor: ItemListTextWithLabelItemTextColor = .primary, textColor: ItemListTextWithLabelItemTextColor = .primary, enabledEntityTypes: EnabledEntityTypes, multiline: Bool, selected: Bool? = nil, sectionId: ItemListSectionId, action: (() -> Void)?, longTapAction: (() -> Void)? = nil, linkItemAction: ((TextLinkItemActionType, TextLinkItem) -> Void)? = nil, tag: Any? = nil) { + public init(theme: PresentationTheme, label: String, text: String, style: ItemListStyle = .plain, labelColor: ItemListTextWithLabelItemTextColor = .primary, textColor: ItemListTextWithLabelItemTextColor = .primary, enabledEntityTypes: EnabledEntityTypes, multiline: Bool, selected: Bool? = nil, sectionId: ItemListSectionId, action: (() -> Void)?, longTapAction: (() -> Void)? = nil, linkItemAction: ((TextLinkItemActionType, TextLinkItem) -> Void)? = nil, tag: Any? = nil) { self.theme = theme self.label = label self.text = text @@ -45,7 +47,7 @@ final class ItemListTextWithLabelItem: ListViewItem, ItemListItem { self.tag = tag } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ItemListTextWithLabelItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -61,7 +63,7 @@ final class ItemListTextWithLabelItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { if let nodeValue = node() as? ItemListTextWithLabelItemNode { let makeLayout = nodeValue.asyncLayout() @@ -78,11 +80,11 @@ final class ItemListTextWithLabelItem: ListViewItem, ItemListItem { } } - var selectable: Bool { + public var selectable: Bool { return self.action != nil } - func selected(listView: ListView) { + public func selected(listView: ListView) { listView.clearHighlightAnimated(true) self.action?() } @@ -95,7 +97,7 @@ private let textItalicFont = Font.italic(17.0) private let textBoldItalicFont = Font.semiboldItalic(17.0) private let textFixedFont = Font.regular(17.0) -class ItemListTextWithLabelItemNode: ListViewItemNode { +public class ItemListTextWithLabelItemNode: ListViewItemNode { let labelNode: TextNode let textNode: TextNode @@ -106,13 +108,13 @@ class ItemListTextWithLabelItemNode: ListViewItemNode { private var linkHighlightingNode: LinkHighlightingNode? private var selectionNode: ItemListSelectableControlNode? - var item: ItemListTextWithLabelItem? + public var item: ItemListTextWithLabelItem? - override var canBeLongTapped: Bool { + override public var canBeLongTapped: Bool { return true } - init() { + public init() { self.backgroundNode = ASDisplayNode() self.backgroundNode.isLayerBacked = true @@ -143,7 +145,7 @@ class ItemListTextWithLabelItemNode: ListViewItemNode { self.addSubnode(self.textNode) } - override func didLoad() { + override public func didLoad() { super.didLoad() let recognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapGesture(_:))) @@ -161,7 +163,7 @@ class ItemListTextWithLabelItemNode: ListViewItemNode { self.view.addGestureRecognizer(recognizer) } - func asyncLayout() -> (_ item: ItemListTextWithLabelItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation) -> Void) { + public func asyncLayout() -> (_ item: ItemListTextWithLabelItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation) -> Void) { let makeLabelLayout = TextNode.asyncLayout(self.labelNode) let makeTextLayout = TextNode.asyncLayout(self.textNode) @@ -323,7 +325,7 @@ class ItemListTextWithLabelItemNode: ListViewItemNode { } } - override func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { + override public func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { super.setHighlighted(highlighted, at: point, animated: animated) if highlighted && self.linkItemAtPoint(point) == nil && self.selectionNode == nil { @@ -361,7 +363,7 @@ class ItemListTextWithLabelItemNode: ListViewItemNode { } } - @objc func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { + @objc private func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { switch recognizer.state { case .ended: if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { @@ -382,11 +384,11 @@ class ItemListTextWithLabelItemNode: ListViewItemNode { private func linkItemAtPoint(_ point: CGPoint) -> TextLinkItem? { let textNodeFrame = self.textNode.frame if let (_, attributes) = self.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { return .url(url) - } else if let peerName = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let peerName = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { return .mention(peerName) - } else if let hashtag = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { + } else if let hashtag = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { return .hashtag(hashtag.peerName, hashtag.hashtag) } else { return nil @@ -395,15 +397,15 @@ class ItemListTextWithLabelItemNode: ListViewItemNode { return nil } - override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { + override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } - override func longTapped() { + override public func longTapped() { self.item?.longTapAction?() } @@ -421,7 +423,7 @@ class ItemListTextWithLabelItemNode: ListViewItemNode { TelegramTextAttributes.Hashtag ] for name in possibleNames { - if let _ = attributes[NSAttributedStringKey(rawValue: name)] { + if let _ = attributes[NSAttributedString.Key(rawValue: name)] { rects = self.textNode.attributeRects(name: name, at: index) break } @@ -449,7 +451,7 @@ class ItemListTextWithLabelItemNode: ListViewItemNode { } } - var tag: Any? { + public var tag: Any? { return self.item?.tag } } diff --git a/submodules/TelegramUI/TelegramUI/ItemListControllerEmptyStateItem.swift b/submodules/TelegramUI/TelegramUI/ItemListControllerEmptyStateItem.swift deleted file mode 100644 index de6314230a..0000000000 --- a/submodules/TelegramUI/TelegramUI/ItemListControllerEmptyStateItem.swift +++ /dev/null @@ -1,15 +0,0 @@ -import Foundation -import UIKit -import AsyncDisplayKit -import Display - -protocol ItemListControllerEmptyStateItem { - func isEqual(to: ItemListControllerEmptyStateItem) -> Bool - func node(current: ItemListControllerEmptyStateItemNode?) -> ItemListControllerEmptyStateItemNode -} - -class ItemListControllerEmptyStateItemNode: ASDisplayNode { - func updateLayout(layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { - - } -} From c3c7a4c3688a5e4fe6919d9b516a79abe5e4ccfd Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:19:00 +0300 Subject: [PATCH 30/41] Refactor MergeLists --- submodules/MergeLists/Info.plist | 22 + .../project.pbxproj | 547 ++++++++++++++++++ .../MergeLists/Sources/Identifiable.swift | 6 + submodules/MergeLists/Sources/MergeLists.h | 19 + .../Sources}/MergeLists.swift | 49 +- 5 files changed, 616 insertions(+), 27 deletions(-) create mode 100644 submodules/MergeLists/Info.plist create mode 100644 submodules/MergeLists/MergeLists_Xcode.xcodeproj/project.pbxproj create mode 100644 submodules/MergeLists/Sources/Identifiable.swift create mode 100644 submodules/MergeLists/Sources/MergeLists.h rename submodules/{TelegramUI/TelegramUI => MergeLists/Sources}/MergeLists.swift (91%) diff --git a/submodules/MergeLists/Info.plist b/submodules/MergeLists/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/MergeLists/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/MergeLists/MergeLists_Xcode.xcodeproj/project.pbxproj b/submodules/MergeLists/MergeLists_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..eb6fd67b28 --- /dev/null +++ b/submodules/MergeLists/MergeLists_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,547 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D0D3288622F338CB00D07EE2 /* MergeLists.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D3288422F338CB00D07EE2 /* MergeLists.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0D3289122F3443C00D07EE2 /* MergeLists.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3289022F3443C00D07EE2 /* MergeLists.swift */; }; + D0D3289322F3444800D07EE2 /* Identifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3289222F3444800D07EE2 /* Identifiable.swift */; }; + D0D3289622F3445700D07EE2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3289522F3445700D07EE2 /* Foundation.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D0D3288122F338CB00D07EE2 /* MergeLists.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MergeLists.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3288422F338CB00D07EE2 /* MergeLists.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MergeLists.h; sourceTree = ""; }; + D0D3288522F338CB00D07EE2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D0D3289022F3443C00D07EE2 /* MergeLists.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MergeLists.swift; sourceTree = ""; }; + D0D3289222F3444800D07EE2 /* Identifiable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Identifiable.swift; sourceTree = ""; }; + D0D3289522F3445700D07EE2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D0D3287E22F338CB00D07EE2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D0D3289622F3445700D07EE2 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D0D3287722F338CB00D07EE2 = { + isa = PBXGroup; + children = ( + D0D3288522F338CB00D07EE2 /* Info.plist */, + D0D3288322F338CB00D07EE2 /* Sources */, + D0D3288222F338CB00D07EE2 /* Products */, + D0D3289422F3445700D07EE2 /* Frameworks */, + ); + sourceTree = ""; + }; + D0D3288222F338CB00D07EE2 /* Products */ = { + isa = PBXGroup; + children = ( + D0D3288122F338CB00D07EE2 /* MergeLists.framework */, + ); + name = Products; + sourceTree = ""; + }; + D0D3288322F338CB00D07EE2 /* Sources */ = { + isa = PBXGroup; + children = ( + D0D3289022F3443C00D07EE2 /* MergeLists.swift */, + D0D3289222F3444800D07EE2 /* Identifiable.swift */, + D0D3288422F338CB00D07EE2 /* MergeLists.h */, + ); + path = Sources; + sourceTree = ""; + }; + D0D3289422F3445700D07EE2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D0D3289522F3445700D07EE2 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D0D3287C22F338CB00D07EE2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D0D3288622F338CB00D07EE2 /* MergeLists.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D0D3288022F338CB00D07EE2 /* MergeLists */ = { + isa = PBXNativeTarget; + buildConfigurationList = D0D3288922F338CB00D07EE2 /* Build configuration list for PBXNativeTarget "MergeLists" */; + buildPhases = ( + D0D3287C22F338CB00D07EE2 /* Headers */, + D0D3287D22F338CB00D07EE2 /* Sources */, + D0D3287E22F338CB00D07EE2 /* Frameworks */, + D0D3287F22F338CB00D07EE2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MergeLists; + productName = MergeLists; + productReference = D0D3288122F338CB00D07EE2 /* MergeLists.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D0D3287822F338CB00D07EE2 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D0D3288022F338CB00D07EE2 = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1010; + }; + }; + }; + buildConfigurationList = D0D3287B22F338CB00D07EE2 /* Build configuration list for PBXProject "MergeLists_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D0D3287722F338CB00D07EE2; + productRefGroup = D0D3288222F338CB00D07EE2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D0D3288022F338CB00D07EE2 /* MergeLists */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D0D3287F22F338CB00D07EE2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D0D3287D22F338CB00D07EE2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D0D3289122F3443C00D07EE2 /* MergeLists.swift in Sources */, + D0D3289322F3444800D07EE2 /* Identifiable.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D0D3288722F338CB00D07EE2 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D0D3288822F338CB00D07EE2 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D0D3288A22F338CB00D07EE2 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.MergeLists; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D0D3288B22F338CB00D07EE2 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.MergeLists; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D0D3288C22F338F300D07EE2 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D0D3288D22F338F300D07EE2 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.MergeLists; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D0D3288E22F3390000D07EE2 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D0D3288F22F3390000D07EE2 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.MergeLists; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D0D3287B22F338CB00D07EE2 /* Build configuration list for PBXProject "MergeLists_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0D3288722F338CB00D07EE2 /* DebugAppStoreLLC */, + D0D3288C22F338F300D07EE2 /* DebugHockeyapp */, + D0D3288822F338CB00D07EE2 /* ReleaseAppStoreLLC */, + D0D3288E22F3390000D07EE2 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D0D3288922F338CB00D07EE2 /* Build configuration list for PBXNativeTarget "MergeLists" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0D3288A22F338CB00D07EE2 /* DebugAppStoreLLC */, + D0D3288D22F338F300D07EE2 /* DebugHockeyapp */, + D0D3288B22F338CB00D07EE2 /* ReleaseAppStoreLLC */, + D0D3288F22F3390000D07EE2 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D0D3287822F338CB00D07EE2 /* Project object */; +} diff --git a/submodules/MergeLists/Sources/Identifiable.swift b/submodules/MergeLists/Sources/Identifiable.swift new file mode 100644 index 0000000000..0ada7637ed --- /dev/null +++ b/submodules/MergeLists/Sources/Identifiable.swift @@ -0,0 +1,6 @@ +import Foundation + +public protocol Identifiable { + associatedtype T: Hashable + var stableId: T { get } +} diff --git a/submodules/MergeLists/Sources/MergeLists.h b/submodules/MergeLists/Sources/MergeLists.h new file mode 100644 index 0000000000..ab329490db --- /dev/null +++ b/submodules/MergeLists/Sources/MergeLists.h @@ -0,0 +1,19 @@ +// +// MergeLists.h +// MergeLists +// +// Created by Peter on 8/1/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for MergeLists. +FOUNDATION_EXPORT double MergeListsVersionNumber; + +//! Project version string for MergeLists. +FOUNDATION_EXPORT const unsigned char MergeListsVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/TelegramUI/TelegramUI/MergeLists.swift b/submodules/MergeLists/Sources/MergeLists.swift similarity index 91% rename from submodules/TelegramUI/TelegramUI/MergeLists.swift rename to submodules/MergeLists/Sources/MergeLists.swift index c87197ea60..04c60ddd0a 100644 --- a/submodules/TelegramUI/TelegramUI/MergeLists.swift +++ b/submodules/MergeLists/Sources/MergeLists.swift @@ -1,34 +1,29 @@ import Foundation -public protocol Identifiable { - associatedtype T: Hashable - var stableId: T { get } -} - public func mergeListsStableWithUpdates(leftList: [T], rightList: [T], allUpdated: Bool = false) -> ([Int], [(Int, T, Int?)], [(Int, T, Int)]) where T: Comparable, T: Identifiable { var removeIndices: [Int] = [] var insertItems: [(Int, T, Int?)] = [] var updatedIndices: [(Int, T, Int)] = [] - if !GlobalExperimentalSettings.isAppStoreBuild { - var existingStableIds: [T.T: T] = [:] - for item in leftList { - if let _ = existingStableIds[item.stableId] { - assertionFailure() - } else { - existingStableIds[item.stableId] = item - } - } - existingStableIds.removeAll() - for item in rightList { - if let other = existingStableIds[item.stableId] { - print("\(other) has the same stableId as \(item): \(item.stableId)") - assertionFailure() - } else { - existingStableIds[item.stableId] = item - } + #if DEBUG + var existingStableIds: [T.T: T] = [:] + for item in leftList { + if let _ = existingStableIds[item.stableId] { + assertionFailure() + } else { + existingStableIds[item.stableId] = item } } + existingStableIds.removeAll() + for item in rightList { + if let other = existingStableIds[item.stableId] { + print("\(other) has the same stableId as \(item): \(item.stableId)") + assertionFailure() + } else { + existingStableIds[item.stableId] = item + } + } + #endif var currentList = leftList @@ -176,11 +171,11 @@ public func mergeListsStableWithUpdates(leftList: [T], rightList: [T], allUpd currentList[index] = item } - if GlobalExperimentalSettings.isAppStoreBuild { - assert(currentList == rightList, "currentList == rightList") - } else { - precondition(currentList == rightList, "currentList == rightList") - } + #if DEBUG + precondition(currentList == rightList, "currentList == rightList") + #else + assert(currentList == rightList, "currentList == rightList") + #endif return (removeIndices, insertItems, updatedIndices) } From bff422ea608cd80a7e984e934d54a863e74e5600 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:19:31 +0300 Subject: [PATCH 31/41] Temporarily turn off Treat warnings as errors --- .../project.pbxproj | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/submodules/MtProtoKit/MtProtoKit_Xcode.xcodeproj/project.pbxproj b/submodules/MtProtoKit/MtProtoKit_Xcode.xcodeproj/project.pbxproj index b321ed0361..60b6cfeae6 100644 --- a/submodules/MtProtoKit/MtProtoKit_Xcode.xcodeproj/project.pbxproj +++ b/submodules/MtProtoKit/MtProtoKit_Xcode.xcodeproj/project.pbxproj @@ -1929,6 +1929,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = D05A830918AFB3F9007F1076; @@ -2492,7 +2493,7 @@ ); GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -2770,7 +2771,7 @@ "DEBUG=1", "$(inherited)", ); - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -3018,7 +3019,7 @@ "DEBUG=1", "$(inherited)", ); - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -3266,7 +3267,7 @@ "DEBUG=1", "$(inherited)", ); - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -3675,7 +3676,7 @@ "DEBUG=1", "$(inherited)", ); - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -3902,7 +3903,7 @@ "$(PROJECT_DIR)/thirdparty", ); GCC_NO_COMMON_BLOCKS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -4122,7 +4123,7 @@ "$(PROJECT_DIR)/thirdparty", ); GCC_NO_COMMON_BLOCKS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -4341,7 +4342,7 @@ "$(PROJECT_DIR)/thirdparty", ); GCC_NO_COMMON_BLOCKS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -4560,7 +4561,7 @@ "$(PROJECT_DIR)/thirdparty", ); GCC_NO_COMMON_BLOCKS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -4801,7 +4802,7 @@ "DEBUG=1", "$(inherited)", ); - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5139,7 +5140,7 @@ "$(PROJECT_DIR)/thirdparty", ); GCC_NO_COMMON_BLOCKS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5233,7 +5234,7 @@ "DEBUG=1", "$(inherited)", ); - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5285,7 +5286,7 @@ "$(PROJECT_DIR)/thirdparty", ); GCC_NO_COMMON_BLOCKS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5534,7 +5535,7 @@ "DEBUG=1", "$(inherited)", ); - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl"; INFOPLIST_FILE = MtProtoKitDynamic/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; From 5b13a8ae3d72c66737abe29bab9c0d49e610e267 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:20:06 +0300 Subject: [PATCH 32/41] Refactor ProgressNavigationButtonNode --- .../ProgressNavigationButtonNode/Info.plist | 22 + .../project.pbxproj | 563 ++++++++++++++++++ .../Sources/ProgressNavigationButtonNode.h | 19 + .../ProgressNavigationButtonNode.swift | 11 +- 4 files changed, 610 insertions(+), 5 deletions(-) create mode 100644 submodules/ProgressNavigationButtonNode/Info.plist create mode 100644 submodules/ProgressNavigationButtonNode/ProgressNavigationButtonNode_Xcode.xcodeproj/project.pbxproj create mode 100644 submodules/ProgressNavigationButtonNode/Sources/ProgressNavigationButtonNode.h rename submodules/{TelegramUI/TelegramUI => ProgressNavigationButtonNode/Sources}/ProgressNavigationButtonNode.swift (73%) diff --git a/submodules/ProgressNavigationButtonNode/Info.plist b/submodules/ProgressNavigationButtonNode/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/ProgressNavigationButtonNode/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/ProgressNavigationButtonNode/ProgressNavigationButtonNode_Xcode.xcodeproj/project.pbxproj b/submodules/ProgressNavigationButtonNode/ProgressNavigationButtonNode_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..7dbf6dbda2 --- /dev/null +++ b/submodules/ProgressNavigationButtonNode/ProgressNavigationButtonNode_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,563 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D060180922F35B1200796784 /* ProgressNavigationButtonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = D060180722F35B1200796784 /* ProgressNavigationButtonNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D060181422F35BC500796784 /* ProgressNavigationButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060181322F35BC500796784 /* ProgressNavigationButtonNode.swift */; }; + D060181722F35C0200796784 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060181622F35C0200796784 /* Foundation.framework */; }; + D060181922F35C0500796784 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060181822F35C0500796784 /* UIKit.framework */; }; + D060181B22F35C0800796784 /* Display.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060181A22F35C0800796784 /* Display.framework */; }; + D060181D22F35C1400796784 /* AsyncDisplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060181C22F35C1400796784 /* AsyncDisplayKit.framework */; }; + D060181F22F35C1700796784 /* TelegramPresentationData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060181E22F35C1700796784 /* TelegramPresentationData.framework */; }; + D060183E22F35CB300796784 /* ActivityIndicator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060183D22F35CB300796784 /* ActivityIndicator.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D060180422F35B1200796784 /* ProgressNavigationButtonNode.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ProgressNavigationButtonNode.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060180722F35B1200796784 /* ProgressNavigationButtonNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProgressNavigationButtonNode.h; sourceTree = ""; }; + D060180822F35B1200796784 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D060181322F35BC500796784 /* ProgressNavigationButtonNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressNavigationButtonNode.swift; sourceTree = ""; }; + D060181622F35C0200796784 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D060181822F35C0500796784 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D060181A22F35C0800796784 /* Display.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Display.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060181C22F35C1400796784 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060181E22F35C1700796784 /* TelegramPresentationData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TelegramPresentationData.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060183D22F35CB300796784 /* ActivityIndicator.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = ActivityIndicator.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D060180122F35B1200796784 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D060183E22F35CB300796784 /* ActivityIndicator.framework in Frameworks */, + D060181F22F35C1700796784 /* TelegramPresentationData.framework in Frameworks */, + D060181D22F35C1400796784 /* AsyncDisplayKit.framework in Frameworks */, + D060181B22F35C0800796784 /* Display.framework in Frameworks */, + D060181922F35C0500796784 /* UIKit.framework in Frameworks */, + D060181722F35C0200796784 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D06017FA22F35B1200796784 = { + isa = PBXGroup; + children = ( + D060180822F35B1200796784 /* Info.plist */, + D060180622F35B1200796784 /* Sources */, + D060180522F35B1200796784 /* Products */, + D060181522F35C0100796784 /* Frameworks */, + ); + sourceTree = ""; + }; + D060180522F35B1200796784 /* Products */ = { + isa = PBXGroup; + children = ( + D060180422F35B1200796784 /* ProgressNavigationButtonNode.framework */, + ); + name = Products; + sourceTree = ""; + }; + D060180622F35B1200796784 /* Sources */ = { + isa = PBXGroup; + children = ( + D060181322F35BC500796784 /* ProgressNavigationButtonNode.swift */, + D060180722F35B1200796784 /* ProgressNavigationButtonNode.h */, + ); + path = Sources; + sourceTree = ""; + }; + D060181522F35C0100796784 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D060183D22F35CB300796784 /* ActivityIndicator.framework */, + D060181E22F35C1700796784 /* TelegramPresentationData.framework */, + D060181C22F35C1400796784 /* AsyncDisplayKit.framework */, + D060181A22F35C0800796784 /* Display.framework */, + D060181822F35C0500796784 /* UIKit.framework */, + D060181622F35C0200796784 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D06017FF22F35B1200796784 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D060180922F35B1200796784 /* ProgressNavigationButtonNode.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D060180322F35B1200796784 /* ProgressNavigationButtonNode */ = { + isa = PBXNativeTarget; + buildConfigurationList = D060180C22F35B1200796784 /* Build configuration list for PBXNativeTarget "ProgressNavigationButtonNode" */; + buildPhases = ( + D06017FF22F35B1200796784 /* Headers */, + D060180022F35B1200796784 /* Sources */, + D060180122F35B1200796784 /* Frameworks */, + D060180222F35B1200796784 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ProgressNavigationButtonNode; + productName = ProgressNavigationButtonNode; + productReference = D060180422F35B1200796784 /* ProgressNavigationButtonNode.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D06017FB22F35B1200796784 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D060180322F35B1200796784 = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1010; + }; + }; + }; + buildConfigurationList = D06017FE22F35B1200796784 /* Build configuration list for PBXProject "ProgressNavigationButtonNode_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D06017FA22F35B1200796784; + productRefGroup = D060180522F35B1200796784 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D060180322F35B1200796784 /* ProgressNavigationButtonNode */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D060180222F35B1200796784 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D060180022F35B1200796784 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D060181422F35BC500796784 /* ProgressNavigationButtonNode.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D060180A22F35B1200796784 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D060180B22F35B1200796784 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D060180D22F35B1200796784 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ProgressNavigationButtonNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D060180E22F35B1200796784 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ProgressNavigationButtonNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D060180F22F35B3300796784 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D060181022F35B3300796784 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ProgressNavigationButtonNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D060181122F35B4100796784 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D060181222F35B4100796784 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.ProgressNavigationButtonNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D06017FE22F35B1200796784 /* Build configuration list for PBXProject "ProgressNavigationButtonNode_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D060180A22F35B1200796784 /* DebugAppStoreLLC */, + D060180F22F35B3300796784 /* DebugHockeyapp */, + D060180B22F35B1200796784 /* ReleaseAppStoreLLC */, + D060181122F35B4100796784 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D060180C22F35B1200796784 /* Build configuration list for PBXNativeTarget "ProgressNavigationButtonNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D060180D22F35B1200796784 /* DebugAppStoreLLC */, + D060181022F35B3300796784 /* DebugHockeyapp */, + D060180E22F35B1200796784 /* ReleaseAppStoreLLC */, + D060181222F35B4100796784 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D06017FB22F35B1200796784 /* Project object */; +} diff --git a/submodules/ProgressNavigationButtonNode/Sources/ProgressNavigationButtonNode.h b/submodules/ProgressNavigationButtonNode/Sources/ProgressNavigationButtonNode.h new file mode 100644 index 0000000000..ef474b0065 --- /dev/null +++ b/submodules/ProgressNavigationButtonNode/Sources/ProgressNavigationButtonNode.h @@ -0,0 +1,19 @@ +// +// ProgressNavigationButtonNode.h +// ProgressNavigationButtonNode +// +// Created by Peter on 8/1/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for ProgressNavigationButtonNode. +FOUNDATION_EXPORT double ProgressNavigationButtonNodeVersionNumber; + +//! Project version string for ProgressNavigationButtonNode. +FOUNDATION_EXPORT const unsigned char ProgressNavigationButtonNodeVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/TelegramUI/TelegramUI/ProgressNavigationButtonNode.swift b/submodules/ProgressNavigationButtonNode/Sources/ProgressNavigationButtonNode.swift similarity index 73% rename from submodules/TelegramUI/TelegramUI/ProgressNavigationButtonNode.swift rename to submodules/ProgressNavigationButtonNode/Sources/ProgressNavigationButtonNode.swift index 2d2e07a94e..241e63d19d 100644 --- a/submodules/TelegramUI/TelegramUI/ProgressNavigationButtonNode.swift +++ b/submodules/ProgressNavigationButtonNode/Sources/ProgressNavigationButtonNode.swift @@ -3,15 +3,16 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import ActivityIndicator -final class ProgressNavigationButtonNode: ASDisplayNode { +public final class ProgressNavigationButtonNode: ASDisplayNode { private var indicatorNode: ActivityIndicator - convenience init(theme: PresentationTheme) { + convenience public init(theme: PresentationTheme) { self.init(color: theme.rootController.navigationBar.accentTextColor) } - init(color: UIColor) { + public init(color: UIColor) { self.indicatorNode = ActivityIndicator(type: .custom(color, 22.0, 1.0, false)) super.init() @@ -19,11 +20,11 @@ final class ProgressNavigationButtonNode: ASDisplayNode { self.addSubnode(self.indicatorNode) } - override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { + override public func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { return CGSize(width: 26.0, height: 22.0) } - override func layout() { + override public func layout() { super.layout() let size = self.bounds.size From 1d35197f20311908897fa57fff41c2eb0096e5c4 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:20:27 +0300 Subject: [PATCH 33/41] Update SwiftSignalKit to Swift 4.2 --- .../SSignalKit_Xcode.xcodeproj/project.pbxproj | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/submodules/SSignalKit/SSignalKit_Xcode.xcodeproj/project.pbxproj b/submodules/SSignalKit/SSignalKit_Xcode.xcodeproj/project.pbxproj index f0350878f7..d93a0865e5 100644 --- a/submodules/SSignalKit/SSignalKit_Xcode.xcodeproj/project.pbxproj +++ b/submodules/SSignalKit/SSignalKit_Xcode.xcodeproj/project.pbxproj @@ -883,7 +883,7 @@ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = DebugHockeyapp; }; @@ -914,7 +914,7 @@ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = ReleaseHockeyapp; }; @@ -1086,7 +1086,7 @@ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = DebugFork; }; @@ -1269,7 +1269,7 @@ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = HockeyappMacAlpha; }; @@ -1617,7 +1617,7 @@ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = ReleaseAppStore; }; @@ -1751,7 +1751,7 @@ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = ReleaseHockeyappInternal; }; @@ -1932,7 +1932,7 @@ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = DebugAppStoreLLC; }; @@ -2193,7 +2193,7 @@ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = ReleaseAppStoreLLC; }; @@ -2373,7 +2373,7 @@ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = none; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = DebugAppStore; }; From 81701d99693a2777dcbc553869979933d4a7c89e Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:21:15 +0300 Subject: [PATCH 34/41] Refactor SwitchNode --- submodules/SwitchNode/Info.plist | 22 + .../Sources}/IconSwitchNode.swift | 3 +- submodules/SwitchNode/Sources/SwitchNode.h | 19 + .../project.pbxproj | 559 ++++++++++++++++++ 4 files changed, 602 insertions(+), 1 deletion(-) create mode 100644 submodules/SwitchNode/Info.plist rename submodules/{TelegramUI/TelegramUI => SwitchNode/Sources}/IconSwitchNode.swift (98%) create mode 100644 submodules/SwitchNode/Sources/SwitchNode.h create mode 100644 submodules/SwitchNode/SwitchNode_Xcode.xcodeproj/project.pbxproj diff --git a/submodules/SwitchNode/Info.plist b/submodules/SwitchNode/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/SwitchNode/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/TelegramUI/TelegramUI/IconSwitchNode.swift b/submodules/SwitchNode/Sources/IconSwitchNode.swift similarity index 98% rename from submodules/TelegramUI/TelegramUI/IconSwitchNode.swift rename to submodules/SwitchNode/Sources/IconSwitchNode.swift index 41d0d17ba8..bdf0fe9db9 100644 --- a/submodules/TelegramUI/TelegramUI/IconSwitchNode.swift +++ b/submodules/SwitchNode/Sources/IconSwitchNode.swift @@ -1,4 +1,5 @@ import Foundation +import Display import UIKit import AsyncDisplayKit @@ -15,7 +16,7 @@ private final class IconSwitchNodeView: TGIconSwitchView { } } -class IconSwitchNode: ASDisplayNode { +open class IconSwitchNode: ASDisplayNode { public var valueUpdated: ((Bool) -> Void)? public var frameColor = UIColor(rgb: 0xe0e0e0) { diff --git a/submodules/SwitchNode/Sources/SwitchNode.h b/submodules/SwitchNode/Sources/SwitchNode.h new file mode 100644 index 0000000000..0931e49023 --- /dev/null +++ b/submodules/SwitchNode/Sources/SwitchNode.h @@ -0,0 +1,19 @@ +// +// SwitchNode.h +// SwitchNode +// +// Created by Peter on 8/1/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for SwitchNode. +FOUNDATION_EXPORT double SwitchNodeVersionNumber; + +//! Project version string for SwitchNode. +FOUNDATION_EXPORT const unsigned char SwitchNodeVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/SwitchNode/SwitchNode_Xcode.xcodeproj/project.pbxproj b/submodules/SwitchNode/SwitchNode_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..a53b293393 --- /dev/null +++ b/submodules/SwitchNode/SwitchNode_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,559 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D060188A22F3604000796784 /* SwitchNode.h in Headers */ = {isa = PBXBuildFile; fileRef = D060188822F3604000796784 /* SwitchNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D060189522F3615800796784 /* IconSwitchNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D060189422F3615800796784 /* IconSwitchNode.swift */; }; + D060189822F3616300796784 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060189722F3616300796784 /* Foundation.framework */; }; + D060189A22F3616600796784 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060189922F3616600796784 /* UIKit.framework */; }; + D060189C22F3616A00796784 /* AsyncDisplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060189B22F3616A00796784 /* AsyncDisplayKit.framework */; }; + D060189E22F3616E00796784 /* LegacyComponents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060189D22F3616E00796784 /* LegacyComponents.framework */; }; + D0A0B53922F370DF00628AF3 /* Display.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0A0B53822F370DF00628AF3 /* Display.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D060188522F3604000796784 /* SwitchNode.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwitchNode.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060188822F3604000796784 /* SwitchNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwitchNode.h; sourceTree = ""; }; + D060188922F3604000796784 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D060189422F3615800796784 /* IconSwitchNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IconSwitchNode.swift; sourceTree = ""; }; + D060189722F3616300796784 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D060189922F3616600796784 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D060189B22F3616A00796784 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060189D22F3616E00796784 /* LegacyComponents.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = LegacyComponents.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0A0B53822F370DF00628AF3 /* Display.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Display.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D060188222F3604000796784 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D0A0B53922F370DF00628AF3 /* Display.framework in Frameworks */, + D060189E22F3616E00796784 /* LegacyComponents.framework in Frameworks */, + D060189C22F3616A00796784 /* AsyncDisplayKit.framework in Frameworks */, + D060189A22F3616600796784 /* UIKit.framework in Frameworks */, + D060189822F3616300796784 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D060187B22F3604000796784 = { + isa = PBXGroup; + children = ( + D060188922F3604000796784 /* Info.plist */, + D060188722F3604000796784 /* Sources */, + D060188622F3604000796784 /* Products */, + D060189622F3616300796784 /* Frameworks */, + ); + sourceTree = ""; + }; + D060188622F3604000796784 /* Products */ = { + isa = PBXGroup; + children = ( + D060188522F3604000796784 /* SwitchNode.framework */, + ); + name = Products; + sourceTree = ""; + }; + D060188722F3604000796784 /* Sources */ = { + isa = PBXGroup; + children = ( + D060189422F3615800796784 /* IconSwitchNode.swift */, + D060188822F3604000796784 /* SwitchNode.h */, + ); + path = Sources; + sourceTree = ""; + }; + D060189622F3616300796784 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D0A0B53822F370DF00628AF3 /* Display.framework */, + D060189D22F3616E00796784 /* LegacyComponents.framework */, + D060189B22F3616A00796784 /* AsyncDisplayKit.framework */, + D060189922F3616600796784 /* UIKit.framework */, + D060189722F3616300796784 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D060188022F3604000796784 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D060188A22F3604000796784 /* SwitchNode.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D060188422F3604000796784 /* SwitchNode */ = { + isa = PBXNativeTarget; + buildConfigurationList = D060188D22F3604000796784 /* Build configuration list for PBXNativeTarget "SwitchNode" */; + buildPhases = ( + D060188022F3604000796784 /* Headers */, + D060188122F3604000796784 /* Sources */, + D060188222F3604000796784 /* Frameworks */, + D060188322F3604000796784 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwitchNode; + productName = SwitchNode; + productReference = D060188522F3604000796784 /* SwitchNode.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D060187C22F3604000796784 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D060188422F3604000796784 = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1010; + }; + }; + }; + buildConfigurationList = D060187F22F3604000796784 /* Build configuration list for PBXProject "SwitchNode_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D060187B22F3604000796784; + productRefGroup = D060188622F3604000796784 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D060188422F3604000796784 /* SwitchNode */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D060188322F3604000796784 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D060188122F3604000796784 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D060189522F3615800796784 /* IconSwitchNode.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D060188B22F3604000796784 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D060188C22F3604000796784 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D060188E22F3604000796784 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.SwitchNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D060188F22F3604000796784 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.SwitchNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D060189022F360BF00796784 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D060189122F360BF00796784 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.SwitchNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D060189222F360CA00796784 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D060189322F360CA00796784 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.SwitchNode; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D060187F22F3604000796784 /* Build configuration list for PBXProject "SwitchNode_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D060188B22F3604000796784 /* DebugAppStoreLLC */, + D060189022F360BF00796784 /* DebugHockeyapp */, + D060188C22F3604000796784 /* ReleaseAppStoreLLC */, + D060189222F360CA00796784 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D060188D22F3604000796784 /* Build configuration list for PBXNativeTarget "SwitchNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D060188E22F3604000796784 /* DebugAppStoreLLC */, + D060189122F360BF00796784 /* DebugHockeyapp */, + D060188F22F3604000796784 /* ReleaseAppStoreLLC */, + D060189322F360CA00796784 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D060187C22F3604000796784 /* Project object */; +} From da3c7280a37231dadd2e7d9129a902ed0bbe80bb Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:23:21 +0300 Subject: [PATCH 35/41] Move presentation resources to TelegramPresentationData --- .../Sources/ChatMessageBubbleImages.swift | 188 +++++++++++++++++ .../Sources/FrameworkSpecific.swift | 13 ++ .../PresentationThemeEssentialGraphics.swift | 1 - .../Resources}/PresentationResourceKey.swift | 4 +- .../PresentationResourcesCallList.swift | 7 +- .../PresentationResourcesChat.swift | 190 +++++++++--------- .../PresentationResourcesChatList.swift | 40 ++-- .../PresentationResourcesItemList.swift | 36 ++-- .../PresentationResourcesRootController.swift | 52 ++--- .../PresentationResourcesSettings.swift | 28 +++ .../Sources/WallpaperUtils.swift | 30 +++ .../project.pbxproj | 52 +++++ .../PresentationResourcesSettings.swift | 28 --- 13 files changed, 475 insertions(+), 194 deletions(-) create mode 100644 submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift create mode 100644 submodules/TelegramPresentationData/Sources/FrameworkSpecific.swift rename submodules/{TelegramUI/TelegramUI => TelegramPresentationData/Sources}/PresentationThemeEssentialGraphics.swift (99%) rename submodules/{TelegramUI/TelegramUI => TelegramPresentationData/Sources/Resources}/PresentationResourceKey.swift (98%) rename submodules/{TelegramUI/TelegramUI => TelegramPresentationData/Sources/Resources}/PresentationResourcesCallList.swift (71%) rename submodules/{TelegramUI/TelegramUI => TelegramPresentationData/Sources/Resources}/PresentationResourcesChat.swift (86%) rename submodules/{TelegramUI/TelegramUI => TelegramPresentationData/Sources/Resources}/PresentationResourcesChatList.swift (89%) rename submodules/{TelegramUI/TelegramUI => TelegramPresentationData/Sources/Resources}/PresentationResourcesItemList.swift (85%) rename submodules/{TelegramUI/TelegramUI => TelegramPresentationData/Sources/Resources}/PresentationResourcesRootController.swift (86%) create mode 100644 submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesSettings.swift create mode 100644 submodules/TelegramPresentationData/Sources/WallpaperUtils.swift delete mode 100644 submodules/TelegramUI/TelegramUI/PresentationResourcesSettings.swift diff --git a/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift b/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift new file mode 100644 index 0000000000..deb72cd8ab --- /dev/null +++ b/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift @@ -0,0 +1,188 @@ +import Foundation +import UIKit +import Display + +public enum MessageBubbleImageNeighbors { + case none + case top(side: Bool) + case bottom + case both + case side +} + +public func messageSingleBubbleLikeImage(fillColor: UIColor, strokeColor: UIColor) -> UIImage { + let diameter: CGFloat = 36.0 + return generateImage(CGSize(width: 36.0, height: diameter), contextGenerator: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + + let lineWidth: CGFloat = 0.5 + + context.setFillColor(strokeColor.cgColor) + context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) + context.setFillColor(fillColor.cgColor) + context.fillEllipse(in: CGRect(origin: CGPoint(x: lineWidth, y: lineWidth), size: CGSize(width: size.width - lineWidth * 2.0, height: size.height - lineWidth * 2.0))) + })!.stretchableImage(withLeftCapWidth: Int(diameter / 2.0), topCapHeight: Int(diameter / 2.0)) +} + +public func messageBubbleImage(incoming: Bool, fillColor: UIColor, strokeColor: UIColor, neighbors: MessageBubbleImageNeighbors) -> UIImage { + let diameter: CGFloat = 36.0 + let corner: CGFloat = 7.0 + return generateImage(CGSize(width: 42.0, height: diameter), contextGenerator: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + + let additionalOffset: CGFloat + switch neighbors { + case .none, .bottom: + additionalOffset = 0.0 + case .both, .side, .top: + additionalOffset = 6.0 + } + + context.translateBy(x: size.width / 2.0, y: size.height / 2.0) + context.scaleBy(x: incoming ? 1.0 : -1.0, y: -1.0) + context.translateBy(x: -size.width / 2.0 + 0.5 + additionalOffset, y: -size.height / 2.0 + 0.5) + + let lineWidth: CGFloat = 1.0 + + context.setFillColor(fillColor.cgColor) + context.setLineWidth(lineWidth) + context.setStrokeColor(strokeColor.cgColor) + + switch neighbors { + case .none: + let _ = try? drawSvgPath(context, path: "M6,17.5 C6,7.83289181 13.8350169,0 23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41102995e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") + context.strokePath() + let _ = try? drawSvgPath(context, path: "M6,17.5 C6,7.83289181 13.8350169,0 23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41102995e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") + context.fillPath() + case .side: + context.strokeEllipse(in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 35.0, height: 35.0))) + context.strokePath() + context.fillEllipse(in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 35.0, height: 35.0))) + case let .top(side): + if side { + let _ = try? drawSvgPath(context, path: "M17.5,0 L17.5,0 C27.1649831,-1.7754286e-15 35,7.83501688 35,17.5 L35,29 C35,32.3137085 32.3137085,35 29,35 L6,35 C2.6862915,35 4.05812251e-16,32.3137085 0,29 L0,17.5 C-1.18361906e-15,7.83501688 7.83501688,1.7754286e-15 17.5,0 ") + context.strokePath() + let _ = try? drawSvgPath(context, path: "M17.5,0 L17.5,0 C27.1649831,-1.7754286e-15 35,7.83501688 35,17.5 L35,29 C35,32.3137085 32.3137085,35 29,35 L6,35 C2.6862915,35 4.05812251e-16,32.3137085 0,29 L0,17.5 C-1.18361906e-15,7.83501688 7.83501688,1.7754286e-15 17.5,0 ") + context.fillPath() + } else { + let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L17.5,0 C7.83501688,0 0,7.83289181 0,17.5 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") + context.strokePath() + let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L17.5,0 C7.83501688,0 0,7.83289181 0,17.5 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") + context.fillPath() + } + case .bottom: + let _ = try? drawSvgPath(context, path: "M6,17.5 L6,5.99681848 C6,2.6882755 8.68486709,0 11.9968185,0 L23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41103066e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") + context.strokePath() + let _ = try? drawSvgPath(context, path: "M6,17.5 L6,5.99681848 C6,2.6882755 8.68486709,0 11.9968185,0 L23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41103066e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") + context.fillPath() + case .both: + let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L5.99681848,0 C2.68486709,0 0,2.6882755 0,5.99681848 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") + context.strokePath() + let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L5.99681848,0 C2.68486709,0 0,2.6882755 0,5.99681848 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") + context.fillPath() + } + })!.stretchableImage(withLeftCapWidth: incoming ? Int(corner + diameter / 2.0) : Int(diameter / 2.0), topCapHeight: Int(diameter / 2.0)) +} + +public enum MessageBubbleActionButtonPosition { + case middle + case bottomLeft + case bottomRight + case bottomSingle +} + +public func messageBubbleActionButtonImage(color: UIColor, strokeColor: UIColor, position: MessageBubbleActionButtonPosition) -> UIImage { + let largeRadius: CGFloat = 17.0 + let smallRadius: CGFloat = 6.0 + let size: CGSize + if case .middle = position { + size = CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius) + } else { + size = CGSize(width: 35.0, height: 35.0) + } + return generateImage(size, contextGenerator: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + context.translateBy(x: size.width / 2.0, y: size.height / 2.0) + if case .bottomRight = position { + context.scaleBy(x: -1.0, y: -1.0) + } else { + context.scaleBy(x: 1.0, y: -1.0) + } + context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0) + context.setBlendMode(.copy) + var effectiveStrokeColor: UIColor? + var strokeAlpha: CGFloat = 0.0 + strokeColor.getRed(nil, green: nil, blue: nil, alpha: &strokeAlpha) + if !strokeAlpha.isZero { + effectiveStrokeColor = strokeColor + } + context.setFillColor(color.cgColor) + let lineWidth: CGFloat = 1.0 + let halfLineWidth = lineWidth / 2.0 + if let effectiveStrokeColor = effectiveStrokeColor { + context.setStrokeColor(effectiveStrokeColor.cgColor) + context.setLineWidth(lineWidth) + } + switch position { + case .middle: + context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) + if effectiveStrokeColor != nil { + context.setBlendMode(.normal) + context.strokeEllipse(in: CGRect(origin: CGPoint(x: halfLineWidth, y: halfLineWidth), size: CGSize(width: size.width - lineWidth, height: size.height - lineWidth))) + context.setBlendMode(.copy) + } + case .bottomLeft, .bottomRight: + context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) + context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) + context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - smallRadius - smallRadius, y: 0.0), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) + context.fill(CGRect(origin: CGPoint(x: smallRadius, y: 0.0), size: CGSize(width: size.width - smallRadius - smallRadius, height: smallRadius + smallRadius))) + context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) + context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) + context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - smallRadius - smallRadius, y: 0.0), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) + context.fill(CGRect(origin: CGPoint(x: smallRadius, y: 0.0), size: CGSize(width: size.width - smallRadius - smallRadius, height: smallRadius + smallRadius))) + context.fill(CGRect(origin: CGPoint(x: 0.0, y: smallRadius), size: CGSize(width: size.width, height: size.height - largeRadius - smallRadius))) + context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - smallRadius - smallRadius, y: size.height - smallRadius - smallRadius), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) + context.fill(CGRect(origin: CGPoint(x: largeRadius, y: size.height - largeRadius - largeRadius), size: CGSize(width: size.width - smallRadius - largeRadius, height: largeRadius + largeRadius))) + context.fill(CGRect(origin: CGPoint(x: size.width - smallRadius, y: size.height - largeRadius), size: CGSize(width: smallRadius, height: largeRadius - smallRadius))) + if effectiveStrokeColor != nil { + context.setBlendMode(.normal) + context.beginPath() + context.move(to: CGPoint(x: halfLineWidth, y: smallRadius + halfLineWidth)) + context.addArc(tangent1End: CGPoint(x: halfLineWidth, y: halfLineWidth), tangent2End: CGPoint(x: halfLineWidth + smallRadius, y: halfLineWidth), radius: smallRadius) + context.addLine(to: CGPoint(x: size.width - smallRadius, y: halfLineWidth)) + context.addArc(tangent1End: CGPoint(x: size.width - halfLineWidth, y: halfLineWidth), tangent2End: CGPoint(x: size.width - halfLineWidth, y: halfLineWidth + smallRadius), radius: smallRadius) + context.addLine(to: CGPoint(x: size.width - halfLineWidth, y: size.height - halfLineWidth - smallRadius)) + context.addArc(tangent1End: CGPoint(x: size.width - halfLineWidth, y: size.height - halfLineWidth), tangent2End: CGPoint(x: size.width - halfLineWidth - smallRadius, y: size.height - halfLineWidth), radius: smallRadius) + context.addLine(to: CGPoint(x: halfLineWidth + largeRadius, y: size.height - halfLineWidth)) + context.addArc(tangent1End: CGPoint(x: halfLineWidth, y: size.height - halfLineWidth), tangent2End: CGPoint(x: halfLineWidth, y: size.height - halfLineWidth - largeRadius), radius: largeRadius) + + context.closePath() + context.strokePath() + context.setBlendMode(.copy) + } + case .bottomSingle: + context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) + context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) + context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - smallRadius - smallRadius, y: 0.0), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) + context.fill(CGRect(origin: CGPoint(x: smallRadius, y: 0.0), size: CGSize(width: size.width - smallRadius - smallRadius, height: smallRadius + smallRadius))) + context.fill(CGRect(origin: CGPoint(x: 0.0, y: smallRadius), size: CGSize(width: size.width, height: size.height - largeRadius - smallRadius))) + + if effectiveStrokeColor != nil { + context.setBlendMode(.normal) + context.beginPath() + context.move(to: CGPoint(x: halfLineWidth, y: smallRadius + halfLineWidth)) + context.addArc(tangent1End: CGPoint(x: halfLineWidth, y: halfLineWidth), tangent2End: CGPoint(x: halfLineWidth + smallRadius, y: halfLineWidth), radius: smallRadius) + context.addLine(to: CGPoint(x: size.width - smallRadius, y: halfLineWidth)) + context.addArc(tangent1End: CGPoint(x: size.width - halfLineWidth, y: halfLineWidth), tangent2End: CGPoint(x: size.width - halfLineWidth, y: halfLineWidth + smallRadius), radius: smallRadius) + context.addLine(to: CGPoint(x: size.width - halfLineWidth, y: size.height - halfLineWidth - largeRadius)) + context.addArc(tangent1End: CGPoint(x: size.width - halfLineWidth, y: size.height - halfLineWidth), tangent2End: CGPoint(x: size.width - halfLineWidth - largeRadius, y: size.height - halfLineWidth), radius: largeRadius) + context.addLine(to: CGPoint(x: halfLineWidth + largeRadius, y: size.height - halfLineWidth)) + context.addArc(tangent1End: CGPoint(x: halfLineWidth, y: size.height - halfLineWidth), tangent2End: CGPoint(x: halfLineWidth, y: size.height - halfLineWidth - largeRadius), radius: largeRadius) + + context.closePath() + context.strokePath() + context.setBlendMode(.copy) + } + } + })!.stretchableImage(withLeftCapWidth: Int(size.width / 2.0), topCapHeight: Int(size.height / 2.0)) +} diff --git a/submodules/TelegramPresentationData/Sources/FrameworkSpecific.swift b/submodules/TelegramPresentationData/Sources/FrameworkSpecific.swift new file mode 100644 index 0000000000..8ca13d7d92 --- /dev/null +++ b/submodules/TelegramPresentationData/Sources/FrameworkSpecific.swift @@ -0,0 +1,13 @@ +import Foundation +import UIKit + +private class FrameworkBundleClass: NSObject { +} + +let frameworkBundle: Bundle = Bundle(for: FrameworkBundleClass.self) + +extension UIImage { + convenience init?(bundleImageName: String) { + self.init(named: bundleImageName, in: frameworkBundle, compatibleWith: nil) + } +} diff --git a/submodules/TelegramUI/TelegramUI/PresentationThemeEssentialGraphics.swift b/submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift similarity index 99% rename from submodules/TelegramUI/TelegramUI/PresentationThemeEssentialGraphics.swift rename to submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift index e0c3fadda5..ae6edcffc1 100644 --- a/submodules/TelegramUI/TelegramUI/PresentationThemeEssentialGraphics.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift @@ -2,7 +2,6 @@ import Foundation import UIKit import Display import TelegramCore -import TelegramPresentationData private func generateCheckImage(partial: Bool, color: UIColor) -> UIImage? { return generateImage(CGSize(width: 11.0, height: 9.0), rotatedContext: { size, context in diff --git a/submodules/TelegramUI/TelegramUI/PresentationResourceKey.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift similarity index 98% rename from submodules/TelegramUI/TelegramUI/PresentationResourceKey.swift rename to submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift index 2e071ccb40..dfe1325e08 100644 --- a/submodules/TelegramUI/TelegramUI/PresentationResourceKey.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift @@ -1,9 +1,9 @@ import Foundation -struct PresentationResources { +public struct PresentationResources { } -enum PresentationResourceKey: Int32 { +public enum PresentationResourceKey: Int32 { case rootNavigationIndefiniteActivity case rootTabContactsIcon diff --git a/submodules/TelegramUI/TelegramUI/PresentationResourcesCallList.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesCallList.swift similarity index 71% rename from submodules/TelegramUI/TelegramUI/PresentationResourcesCallList.swift rename to submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesCallList.swift index 18943b6698..89f5a4e0d7 100644 --- a/submodules/TelegramUI/TelegramUI/PresentationResourcesCallList.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesCallList.swift @@ -1,16 +1,15 @@ import Foundation import UIKit import Display -import TelegramPresentationData -struct PresentationResourcesCallList { - static func outgoingIcon(_ theme: PresentationTheme) -> UIImage? { +public struct PresentationResourcesCallList { + public static func outgoingIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.callListOutgoingIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Call List/OutgoingIcon"), color: theme.list.disclosureArrowColor) }) } - static func infoButton(_ theme: PresentationTheme) -> UIImage? { + public static func infoButton(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.callListInfoButton.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Call List/InfoButton"), color: theme.list.itemAccentColor) }) diff --git a/submodules/TelegramUI/TelegramUI/PresentationResourcesChat.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift similarity index 86% rename from submodules/TelegramUI/TelegramUI/PresentationResourcesChat.swift rename to submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift index 0239693f0b..6766585161 100644 --- a/submodules/TelegramUI/TelegramUI/PresentationResourcesChat.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift @@ -38,8 +38,8 @@ private func generateInputPanelButtonBackgroundImage(fillColor: UIColor, strokeC })?.stretchableImage(withLeftCapWidth: Int(radius), topCapHeight: Int(radius)) } -struct PresentationResourcesChat { - static func chatTitleLockIcon(_ theme: PresentationTheme) -> UIImage? { +public struct PresentationResourcesChat { + public static func chatTitleLockIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatTitleLockIcon.rawValue, { theme in return generateImage(CGSize(width: 9.0, height: 13.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -56,7 +56,7 @@ struct PresentationResourcesChat { }) } - static func chatTitleMuteIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatTitleMuteIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatTitleMuteIcon.rawValue, { theme in return generateImage(CGSize(width: 9.0, height: 9.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -67,7 +67,7 @@ struct PresentationResourcesChat { }) } - static func principalGraphics(_ theme: PresentationTheme, wallpaper: TelegramWallpaper) -> PrincipalThemeEssentialGraphics { + public static func principalGraphics(_ theme: PresentationTheme, wallpaper: TelegramWallpaper) -> PrincipalThemeEssentialGraphics { let hasWallpaper = !wallpaper.isEmpty let key: PresentationResourceKey = !hasWallpaper ? PresentationResourceKey.chatPrincipalThemeEssentialGraphicsWithoutWallpaper : PresentationResourceKey.chatPrincipalThemeEssentialGraphicsWithWallpaper return theme.object(key.rawValue, { theme in @@ -75,50 +75,50 @@ struct PresentationResourcesChat { }) as! PrincipalThemeEssentialGraphics } - static func additionalGraphics(_ theme: PresentationTheme, wallpaper: TelegramWallpaper) -> PrincipalThemeAdditionalGraphics { + public static func additionalGraphics(_ theme: PresentationTheme, wallpaper: TelegramWallpaper) -> PrincipalThemeAdditionalGraphics { let key: PresentationResourceKey = wallpaper.isBuiltin ? PresentationResourceKey.chatPrincipalThemeAdditionalGraphicsWithDefaultWallpaper : PresentationResourceKey.chatPrincipalThemeAdditionalGraphicsWithCustomWallpaper return theme.object(key.rawValue, { theme in return PrincipalThemeAdditionalGraphics(theme.chat, wallpaper: wallpaper) }) as! PrincipalThemeAdditionalGraphics } - static func chatBubbleVerticalLineIncomingImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleVerticalLineIncomingImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleVerticalLineIncomingImage.rawValue, { theme in return generateLineImage(color: theme.chat.message.incoming.accentControlColor) }) } - static func chatBubbleVerticalLineOutgoingImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleVerticalLineOutgoingImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleVerticalLineOutgoingImage.rawValue, { theme in return generateLineImage(color: theme.chat.message.outgoing.accentControlColor) }) } - static func chatBubbleConsumableContentIncomingIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleConsumableContentIncomingIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleConsumableContentIncomingIcon.rawValue, { theme in return generateFilledCircleImage(diameter: 4.0, color: theme.chat.message.incoming.accentControlColor) }) } - static func chatBubbleConsumableContentOutgoingIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleConsumableContentOutgoingIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleConsumableContentOutgoingIcon.rawValue, { theme in return generateFilledCircleImage(diameter: 4.0, color: theme.chat.message.outgoing.accentControlColor) }) } - static func chatMediaConsumableContentIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatMediaConsumableContentIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatMediaConsumableContentIcon.rawValue, { theme in return generateFilledCircleImage(diameter: 4.0, color: theme.chat.message.mediaDateAndStatusTextColor) }) } - static func chatBubbleSecretMediaIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleSecretMediaIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleSecretMediaIcon.rawValue, { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/SecretMediaIcon"), color: theme.chat.message.mediaOverlayControlColors.foregroundColor) }) } - static func chatBubbleSecretMediaCompactIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleSecretMediaCompactIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleSecretMediaCompactIcon.rawValue, { theme in if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/SecretMediaIcon"), color: theme.chat.message.mediaOverlayControlColors.foregroundColor) { let factor: CGFloat = 0.6 @@ -132,14 +132,14 @@ struct PresentationResourcesChat { }) } - static func chatInstantVideoBackgroundImage(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? { + public static func chatInstantVideoBackgroundImage(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? { let key: PresentationResourceKey = !wallpaper ? PresentationResourceKey.chatInstantVideoWithoutWallpaperBackgroundImage : PresentationResourceKey.chatInstantVideoWithWallpaperBackgroundImage return theme.image(key.rawValue, { theme in return generateInstantVideoBackground(fillColor: theme.chat.message.freeform.withWallpaper.fill, strokeColor: theme.chat.message.freeform.withWallpaper.stroke) }) } - static func chatUnreadBarBackgroundImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatUnreadBarBackgroundImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatUnreadBarBackgroundImage.rawValue, { theme in return generateImage(CGSize(width: 1.0, height: 8.0), contextGenerator: { size, context -> Void in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -152,13 +152,13 @@ struct PresentationResourcesChat { }) } - static func chatInfoItemBackgroundImageWithoutWallpaper(_ theme: PresentationTheme) -> UIImage? { + public static func chatInfoItemBackgroundImageWithoutWallpaper(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInfoItemBackgroundImageWithoutWallpaper.rawValue, { theme in return messageSingleBubbleLikeImage(fillColor: theme.chat.message.incoming.bubble.withoutWallpaper.fill, strokeColor: theme.chat.message.incoming.bubble.withoutWallpaper.stroke) }) } - static func chatInfoItemBackgroundImage(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? { + public static func chatInfoItemBackgroundImage(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? { let key: PresentationResourceKey = !wallpaper ? PresentationResourceKey.chatInfoItemBackgroundImageWithoutWallpaper : PresentationResourceKey.chatInfoItemBackgroundImageWithWallpaper return theme.image(key.rawValue, { theme in let components: PresentationThemeBubbleColorComponents = wallpaper ? theme.chat.message.incoming.bubble.withWallpaper : theme.chat.message.incoming.bubble.withoutWallpaper @@ -166,7 +166,7 @@ struct PresentationResourcesChat { }) } - static func chatInputPanelCloseIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelCloseIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelCloseIconImage.rawValue, { theme in return generateImage(CGSize(width: 12.0, height: 12.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -184,25 +184,25 @@ struct PresentationResourcesChat { }) } - static func chatInputPanelEncircledCloseIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelEncircledCloseIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelEncircledCloseIconImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/EncircledCloseButton"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatInputPanelVerticalSeparatorLineImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelVerticalSeparatorLineImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelVerticalSeparatorLineImage.rawValue, { theme in return generateVerticallyStretchableFilledCircleImage(radius: 1.0, color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatMediaInputPanelHighlightedIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatMediaInputPanelHighlightedIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatMediaInputPanelHighlightedIconImage.rawValue, { theme in return generateStretchableFilledCircleImage(radius: 9.0, color: theme.chat.inputMediaPanel.panelHighlightedIconBackgroundColor) }) } - static func chatInputMediaPanelSavedStickersIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputMediaPanelSavedStickersIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputMediaPanelSavedStickersIconImage.rawValue, { theme in return generateImage(CGSize(width: 26.0, height: 26.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -213,7 +213,7 @@ struct PresentationResourcesChat { }) } - static func chatInputMediaPanelRecentStickersIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputMediaPanelRecentStickersIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputMediaPanelRecentStickersIconImage.rawValue, { theme in return generateImage(CGSize(width: 26.0, height: 26.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -224,7 +224,7 @@ struct PresentationResourcesChat { }) } - static func chatInputMediaPanelRecentGifsIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputMediaPanelRecentGifsIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputMediaPanelRecentGifsIconImage.rawValue, { theme in return generateImage(CGSize(width: 26.0, height: 26.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -235,49 +235,49 @@ struct PresentationResourcesChat { }) } - static func chatInputMediaPanelTrendingIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputMediaPanelTrendingIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputMediaPanelTrendingIconImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Media/TrendingIcon"), color: theme.chat.inputMediaPanel.panelIconColor) }) } - static func chatInputMediaPanelSettingsIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputMediaPanelSettingsIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputMediaPanelSettingsIconImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Media/SettingsIcon"), color: theme.chat.inputMediaPanel.panelIconColor) }) } - static func chatInputMediaPanelAddPackButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputMediaPanelAddPackButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputMediaPanelAddPackButtonImage.rawValue, { theme in return generateStretchableFilledCircleImage(diameter: 8.0, color: nil, strokeColor: theme.chat.inputPanel.panelControlAccentColor, strokeWidth: 1.0, backgroundColor: nil) }) } - static func chatInputMediaPanelGridSetupImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputMediaPanelGridSetupImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputMediaPanelGridSetupImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Media/GridSetupIcon"), color: theme.chat.inputMediaPanel.panelIconColor.withAlphaComponent(0.65)) }) } - static func chatInputMediaPanelGridDismissImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputMediaPanelGridDismissImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputMediaPanelGridDismissImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Media/GridDismissIcon"), color: theme.chat.inputMediaPanel.panelIconColor.withAlphaComponent(0.65)) }) } - static func chatInputButtonPanelButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputButtonPanelButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputButtonPanelButtonImage.rawValue, { theme in return generateInputPanelButtonBackgroundImage(fillColor: theme.chat.inputButtonPanel.buttonFillColor, strokeColor: theme.chat.inputButtonPanel.buttonStrokeColor) }) } - static func chatInputButtonPanelButtonHighlightedImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputButtonPanelButtonHighlightedImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputButtonPanelButtonHighlightedImage.rawValue, { theme in return generateInputPanelButtonBackgroundImage(fillColor: theme.chat.inputButtonPanel.buttonHighlightedFillColor, strokeColor: theme.chat.inputButtonPanel.buttonHighlightedStrokeColor) }) } - static func chatInputTextFieldBackgroundImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputTextFieldBackgroundImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputTextFieldBackgroundImage.rawValue, { theme in let diameter: CGFloat = 35.0 UIGraphicsBeginImageContextWithOptions(CGSize(width: diameter, height: diameter), false, 0.0) @@ -300,7 +300,7 @@ struct PresentationResourcesChat { }) } - static func chatInputTextFieldClearImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputTextFieldClearImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputTextFieldClearImage.rawValue, { theme in return generateImage(CGSize(width: 14.0, height: 14.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -329,7 +329,7 @@ struct PresentationResourcesChat { }) } - static func chatInputPanelSendButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelSendButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelSendButtonImage.rawValue, { theme in return generateImage(CGSize(width: 33.0, height: 33.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -346,7 +346,7 @@ struct PresentationResourcesChat { }) } - static func chatInputPanelApplyButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelApplyButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelApplyButtonImage.rawValue, { theme in return generateImage(CGSize(width: 33.0, height: 33.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -362,37 +362,37 @@ struct PresentationResourcesChat { }) } - static func chatInputPanelVoiceButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelVoiceButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelVoiceButtonImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconMicrophone"), color: theme.chat.inputPanel.panelControlColor) }) } - static func chatInputPanelVideoButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelVideoButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelVideoButtonImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconVideo"), color: theme.chat.inputPanel.panelControlColor) }) } - static func chatInputPanelVoiceActiveButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelVoiceActiveButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelVoiceActiveButtonImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconMicrophone"), color: theme.chat.inputPanel.mediaRecordingControl.activeIconColor) }) } - static func chatInputPanelVideoActiveButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelVideoActiveButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelVideoActiveButtonImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconVideo"), color: theme.chat.inputPanel.mediaRecordingControl.activeIconColor) }) } - static func chatInputPanelAttachmentButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelAttachmentButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelAttachmentButtonImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconAttachment"), color: theme.chat.inputPanel.panelControlColor) }) } - static func chatInputPanelEditAttachmentButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelEditAttachmentButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelEditAttachmentButtonImage.rawValue, { theme in if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconAttachment"), color: theme.chat.inputPanel.panelControlColor) { return generateImage(image.size, rotatedContext: { size, context in @@ -439,67 +439,67 @@ struct PresentationResourcesChat { }) } - static func chatInputPanelExpandButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelExpandButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelExpandButtonImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconExpandInput"), color: theme.chat.inputPanel.panelControlColor) }) } - static func chatInputPanelMediaRecordingDotImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelMediaRecordingDotImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelMediaRecordingDotImage.rawValue, { theme in return generateFilledCircleImage(diameter: 9.0, color: theme.chat.inputPanel.mediaRecordingDotColor) }) } - static func chatInputPanelMediaRecordingCancelArrowImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputPanelMediaRecordingCancelArrowImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputPanelMediaRecordingCancelArrowImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AudioRecordingCancelArrow"), color: theme.chat.inputPanel.panelControlColor) }) } - static func chatInputTextFieldStickersImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputTextFieldStickersImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputTextFieldStickersImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconStickers"), color: theme.chat.inputPanel.inputControlColor) }) } - static func chatInputTextFieldInputButtonsImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputTextFieldInputButtonsImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputTextFieldInputButtonsImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconInputButtons"), color: theme.chat.inputPanel.inputControlColor) }) } - static func chatInputTextFieldCommandsImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputTextFieldCommandsImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputTextFieldCommandsImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconCommands"), color: theme.chat.inputPanel.inputControlColor) }) } - static func chatInputTextFieldSilentPostOnImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputTextFieldSilentPostOnImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputTextFieldSilentPostOnImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconSilentPostOn"), color: theme.chat.inputPanel.inputControlColor) }) } - static func chatInputTextFieldSilentPostOffImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputTextFieldSilentPostOffImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputTextFieldSilentPostOffImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconSilentPostOff"), color: theme.chat.inputPanel.inputControlColor) }) } - static func chatInputTextFieldKeyboardImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputTextFieldKeyboardImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputTextFieldKeyboardImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconKeyboard"), color: theme.chat.inputPanel.inputControlColor) }) } - static func chatInputTextFieldTimerImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputTextFieldTimerImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputTextFieldTimerImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconTimer"), color: theme.chat.inputPanel.inputControlColor) }) } - static func chatHistoryNavigationButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatHistoryNavigationButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatHistoryNavigationButtonImage.rawValue, { theme in return generateImage(CGSize(width: 38.0, height: 38.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -520,7 +520,7 @@ struct PresentationResourcesChat { }) } - static func chatHistoryMentionsButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatHistoryMentionsButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatHistoryMentionsButtonImage.rawValue, { theme in return generateImage(CGSize(width: 38.0, height: 38.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -537,19 +537,19 @@ struct PresentationResourcesChat { }) } - static func chatHistoryNavigationButtonBadgeImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatHistoryNavigationButtonBadgeImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatHistoryNavigationButtonBadgeImage.rawValue, { theme in return generateStretchableFilledCircleImage(diameter: 18.0, color: theme.chat.historyNavigation.badgeBackgroundColor, strokeColor: theme.chat.historyNavigation.badgeStrokeColor, strokeWidth: 1.0, backgroundColor: nil) }) } - static func sharedMediaFileDownloadStartIcon(_ theme: PresentationTheme) -> UIImage? { + public static func sharedMediaFileDownloadStartIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.sharedMediaFileDownloadStartIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "List Menu/ListDownloadStartIcon"), color: theme.list.itemAccentColor) }) } - static func sharedMediaFileDownloadPauseIcon(_ theme: PresentationTheme) -> UIImage? { + public static func sharedMediaFileDownloadPauseIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.sharedMediaFileDownloadPauseIcon.rawValue, { theme in return generateImage(CGSize(width: 11.0, height: 11.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -562,7 +562,7 @@ struct PresentationResourcesChat { }) } - static func sharedMediaInstantViewIcon(_ theme: PresentationTheme) -> UIImage? { + public static func sharedMediaInstantViewIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.sharedMediaInstantViewIcon.rawValue, { theme in return generateImage(CGSize(width: 9.0, height: 12.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -577,13 +577,13 @@ struct PresentationResourcesChat { }) } - static func chatInfoCallButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInfoCallButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInfoCallButtonImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Info/CallButton"), color: theme.list.itemAccentColor) }) } - static func chatInstantMessageInfoBackgroundImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInstantMessageInfoBackgroundImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInstantMessageInfoBackgroundImage.rawValue, { theme in return generateImage(CGSize(width: 24.0, height: 24.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -593,7 +593,7 @@ struct PresentationResourcesChat { }) } - static func chatInstantMessageMuteIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInstantMessageMuteIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInstantMessageMuteIconImage.rawValue, { theme in return generateImage(CGSize(width: 24.0, height: 24.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -605,19 +605,19 @@ struct PresentationResourcesChat { }) } - static func chatBubbleIncomingCallButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleIncomingCallButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleIncomingCallButtonImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Info/CallButton"), color: theme.chat.message.incoming.accentControlColor) }) } - static func chatBubbleOutgoingCallButtonImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleOutgoingCallButtonImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleOutgoingCallButtonImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Info/CallButton"), color: theme.chat.message.outgoing.accentControlColor) }) } - static func chatBubbleMapPinImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleMapPinImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleMapPinImage.rawValue, { theme in return generateImage(CGSize(width: 62.0, height: 74.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -634,85 +634,85 @@ struct PresentationResourcesChat { }) } - static func chatInputSearchPanelUpImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputSearchPanelUpImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputSearchPanelUpImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Search/UpButton"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatInputSearchPanelUpDisabledImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputSearchPanelUpDisabledImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputSearchPanelUpDisabledImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Search/UpButton"), color: theme.chat.inputPanel.panelControlDisabledColor) }) } - static func chatInputSearchPanelDownImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputSearchPanelDownImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputSearchPanelDownImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Search/DownButton"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatInputSearchPanelDownDisabledImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputSearchPanelDownDisabledImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputSearchPanelDownDisabledImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Search/DownButton"), color: theme.chat.inputPanel.panelControlDisabledColor) }) } - static func chatInputSearchPanelCalendarImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputSearchPanelCalendarImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputSearchPanelCalendarImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Search/Calendar"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatInputSearchPanelMembersImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatInputSearchPanelMembersImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatInputSearchPanelMembersImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Search/Members"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatTitlePanelInfoImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatTitlePanelInfoImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatTitlePanelInfoImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Title Panels/InfoIcon"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatTitlePanelSearchImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatTitlePanelSearchImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatTitlePanelSearchImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Title Panels/SearchIcon"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatTitlePanelUnarchiveImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatTitlePanelUnarchiveImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatTitlePanelUnarchiveImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Title Panels/UnarchiveIcon"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatTitlePanelMuteImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatTitlePanelMuteImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatTitlePanelMuteImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/RevealActionMuteIcon"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatTitlePanelUnmuteImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatTitlePanelUnmuteImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatTitlePanelUnmuteImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/RevealActionUnmuteIcon"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatTitlePanelCallImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatTitlePanelCallImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatTitlePanelCallImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Info/CallButton"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatTitlePanelReportImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatTitlePanelReportImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatTitlePanelReportImage.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Title Panels/ReportIcon"), color: theme.chat.inputPanel.panelControlAccentColor) }) } - static func chatTitlePanelGroupingImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatTitlePanelGroupingImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatTitlePanelGroupingImage.rawValue, { theme in return generateImage(CGSize(width: 32.0, height: 32.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -724,57 +724,57 @@ struct PresentationResourcesChat { }) } - static func chatMessageAttachedContentButtonIncoming(_ theme: PresentationTheme) -> UIImage? { + public static func chatMessageAttachedContentButtonIncoming(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatMessageAttachedContentButtonIncoming.rawValue, { theme in return generateStretchableFilledCircleImage(diameter: 9.0, color: nil, strokeColor: theme.chat.message.incoming.accentControlColor, strokeWidth: 1.0, backgroundColor: nil) }) } - static func chatMessageAttachedContentHighlightedButtonIncoming(_ theme: PresentationTheme) -> UIImage? { + public static func chatMessageAttachedContentHighlightedButtonIncoming(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatMessageAttachedContentHighlightedButtonIncoming.rawValue, { theme in return generateStretchableFilledCircleImage(diameter: 9.0, color: theme.chat.message.incoming.accentControlColor) }) } - static func chatMessageAttachedContentButtonOutgoing(_ theme: PresentationTheme) -> UIImage? { + public static func chatMessageAttachedContentButtonOutgoing(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatMessageAttachedContentButtonOutgoing.rawValue, { theme in return generateStretchableFilledCircleImage(diameter: 9.0, color: nil, strokeColor: theme.chat.message.outgoing.accentControlColor, strokeWidth: 1.0, backgroundColor: nil) }) } - static func chatMessageAttachedContentHighlightedButtonOutgoing(_ theme: PresentationTheme) -> UIImage? { + public static func chatMessageAttachedContentHighlightedButtonOutgoing(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatMessageAttachedContentHighlightedButtonOutgoing.rawValue, { theme in return generateStretchableFilledCircleImage(diameter: 9.0, color: theme.chat.message.outgoing.accentControlColor) }) } - static func chatMessageAttachedContentButtonIconInstantIncoming(_ theme: PresentationTheme) -> UIImage? { + public static func chatMessageAttachedContentButtonIconInstantIncoming(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatMessageAttachedContentButtonIconInstantIncoming.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/AttachedContentInstantIcon"), color: theme.chat.message.incoming.accentControlColor) }) } - static func chatMessageAttachedContentHighlightedButtonIconInstantIncoming(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? { + public static func chatMessageAttachedContentHighlightedButtonIconInstantIncoming(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? { let key: PresentationResourceKey = !wallpaper ? PresentationResourceKey.chatMessageAttachedContentHighlightedButtonIconInstantIncomingWithoutWallpaper : PresentationResourceKey.chatMessageAttachedContentHighlightedButtonIconInstantIncomingWithWallpaper return theme.image(key.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/AttachedContentInstantIcon"), color: bubbleColorComponents(theme: theme, incoming: true, wallpaper: wallpaper).fill) }) } - static func chatMessageAttachedContentButtonIconInstantOutgoing(_ theme: PresentationTheme) -> UIImage? { + public static func chatMessageAttachedContentButtonIconInstantOutgoing(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatMessageAttachedContentButtonIconInstantOutgoing.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/AttachedContentInstantIcon"), color: theme.chat.message.outgoing.accentControlColor) }) } - static func chatMessageAttachedContentHighlightedButtonIconInstantOutgoing(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? { + public static func chatMessageAttachedContentHighlightedButtonIconInstantOutgoing(_ theme: PresentationTheme, wallpaper: Bool) -> UIImage? { let key: PresentationResourceKey = !wallpaper ? PresentationResourceKey.chatMessageAttachedContentHighlightedButtonIconInstantOutgoingWithoutWallpaper : PresentationResourceKey.chatMessageAttachedContentHighlightedButtonIconInstantOutgoingWithWallpaper return theme.image(key.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/AttachedContentInstantIcon"), color: bubbleColorComponents(theme: theme, incoming: false, wallpaper: wallpaper).fill) }) } - static func chatBubbleReplyThumbnailPlayImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleReplyThumbnailPlayImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleReplyThumbnailPlayImage.rawValue, { theme in return generateImage(CGSize(width: 16.0, height: 16.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -806,7 +806,7 @@ struct PresentationResourcesChat { }) } - static func chatCommandPanelArrowImage(_ theme: PresentationTheme) -> UIImage? { + public static func chatCommandPanelArrowImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatCommandPanelArrowImage.rawValue, { theme in return generateImage(CGSize(width: 11.0, height: 11.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -834,7 +834,7 @@ struct PresentationResourcesChat { }) } - static func chatBubbleFileCloudFetchMediaIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleFileCloudFetchMediaIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleFileCloudFetchMediaIcon.rawValue, { theme in guard let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/FileCloudFetch"), color: theme.chat.message.mediaOverlayControlColors.foregroundColor) else { return nil @@ -846,31 +846,31 @@ struct PresentationResourcesChat { }) } - static func chatBubbleFileCloudFetchIncomingIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleFileCloudFetchIncomingIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleFileCloudFetchIncomingIcon.rawValue, { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/FileCloudFetch"), color: theme.chat.message.incoming.accentControlColor) }) } - static func chatBubbleFileCloudFetchOutgoingIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleFileCloudFetchOutgoingIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleFileCloudFetchOutgoingIcon.rawValue, { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/FileCloudFetch"), color: theme.chat.message.outgoing.accentControlColor) }) } - static func chatBubbleFileCloudFetchedIncomingIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleFileCloudFetchedIncomingIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleFileCloudFetchedIncomingIcon.rawValue, { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/FileCloudFetched"), color: theme.chat.message.incoming.accentControlColor) }) } - static func chatBubbleFileCloudFetchedOutgoingIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleFileCloudFetchedOutgoingIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleFileCloudFetchedOutgoingIcon.rawValue, { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/FileCloudFetched"), color: theme.chat.message.outgoing.accentControlColor) }) } - static func chatBubbleDeliveryFailedIcon(_ theme: PresentationTheme) -> UIImage? { + public static func chatBubbleDeliveryFailedIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatBubbleDeliveryFailedIcon.rawValue, { theme in return generateImage(CGSize(width: 22.0, height: 22.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -885,19 +885,19 @@ struct PresentationResourcesChat { }) } - static func groupInfoAdminsIcon(_ theme: PresentationTheme) -> UIImage? { + public static func groupInfoAdminsIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.groupInfoAdminsIcon.rawValue, { _ in return UIImage(bundleImageName: "Chat/Info/GroupAdminsIcon")?.precomposed() }) } - static func groupInfoPermissionsIcon(_ theme: PresentationTheme) -> UIImage? { + public static func groupInfoPermissionsIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.groupInfoPermissionsIcon.rawValue, { _ in return UIImage(bundleImageName: "Chat/Info/GroupPermissionsIcon")?.precomposed() }) } - static func groupInfoMembersIcon(_ theme: PresentationTheme) -> UIImage? { + public static func groupInfoMembersIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.groupInfoMembersIcon.rawValue, { _ in return UIImage(bundleImageName: "Chat/Info/GroupMembersIcon")?.precomposed() }) diff --git a/submodules/TelegramUI/TelegramUI/PresentationResourcesChatList.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChatList.swift similarity index 89% rename from submodules/TelegramUI/TelegramUI/PresentationResourcesChatList.swift rename to submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChatList.swift index 4799b9802c..e21dfcda23 100644 --- a/submodules/TelegramUI/TelegramUI/PresentationResourcesChatList.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChatList.swift @@ -55,21 +55,21 @@ private func generateClockMinImage(color: UIColor) -> UIImage? { }) } -enum RecentStatusOnlineIconState { +public enum RecentStatusOnlineIconState { case regular case highlighted case pinned case panel } -enum ScamIconType { +public enum ScamIconType { case regular case outgoing case service } -struct PresentationResourcesChatList { - static func pendingImage(_ theme: PresentationTheme) -> UIImage? { +public struct PresentationResourcesChatList { + public static func pendingImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListPending.rawValue, { theme in return generateImage(CGSize(width: 12.0, height: 14.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -84,31 +84,31 @@ struct PresentationResourcesChatList { }) } - static func singleCheckImage(_ theme: PresentationTheme) -> UIImage? { + public static func singleCheckImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListSingleCheck.rawValue, { theme in return generateStatusCheckImage(theme: theme, single: true) }) } - static func doubleCheckImage(_ theme: PresentationTheme) -> UIImage? { + public static func doubleCheckImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListDoubleCheck.rawValue, { theme in return generateStatusCheckImage(theme: theme, single: false) }) } - static func clockFrameImage(_ theme: PresentationTheme) -> UIImage? { + public static func clockFrameImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListClockFrame.rawValue, { theme in return generateClockFrameImage(color: theme.chatList.pendingIndicatorColor) }) } - static func clockMinImage(_ theme: PresentationTheme) -> UIImage? { + public static func clockMinImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListClockMin.rawValue, { theme in return generateClockMinImage(color: theme.chatList.pendingIndicatorColor) }) } - static func lockTopUnlockedImage(_ theme: PresentationTheme) -> UIImage? { + public static func lockTopUnlockedImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListLockTopUnlockedImage.rawValue, { theme in return generateImage(CGSize(width: 7.0, height: 6.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -124,7 +124,7 @@ struct PresentationResourcesChatList { }) } - static func lockBottomUnlockedImage(_ theme: PresentationTheme) -> UIImage? { + public static func lockBottomUnlockedImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListLockBottomUnlockedImage.rawValue, { theme in return generateImage(CGSize(width: 10.0, height: 8.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -135,7 +135,7 @@ struct PresentationResourcesChatList { }) } - static func recentStatusOnlineIcon(_ theme: PresentationTheme, state: RecentStatusOnlineIconState) -> UIImage? { + public static func recentStatusOnlineIcon(_ theme: PresentationTheme, state: RecentStatusOnlineIconState) -> UIImage? { let key: PresentationResourceKey switch state { case .regular: @@ -169,49 +169,49 @@ struct PresentationResourcesChatList { }) } - static func badgeBackgroundActive(_ theme: PresentationTheme) -> UIImage? { + public static func badgeBackgroundActive(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListBadgeBackgroundActive.rawValue, { theme in return generateBadgeBackgroundImage(theme: theme, active: true) }) } - static func badgeBackgroundInactive(_ theme: PresentationTheme) -> UIImage? { + public static func badgeBackgroundInactive(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListBadgeBackgroundInactive.rawValue, { theme in return generateBadgeBackgroundImage(theme: theme, active: false) }) } - static func badgeBackgroundMention(_ theme: PresentationTheme) -> UIImage? { + public static func badgeBackgroundMention(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListBadgeBackgroundMention.rawValue, { theme in return generateBadgeBackgroundImage(theme: theme, active: true, icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/MentionBadgeIcon"), color: theme.chatList.unreadBadgeActiveTextColor)) }) } - static func badgeBackgroundInactiveMention(_ theme: PresentationTheme) -> UIImage? { + public static func badgeBackgroundInactiveMention(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListBadgeBackgroundInactiveMention.rawValue, { theme in return generateBadgeBackgroundImage(theme: theme, active: false, icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/MentionBadgeIcon"), color: theme.chatList.unreadBadgeInactiveTextColor)) }) } - static func badgeBackgroundPinned(_ theme: PresentationTheme) -> UIImage? { + public static func badgeBackgroundPinned(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListBadgeBackgroundPinned.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/PeerPinnedIcon"), color: theme.chatList.pinnedBadgeColor) }) } - static func mutedIcon(_ theme: PresentationTheme) -> UIImage? { + public static func mutedIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListMutedIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/PeerMutedIcon"), color: theme.chatList.muteIconColor) }) } - static func verifiedIcon(_ theme: PresentationTheme) -> UIImage? { + public static func verifiedIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListVerifiedIcon.rawValue, { theme in return UIImage(bundleImageName: "Chat List/PeerVerifiedIcon")?.precomposed() }) } - static func scamIcon(_ theme: PresentationTheme, type: ScamIconType) -> UIImage? { + public static func scamIcon(_ theme: PresentationTheme, type: ScamIconType) -> UIImage? { let key: PresentationResourceKey let color: UIColor switch type { @@ -247,7 +247,7 @@ struct PresentationResourcesChatList { }) } - static func secretIcon(_ theme: PresentationTheme) -> UIImage? { + public static func secretIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatListSecretIcon.rawValue, { theme in return generateImage(CGSize(width: 9.0, height: 12.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) diff --git a/submodules/TelegramUI/TelegramUI/PresentationResourcesItemList.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift similarity index 85% rename from submodules/TelegramUI/TelegramUI/PresentationResourcesItemList.swift rename to submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift index 73faca85b1..30417c5c09 100644 --- a/submodules/TelegramUI/TelegramUI/PresentationResourcesItemList.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift @@ -16,7 +16,7 @@ private func generateArrowImage(_ theme: PresentationTheme) -> UIImage? { }) } -func generateItemListCheckIcon(color: UIColor) -> UIImage? { +public func generateItemListCheckIcon(color: UIColor) -> UIImage? { return generateImage(CGSize(width: 12.0, height: 10.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) context.setStrokeColor(color.cgColor) @@ -29,7 +29,7 @@ func generateItemListCheckIcon(color: UIColor) -> UIImage? { }) } -func generateItemListPlusIcon(_ color: UIColor) -> UIImage? { +public func generateItemListPlusIcon(_ color: UIColor) -> UIImage? { return generateImage(CGSize(width: 18.0, height: 18.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) context.setFillColor(color.cgColor) @@ -40,42 +40,42 @@ func generateItemListPlusIcon(_ color: UIColor) -> UIImage? { }) } -struct PresentationResourcesItemList { - static func disclosureArrowImage(_ theme: PresentationTheme) -> UIImage? { +public struct PresentationResourcesItemList { + public static func disclosureArrowImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListDisclosureArrow.rawValue, generateArrowImage) } - static func checkIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func checkIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListCheckIcon.rawValue, { theme in return generateItemListCheckIcon(color: theme.list.itemAccentColor) }) } - static func secondaryCheckIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func secondaryCheckIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListSecondaryCheckIcon.rawValue, { theme in return generateItemListCheckIcon(color: theme.list.itemSecondaryTextColor) }) } - static func plusIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func plusIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListPlusIcon.rawValue, { theme in return generateItemListPlusIcon(theme.list.itemAccentColor) }) } - static func stickerUnreadDotImage(_ theme: PresentationTheme) -> UIImage? { + public static func stickerUnreadDotImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListStickerItemUnreadDot.rawValue, { theme in return generateFilledCircleImage(diameter: 6.0, color: theme.list.itemAccentColor) }) } - static func verifiedPeerIcon(_ theme: PresentationTheme) -> UIImage? { + public static func verifiedPeerIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListVerifiedPeerIcon.rawValue, { theme in return UIImage(bundleImageName: "Item List/PeerVerifiedIcon")?.precomposed() }) } - static func itemListDeleteIndicatorIcon(_ theme: PresentationTheme) -> UIImage? { + public static func itemListDeleteIndicatorIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListDeleteIndicatorIcon.rawValue, { theme in guard let image = generateTintedImage(image: UIImage(bundleImageName: "Item List/RemoveItemIcon"), color: theme.list.itemDestructiveColor) else { return nil @@ -89,7 +89,7 @@ struct PresentationResourcesItemList { }) } - static func itemListReorderIndicatorIcon(_ theme: PresentationTheme) -> UIImage? { + public static func itemListReorderIndicatorIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListReorderIndicatorIcon.rawValue, { theme in generateImage(CGSize(width: 16.0, height: 9.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -102,25 +102,25 @@ struct PresentationResourcesItemList { }) } - static func addPersonIcon(_ theme: PresentationTheme) -> UIImage? { + public static func addPersonIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListAddPersonIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Contact List/AddMemberIcon"), color: theme.list.itemAccentColor) }) } - static func createGroupIcon(_ theme: PresentationTheme) -> UIImage? { + public static func createGroupIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListCreateGroupIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Location/CreateGroupIcon"), color: theme.list.itemAccentColor) }) } - static func addExceptionIcon(_ theme: PresentationTheme) -> UIImage? { + public static func addExceptionIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListAddExceptionIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Item List/AddExceptionIcon"), color: theme.list.itemAccentColor) }) } - static func addPhoneIcon(_ theme: PresentationTheme) -> UIImage? { + public static func addPhoneIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListAddPhoneIcon.rawValue, { theme in guard let image = generateTintedImage(image: UIImage(bundleImageName: "Item List/AddItemIcon"), color: theme.list.itemAccentColor) else { return nil @@ -134,19 +134,19 @@ struct PresentationResourcesItemList { }) } - static func itemListClearInputIcon(_ theme: PresentationTheme) -> UIImage? { + public static func itemListClearInputIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListClearInputIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Components/Search Bar/Clear"), color: theme.list.inputClearButtonColor) }) } - static func cloudFetchIcon(_ theme: PresentationTheme) -> UIImage? { + public static func cloudFetchIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListCloudFetchIcon.rawValue, { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/FileCloudFetch"), color: theme.list.itemAccentColor) }) } - static func itemListCloseIconImage(_ theme: PresentationTheme) -> UIImage? { + public static func itemListCloseIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListCloseIconImage.rawValue, { theme in return generateImage(CGSize(width: 12.0, height: 12.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) diff --git a/submodules/TelegramUI/TelegramUI/PresentationResourcesRootController.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift similarity index 86% rename from submodules/TelegramUI/TelegramUI/PresentationResourcesRootController.swift rename to submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift index f047389114..8b8fc7b2cc 100644 --- a/submodules/TelegramUI/TelegramUI/PresentationResourcesRootController.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift @@ -7,7 +7,7 @@ private func generateShareButtonImage(theme: PresentationTheme) -> UIImage? { return generateTintedImage(image: UIImage(bundleImageName: "Chat List/NavigationShare"), color: theme.rootController.navigationBar.accentTextColor) } -func generateIndefiniteActivityIndicatorImage(color: UIColor, diameter: CGFloat = 22.0, lineWidth: CGFloat = 2.0) -> UIImage? { +public func generateIndefiniteActivityIndicatorImage(color: UIColor, diameter: CGFloat = 22.0, lineWidth: CGFloat = 2.0) -> UIImage? { return generateImage(CGSize(width: diameter, height: diameter), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) context.setStrokeColor(color.cgColor) @@ -19,7 +19,7 @@ func generateIndefiniteActivityIndicatorImage(color: UIColor, diameter: CGFloat }) } -func generatePlayerRateIcon(_ color: UIColor) -> UIImage? { +public func generatePlayerRateIcon(_ color: UIColor) -> UIImage? { return generateImage(CGSize(width: 19.0, height: 16.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) context.setFillColor(color.cgColor) @@ -30,42 +30,42 @@ func generatePlayerRateIcon(_ color: UIColor) -> UIImage? { }) } -struct PresentationResourcesRootController { - static func navigationIndefiniteActivityImage(_ theme: PresentationTheme) -> UIImage? { +public struct PresentationResourcesRootController { + public static func navigationIndefiniteActivityImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.rootNavigationIndefiniteActivity.rawValue, { theme in generateIndefiniteActivityIndicatorImage(color: theme.rootController.navigationBar.accentTextColor) }) } - static func navigationComposeIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationComposeIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationComposeIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/ComposeIcon"), color: theme.rootController.navigationBar.accentTextColor) }) } - static func navigationShareIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationShareIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationShareIcon.rawValue, generateShareButtonImage) } - static func navigationCallIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationCallIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationCallIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Info/CallButton"), color: theme.rootController.navigationBar.accentTextColor) }) } - static func navigationInfoIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationInfoIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationInfoIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/InfoIcon"), color: theme.rootController.navigationBar.accentTextColor) }) } - static func navigationSearchIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationSearchIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationSearchIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/SearchIcon"), color: theme.rootController.navigationBar.accentTextColor) }) } - static func navigationCompactSearchIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationCompactSearchIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationCompactSearchIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/SearchIcon"), color: theme.rootController.navigationBar.accentTextColor).flatMap({ image in let factor: CGFloat = 0.8 @@ -78,13 +78,13 @@ struct PresentationResourcesRootController { }) } - static func navigationAddIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationAddIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationAddIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/AddIcon"), color: theme.rootController.navigationBar.accentTextColor) }) } - static func navigationPlayerCloseButton(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerCloseButton(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerCloseButton.rawValue, { theme in return generateImage(CGSize(width: 12.0, height: 12.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -101,79 +101,79 @@ struct PresentationResourcesRootController { }) } - static func navigationPlayerPlayIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerPlayIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerPlayIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/MinimizedPlay"), color: theme.rootController.navigationBar.accentTextColor) }) } - static func navigationPlayerRateActiveIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerRateActiveIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerRateActiveIcon.rawValue, { theme in return generatePlayerRateIcon(theme.rootController.navigationBar.accentTextColor) }) } - static func navigationPlayerRateInactiveIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerRateInactiveIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerRateInactiveIcon.rawValue, { theme in return generatePlayerRateIcon(theme.rootController.navigationBar.controlColor) }) } - static func navigationPlayerPauseIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerPauseIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerPauseIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/MinimizedPause"), color: theme.rootController.navigationBar.accentTextColor) }) } - static func navigationLiveLocationIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationLiveLocationIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationLiveLocationIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat List/LiveLocationPanelIcon"), color: theme.rootController.navigationBar.accentTextColor) }) } - static func navigationPlayerMaximizedPlayIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerMaximizedPlayIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerMaximizedPlayIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/Play"), color: theme.rootController.navigationBar.primaryTextColor) }) } - static func navigationPlayerMaximizedPauseIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerMaximizedPauseIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerMaximizedPauseIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/Pause"), color: theme.rootController.navigationBar.primaryTextColor) }) } - static func navigationPlayerMaximizedPreviousIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerMaximizedPreviousIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerMaximizedPreviousIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/Previous"), color: theme.rootController.navigationBar.primaryTextColor) }) } - static func navigationPlayerMaximizedNextIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerMaximizedNextIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerMaximizedNextIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/Next"), color: theme.rootController.navigationBar.primaryTextColor) }) } - static func navigationPlayerMaximizedShuffleIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerMaximizedShuffleIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerMaximizedShuffleIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/Shuffle"), color: theme.rootController.navigationBar.primaryTextColor) }) } - static func navigationPlayerMaximizedRepeatIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerMaximizedRepeatIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerMaximizedRepeatIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/Repeat"), color: theme.rootController.navigationBar.primaryTextColor) }) } - static func navigationPlayerHandleIcon(_ theme: PresentationTheme) -> UIImage? { + public static func navigationPlayerHandleIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.navigationPlayerHandleIcon.rawValue, { theme in return generateStretchableFilledCircleImage(diameter: 7.0, color: theme.rootController.navigationBar.controlColor) }) } - static func inAppNotificationBackground(_ theme: PresentationTheme) -> UIImage? { + public static func inAppNotificationBackground(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.inAppNotificationBackground.rawValue, { theme in let inset: CGFloat = 16.0 return generateImage(CGSize(width: 30.0 + inset * 2.0, height: 30.0 + 8.0 * 2.0 + 20.0), rotatedContext: { size, context in @@ -185,7 +185,7 @@ struct PresentationResourcesRootController { }) } - static func inAppNotificationSecretChatIcon(_ theme: PresentationTheme) -> UIImage? { + public static func inAppNotificationSecretChatIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.inAppNotificationSecretChatIcon.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Notification/SecretLock"), color: theme.inAppNotification.primaryTextColor) }) diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesSettings.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesSettings.swift new file mode 100644 index 0000000000..fd7466ff77 --- /dev/null +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesSettings.swift @@ -0,0 +1,28 @@ +import Foundation +import UIKit +import Display + +public struct PresentationResourcesSettings { + public static let editProfile = UIImage(bundleImageName: "Settings/MenuIcons/EditProfile")?.precomposed() + public static let proxy = UIImage(bundleImageName: "Settings/MenuIcons/Proxy")?.precomposed() + public static let savedMessages = UIImage(bundleImageName: "Settings/MenuIcons/SavedMessages")?.precomposed() + public static let recentCalls = UIImage(bundleImageName: "Settings/MenuIcons/RecentCalls")?.precomposed() + public static let stickers = UIImage(bundleImageName: "Settings/MenuIcons/Stickers")?.precomposed() + + public static let notifications = UIImage(bundleImageName: "Settings/MenuIcons/Notifications")?.precomposed() + public static let security = UIImage(bundleImageName: "Settings/MenuIcons/Security")?.precomposed() + public static let dataAndStorage = UIImage(bundleImageName: "Settings/MenuIcons/DataAndStorage")?.precomposed() + public static let appearance = UIImage(bundleImageName: "Settings/MenuIcons/Appearance")?.precomposed() + public static let language = UIImage(bundleImageName: "Settings/MenuIcons/Language")?.precomposed() + + public static let passport = UIImage(bundleImageName: "Settings/MenuIcons/Passport")?.precomposed() + public static let watch = UIImage(bundleImageName: "Settings/MenuIcons/Watch")?.precomposed() + + public static let support = UIImage(bundleImageName: "Settings/MenuIcons/Support")?.precomposed() + public static let faq = UIImage(bundleImageName: "Settings/MenuIcons/Faq")?.precomposed() + + public static let addAccount = UIImage(bundleImageName: "Settings/MenuIcons/AddAccount")?.precomposed() + public static let setPasscode = UIImage(bundleImageName: "Settings/MenuIcons/SetPasscode")?.precomposed() + public static let clearCache = UIImage(bundleImageName: "Settings/MenuIcons/ClearCache")?.precomposed() + public static let changePhoneNumber = UIImage(bundleImageName: "Settings/MenuIcons/ChangePhoneNumber")?.precomposed() +} diff --git a/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift b/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift new file mode 100644 index 0000000000..78c1a8f067 --- /dev/null +++ b/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift @@ -0,0 +1,30 @@ +import Foundation +import TelegramCore + +public extension TelegramWallpaper { + public var isEmpty: Bool { + switch self { + case .image: + return false + case let .file(file): + if file.isPattern, file.settings.color == 0xffffff { + return true + } else { + return false + } + case let .color(color): + return color == 0xffffff + default: + return false + } + } + + public var isBuiltin: Bool { + switch self { + case .builtin: + return true + default: + return false + } + } +} diff --git a/submodules/TelegramPresentationData/TelegramPresentationData_Xcode.xcodeproj/project.pbxproj b/submodules/TelegramPresentationData/TelegramPresentationData_Xcode.xcodeproj/project.pbxproj index 5955d030f5..dc736b81b1 100644 --- a/submodules/TelegramPresentationData/TelegramPresentationData_Xcode.xcodeproj/project.pbxproj +++ b/submodules/TelegramPresentationData/TelegramPresentationData_Xcode.xcodeproj/project.pbxproj @@ -11,6 +11,17 @@ 0957DE1522D88B82001B4D57 /* PresentationThemeEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0957DE1422D88B82001B4D57 /* PresentationThemeEncoder.swift */; }; 0957DE1922D95E0F001B4D57 /* PresentationThemeDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0957DE1822D95E0F001B4D57 /* PresentationThemeDecoder.swift */; }; 097A581B22D528680078B73C /* PresentationThemeCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097A581A22D528680078B73C /* PresentationThemeCodable.swift */; }; + D06017EB22F3578200796784 /* PresentationResourcesSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017E422F3578100796784 /* PresentationResourcesSettings.swift */; }; + D06017EC22F3578200796784 /* PresentationResourcesChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017E522F3578100796784 /* PresentationResourcesChat.swift */; }; + D06017ED22F3578200796784 /* PresentationResourcesCallList.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017E622F3578100796784 /* PresentationResourcesCallList.swift */; }; + D06017EE22F3578200796784 /* PresentationResourcesRootController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017E722F3578100796784 /* PresentationResourcesRootController.swift */; }; + D06017EF22F3578200796784 /* PresentationResourceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017E822F3578200796784 /* PresentationResourceKey.swift */; }; + D06017F022F3578200796784 /* PresentationResourcesChatList.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017E922F3578200796784 /* PresentationResourcesChatList.swift */; }; + D06017F122F3578200796784 /* PresentationResourcesItemList.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017EA22F3578200796784 /* PresentationResourcesItemList.swift */; }; + D06017F322F3583200796784 /* FrameworkSpecific.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017F222F3583200796784 /* FrameworkSpecific.swift */; }; + D06017F522F35A4000796784 /* PresentationThemeEssentialGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017F422F35A4000796784 /* PresentationThemeEssentialGraphics.swift */; }; + D06017F722F35A9200796784 /* ChatMessageBubbleImages.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017F622F35A9200796784 /* ChatMessageBubbleImages.swift */; }; + D06017F922F35ACF00796784 /* WallpaperUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06017F822F35ACF00796784 /* WallpaperUtils.swift */; }; D0AE31AB22B273F20058D3BC /* TelegramPresentationData.h in Headers */ = {isa = PBXBuildFile; fileRef = D0AE31A922B273F20058D3BC /* TelegramPresentationData.h */; settings = {ATTRIBUTES = (Public, ); }; }; D0AE31B422B2746B0058D3BC /* PresentationStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AE31B122B2746B0058D3BC /* PresentationStrings.swift */; }; D0AE31B522B2746B0058D3BC /* PresentationData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AE31B222B2746B0058D3BC /* PresentationData.swift */; }; @@ -39,6 +50,17 @@ 0957DE1422D88B82001B4D57 /* PresentationThemeEncoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentationThemeEncoder.swift; sourceTree = ""; }; 0957DE1822D95E0F001B4D57 /* PresentationThemeDecoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentationThemeDecoder.swift; sourceTree = ""; }; 097A581A22D528680078B73C /* PresentationThemeCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentationThemeCodable.swift; sourceTree = ""; }; + D06017E422F3578100796784 /* PresentationResourcesSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesSettings.swift; sourceTree = ""; }; + D06017E522F3578100796784 /* PresentationResourcesChat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesChat.swift; sourceTree = ""; }; + D06017E622F3578100796784 /* PresentationResourcesCallList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesCallList.swift; sourceTree = ""; }; + D06017E722F3578100796784 /* PresentationResourcesRootController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesRootController.swift; sourceTree = ""; }; + D06017E822F3578200796784 /* PresentationResourceKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourceKey.swift; sourceTree = ""; }; + D06017E922F3578200796784 /* PresentationResourcesChatList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesChatList.swift; sourceTree = ""; }; + D06017EA22F3578200796784 /* PresentationResourcesItemList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesItemList.swift; sourceTree = ""; }; + D06017F222F3583200796784 /* FrameworkSpecific.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FrameworkSpecific.swift; sourceTree = ""; }; + D06017F422F35A4000796784 /* PresentationThemeEssentialGraphics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationThemeEssentialGraphics.swift; sourceTree = ""; }; + D06017F622F35A9200796784 /* ChatMessageBubbleImages.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessageBubbleImages.swift; sourceTree = ""; }; + D06017F822F35ACF00796784 /* WallpaperUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WallpaperUtils.swift; sourceTree = ""; }; D0AE31A622B273F20058D3BC /* TelegramPresentationData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TelegramPresentationData.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0AE31A922B273F20058D3BC /* TelegramPresentationData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TelegramPresentationData.h; sourceTree = ""; }; D0AE31AA22B273F20058D3BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -80,6 +102,20 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + D06017E322F3574F00796784 /* Resources */ = { + isa = PBXGroup; + children = ( + D06017E822F3578200796784 /* PresentationResourceKey.swift */, + D06017E622F3578100796784 /* PresentationResourcesCallList.swift */, + D06017E522F3578100796784 /* PresentationResourcesChat.swift */, + D06017E922F3578200796784 /* PresentationResourcesChatList.swift */, + D06017EA22F3578200796784 /* PresentationResourcesItemList.swift */, + D06017E722F3578100796784 /* PresentationResourcesRootController.swift */, + D06017E422F3578100796784 /* PresentationResourcesSettings.swift */, + ); + path = Resources; + sourceTree = ""; + }; D0AE319C22B273F20058D3BC = { isa = PBXGroup; children = ( @@ -101,6 +137,7 @@ D0AE31A822B273F20058D3BC /* Sources */ = { isa = PBXGroup; children = ( + D06017E322F3574F00796784 /* Resources */, D0AE31D122B27A780058D3BC /* DefaultDayPresentationTheme.swift */, D0AE31CE22B27A780058D3BC /* DefaultDarkPresentationTheme.swift */, D0AE31CF22B27A780058D3BC /* DefaultDarkTintedPresentationTheme.swift */, @@ -120,6 +157,10 @@ 097A581A22D528680078B73C /* PresentationThemeCodable.swift */, 0957DE1422D88B82001B4D57 /* PresentationThemeEncoder.swift */, 0957DE1822D95E0F001B4D57 /* PresentationThemeDecoder.swift */, + D06017F422F35A4000796784 /* PresentationThemeEssentialGraphics.swift */, + D06017F622F35A9200796784 /* ChatMessageBubbleImages.swift */, + D06017F822F35ACF00796784 /* WallpaperUtils.swift */, + D06017F222F3583200796784 /* FrameworkSpecific.swift */, D0AE31A922B273F20058D3BC /* TelegramPresentationData.h */, ); path = Sources; @@ -219,23 +260,34 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D06017F122F3578200796784 /* PresentationResourcesItemList.swift in Sources */, + D06017EC22F3578200796784 /* PresentationResourcesChat.swift in Sources */, D0AE31D522B27A780058D3BC /* DefaultDayPresentationTheme.swift in Sources */, + D06017F322F3583200796784 /* FrameworkSpecific.swift in Sources */, + D06017F022F3578200796784 /* PresentationResourcesChatList.swift in Sources */, D0AE31D422B27A780058D3BC /* DefaultPresentationStrings.swift in Sources */, 097A581B22D528680078B73C /* PresentationThemeCodable.swift in Sources */, 0938677D22E0B9CB000EF19E /* MakePresentationTheme.swift in Sources */, + D06017EB22F3578200796784 /* PresentationResourcesSettings.swift in Sources */, D0AE31CB22B279D00058D3BC /* NumericFormat.swift in Sources */, + D06017F722F35A9200796784 /* ChatMessageBubbleImages.swift in Sources */, 0957DE1922D95E0F001B4D57 /* PresentationThemeDecoder.swift in Sources */, D0AE31B422B2746B0058D3BC /* PresentationStrings.swift in Sources */, D0AE321422B2826A0058D3BC /* ComponentsThemes.swift in Sources */, D0AE31C522B279720058D3BC /* StringPluralization.swift in Sources */, D0AE31CD22B279FD0058D3BC /* PresentationsResourceCache.swift in Sources */, D0AE31C922B2799B0058D3BC /* NumberPluralizationForm.m in Sources */, + D06017EF22F3578200796784 /* PresentationResourceKey.swift in Sources */, D0AE31D922B27AAF0058D3BC /* EDSunriseSet.m in Sources */, D0AE31B522B2746B0058D3BC /* PresentationData.swift in Sources */, + D06017F922F35ACF00796784 /* WallpaperUtils.swift in Sources */, D0AE31D322B27A780058D3BC /* DefaultDarkTintedPresentationTheme.swift in Sources */, D0AE31B622B2746B0058D3BC /* PresentationTheme.swift in Sources */, + D06017ED22F3578200796784 /* PresentationResourcesCallList.swift in Sources */, 0957DE1522D88B82001B4D57 /* PresentationThemeEncoder.swift in Sources */, D0AE31D222B27A780058D3BC /* DefaultDarkPresentationTheme.swift in Sources */, + D06017EE22F3578200796784 /* PresentationResourcesRootController.swift in Sources */, + D06017F522F35A4000796784 /* PresentationThemeEssentialGraphics.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/submodules/TelegramUI/TelegramUI/PresentationResourcesSettings.swift b/submodules/TelegramUI/TelegramUI/PresentationResourcesSettings.swift deleted file mode 100644 index b98eb9d519..0000000000 --- a/submodules/TelegramUI/TelegramUI/PresentationResourcesSettings.swift +++ /dev/null @@ -1,28 +0,0 @@ -import Foundation -import UIKit -import Display - -struct PresentationResourcesSettings { - static let editProfile = UIImage(bundleImageName: "Settings/MenuIcons/EditProfile")?.precomposed() - static let proxy = UIImage(bundleImageName: "Settings/MenuIcons/Proxy")?.precomposed() - static let savedMessages = UIImage(bundleImageName: "Settings/MenuIcons/SavedMessages")?.precomposed() - static let recentCalls = UIImage(bundleImageName: "Settings/MenuIcons/RecentCalls")?.precomposed() - static let stickers = UIImage(bundleImageName: "Settings/MenuIcons/Stickers")?.precomposed() - - static let notifications = UIImage(bundleImageName: "Settings/MenuIcons/Notifications")?.precomposed() - static let security = UIImage(bundleImageName: "Settings/MenuIcons/Security")?.precomposed() - static let dataAndStorage = UIImage(bundleImageName: "Settings/MenuIcons/DataAndStorage")?.precomposed() - static let appearance = UIImage(bundleImageName: "Settings/MenuIcons/Appearance")?.precomposed() - static let language = UIImage(bundleImageName: "Settings/MenuIcons/Language")?.precomposed() - - static let passport = UIImage(bundleImageName: "Settings/MenuIcons/Passport")?.precomposed() - static let watch = UIImage(bundleImageName: "Settings/MenuIcons/Watch")?.precomposed() - - static let support = UIImage(bundleImageName: "Settings/MenuIcons/Support")?.precomposed() - static let faq = UIImage(bundleImageName: "Settings/MenuIcons/Faq")?.precomposed() - - static let addAccount = UIImage(bundleImageName: "Settings/MenuIcons/AddAccount")?.precomposed() - static let setPasscode = UIImage(bundleImageName: "Settings/MenuIcons/SetPasscode")?.precomposed() - static let clearCache = UIImage(bundleImageName: "Settings/MenuIcons/ClearCache")?.precomposed() - static let changePhoneNumber = UIImage(bundleImageName: "Settings/MenuIcons/ChangePhoneNumber")?.precomposed() -} From 24e76f5eacb3feca8259c5b5a628c7860573640f Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:23:55 +0300 Subject: [PATCH 36/41] Move ChatMessageBubbleImages to TelegramPresentationData --- .../TelegramUI/ChatMessageBubbleImages.swift | 188 ------------------ 1 file changed, 188 deletions(-) delete mode 100644 submodules/TelegramUI/TelegramUI/ChatMessageBubbleImages.swift diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleImages.swift b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleImages.swift deleted file mode 100644 index dc128a9fba..0000000000 --- a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleImages.swift +++ /dev/null @@ -1,188 +0,0 @@ -import Foundation -import UIKit -import Display - -enum MessageBubbleImageNeighbors { - case none - case top(side: Bool) - case bottom - case both - case side -} - -func messageSingleBubbleLikeImage(fillColor: UIColor, strokeColor: UIColor) -> UIImage { - let diameter: CGFloat = 36.0 - return generateImage(CGSize(width: 36.0, height: diameter), contextGenerator: { size, context in - context.clear(CGRect(origin: CGPoint(), size: size)) - - let lineWidth: CGFloat = 0.5 - - context.setFillColor(strokeColor.cgColor) - context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) - context.setFillColor(fillColor.cgColor) - context.fillEllipse(in: CGRect(origin: CGPoint(x: lineWidth, y: lineWidth), size: CGSize(width: size.width - lineWidth * 2.0, height: size.height - lineWidth * 2.0))) - })!.stretchableImage(withLeftCapWidth: Int(diameter / 2.0), topCapHeight: Int(diameter / 2.0)) -} - -func messageBubbleImage(incoming: Bool, fillColor: UIColor, strokeColor: UIColor, neighbors: MessageBubbleImageNeighbors) -> UIImage { - let diameter: CGFloat = 36.0 - let corner: CGFloat = 7.0 - return generateImage(CGSize(width: 42.0, height: diameter), contextGenerator: { size, context in - context.clear(CGRect(origin: CGPoint(), size: size)) - - let additionalOffset: CGFloat - switch neighbors { - case .none, .bottom: - additionalOffset = 0.0 - case .both, .side, .top: - additionalOffset = 6.0 - } - - context.translateBy(x: size.width / 2.0, y: size.height / 2.0) - context.scaleBy(x: incoming ? 1.0 : -1.0, y: -1.0) - context.translateBy(x: -size.width / 2.0 + 0.5 + additionalOffset, y: -size.height / 2.0 + 0.5) - - let lineWidth: CGFloat = 1.0 - - context.setFillColor(fillColor.cgColor) - context.setLineWidth(lineWidth) - context.setStrokeColor(strokeColor.cgColor) - - switch neighbors { - case .none: - let _ = try? drawSvgPath(context, path: "M6,17.5 C6,7.83289181 13.8350169,0 23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41102995e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") - context.strokePath() - let _ = try? drawSvgPath(context, path: "M6,17.5 C6,7.83289181 13.8350169,0 23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41102995e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") - context.fillPath() - case .side: - context.strokeEllipse(in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 35.0, height: 35.0))) - context.strokePath() - context.fillEllipse(in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: 35.0, height: 35.0))) - case let .top(side): - if side { - let _ = try? drawSvgPath(context, path: "M17.5,0 L17.5,0 C27.1649831,-1.7754286e-15 35,7.83501688 35,17.5 L35,29 C35,32.3137085 32.3137085,35 29,35 L6,35 C2.6862915,35 4.05812251e-16,32.3137085 0,29 L0,17.5 C-1.18361906e-15,7.83501688 7.83501688,1.7754286e-15 17.5,0 ") - context.strokePath() - let _ = try? drawSvgPath(context, path: "M17.5,0 L17.5,0 C27.1649831,-1.7754286e-15 35,7.83501688 35,17.5 L35,29 C35,32.3137085 32.3137085,35 29,35 L6,35 C2.6862915,35 4.05812251e-16,32.3137085 0,29 L0,17.5 C-1.18361906e-15,7.83501688 7.83501688,1.7754286e-15 17.5,0 ") - context.fillPath() - } else { - let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L17.5,0 C7.83501688,0 0,7.83289181 0,17.5 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") - context.strokePath() - let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L17.5,0 C7.83501688,0 0,7.83289181 0,17.5 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") - context.fillPath() - } - case .bottom: - let _ = try? drawSvgPath(context, path: "M6,17.5 L6,5.99681848 C6,2.6882755 8.68486709,0 11.9968185,0 L23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41103066e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") - context.strokePath() - let _ = try? drawSvgPath(context, path: "M6,17.5 L6,5.99681848 C6,2.6882755 8.68486709,0 11.9968185,0 L23.5,0 C33.1671082,0 41,7.83501688 41,17.5 C41,27.1671082 33.1649831,35 23.5,35 C19.2941198,35 15.4354328,33.5169337 12.4179496,31.0453367 C9.05531719,34.9894816 -2.41103066e-08,35 0,35 C5.972003,31.5499861 6,26.8616169 6,26.8616169 L6,17.5 L6,17.5 ") - context.fillPath() - case .both: - let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L5.99681848,0 C2.68486709,0 0,2.6882755 0,5.99681848 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") - context.strokePath() - let _ = try? drawSvgPath(context, path: "M35,17.5 C35,7.83501688 27.1671082,0 17.5,0 L5.99681848,0 C2.68486709,0 0,2.6882755 0,5.99681848 L0,29.0031815 C0,32.3151329 2.6882755,35 5.99681848,35 L17.5,35 C27.1649831,35 35,27.1671082 35,17.5 L35,17.5 L35,17.5 ") - context.fillPath() - } - })!.stretchableImage(withLeftCapWidth: incoming ? Int(corner + diameter / 2.0) : Int(diameter / 2.0), topCapHeight: Int(diameter / 2.0)) -} - -enum MessageBubbleActionButtonPosition { - case middle - case bottomLeft - case bottomRight - case bottomSingle -} - -func messageBubbleActionButtonImage(color: UIColor, strokeColor: UIColor, position: MessageBubbleActionButtonPosition) -> UIImage { - let largeRadius: CGFloat = 17.0 - let smallRadius: CGFloat = 6.0 - let size: CGSize - if case .middle = position { - size = CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius) - } else { - size = CGSize(width: 35.0, height: 35.0) - } - return generateImage(size, contextGenerator: { size, context in - context.clear(CGRect(origin: CGPoint(), size: size)) - context.translateBy(x: size.width / 2.0, y: size.height / 2.0) - if case .bottomRight = position { - context.scaleBy(x: -1.0, y: -1.0) - } else { - context.scaleBy(x: 1.0, y: -1.0) - } - context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0) - context.setBlendMode(.copy) - var effectiveStrokeColor: UIColor? - var strokeAlpha: CGFloat = 0.0 - strokeColor.getRed(nil, green: nil, blue: nil, alpha: &strokeAlpha) - if !strokeAlpha.isZero { - effectiveStrokeColor = strokeColor - } - context.setFillColor(color.cgColor) - let lineWidth: CGFloat = 1.0 - let halfLineWidth = lineWidth / 2.0 - if let effectiveStrokeColor = effectiveStrokeColor { - context.setStrokeColor(effectiveStrokeColor.cgColor) - context.setLineWidth(lineWidth) - } - switch position { - case .middle: - context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) - if effectiveStrokeColor != nil { - context.setBlendMode(.normal) - context.strokeEllipse(in: CGRect(origin: CGPoint(x: halfLineWidth, y: halfLineWidth), size: CGSize(width: size.width - lineWidth, height: size.height - lineWidth))) - context.setBlendMode(.copy) - } - case .bottomLeft, .bottomRight: - context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) - context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) - context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - smallRadius - smallRadius, y: 0.0), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) - context.fill(CGRect(origin: CGPoint(x: smallRadius, y: 0.0), size: CGSize(width: size.width - smallRadius - smallRadius, height: smallRadius + smallRadius))) - context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) - context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) - context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - smallRadius - smallRadius, y: 0.0), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) - context.fill(CGRect(origin: CGPoint(x: smallRadius, y: 0.0), size: CGSize(width: size.width - smallRadius - smallRadius, height: smallRadius + smallRadius))) - context.fill(CGRect(origin: CGPoint(x: 0.0, y: smallRadius), size: CGSize(width: size.width, height: size.height - largeRadius - smallRadius))) - context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - smallRadius - smallRadius, y: size.height - smallRadius - smallRadius), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) - context.fill(CGRect(origin: CGPoint(x: largeRadius, y: size.height - largeRadius - largeRadius), size: CGSize(width: size.width - smallRadius - largeRadius, height: largeRadius + largeRadius))) - context.fill(CGRect(origin: CGPoint(x: size.width - smallRadius, y: size.height - largeRadius), size: CGSize(width: smallRadius, height: largeRadius - smallRadius))) - if effectiveStrokeColor != nil { - context.setBlendMode(.normal) - context.beginPath() - context.move(to: CGPoint(x: halfLineWidth, y: smallRadius + halfLineWidth)) - context.addArc(tangent1End: CGPoint(x: halfLineWidth, y: halfLineWidth), tangent2End: CGPoint(x: halfLineWidth + smallRadius, y: halfLineWidth), radius: smallRadius) - context.addLine(to: CGPoint(x: size.width - smallRadius, y: halfLineWidth)) - context.addArc(tangent1End: CGPoint(x: size.width - halfLineWidth, y: halfLineWidth), tangent2End: CGPoint(x: size.width - halfLineWidth, y: halfLineWidth + smallRadius), radius: smallRadius) - context.addLine(to: CGPoint(x: size.width - halfLineWidth, y: size.height - halfLineWidth - smallRadius)) - context.addArc(tangent1End: CGPoint(x: size.width - halfLineWidth, y: size.height - halfLineWidth), tangent2End: CGPoint(x: size.width - halfLineWidth - smallRadius, y: size.height - halfLineWidth), radius: smallRadius) - context.addLine(to: CGPoint(x: halfLineWidth + largeRadius, y: size.height - halfLineWidth)) - context.addArc(tangent1End: CGPoint(x: halfLineWidth, y: size.height - halfLineWidth), tangent2End: CGPoint(x: halfLineWidth, y: size.height - halfLineWidth - largeRadius), radius: largeRadius) - - context.closePath() - context.strokePath() - context.setBlendMode(.copy) - } - case .bottomSingle: - context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) - context.fillEllipse(in: CGRect(origin: CGPoint(), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) - context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - smallRadius - smallRadius, y: 0.0), size: CGSize(width: smallRadius + smallRadius, height: smallRadius + smallRadius))) - context.fill(CGRect(origin: CGPoint(x: smallRadius, y: 0.0), size: CGSize(width: size.width - smallRadius - smallRadius, height: smallRadius + smallRadius))) - context.fill(CGRect(origin: CGPoint(x: 0.0, y: smallRadius), size: CGSize(width: size.width, height: size.height - largeRadius - smallRadius))) - - if effectiveStrokeColor != nil { - context.setBlendMode(.normal) - context.beginPath() - context.move(to: CGPoint(x: halfLineWidth, y: smallRadius + halfLineWidth)) - context.addArc(tangent1End: CGPoint(x: halfLineWidth, y: halfLineWidth), tangent2End: CGPoint(x: halfLineWidth + smallRadius, y: halfLineWidth), radius: smallRadius) - context.addLine(to: CGPoint(x: size.width - smallRadius, y: halfLineWidth)) - context.addArc(tangent1End: CGPoint(x: size.width - halfLineWidth, y: halfLineWidth), tangent2End: CGPoint(x: size.width - halfLineWidth, y: halfLineWidth + smallRadius), radius: smallRadius) - context.addLine(to: CGPoint(x: size.width - halfLineWidth, y: size.height - halfLineWidth - largeRadius)) - context.addArc(tangent1End: CGPoint(x: size.width - halfLineWidth, y: size.height - halfLineWidth), tangent2End: CGPoint(x: size.width - halfLineWidth - largeRadius, y: size.height - halfLineWidth), radius: largeRadius) - context.addLine(to: CGPoint(x: halfLineWidth + largeRadius, y: size.height - halfLineWidth)) - context.addArc(tangent1End: CGPoint(x: halfLineWidth, y: size.height - halfLineWidth), tangent2End: CGPoint(x: halfLineWidth, y: size.height - halfLineWidth - largeRadius), radius: largeRadius) - - context.closePath() - context.strokePath() - context.setBlendMode(.copy) - } - } - })!.stretchableImage(withLeftCapWidth: Int(size.width / 2.0), topCapHeight: Int(size.height / 2.0)) -} From 7ef834df312de34fb005bac2ea8f5b91576b99d2 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:25:27 +0300 Subject: [PATCH 37/41] Refactor TextFormat --- submodules/TextFormat/Info.plist | 22 + .../Sources}/ChatTextInputAttributes.swift | 190 ++---- .../Sources}/GenerateTextEntities.swift | 102 ++-- .../Sources}/Markdown.swift | 44 +- .../Sources}/StringWithAppliedEntities.swift | 82 +-- .../Sources/TelegramAttributes.swift | 42 ++ submodules/TextFormat/Sources/TextFormat.h | 19 + .../project.pbxproj | 575 ++++++++++++++++++ 8 files changed, 832 insertions(+), 244 deletions(-) create mode 100644 submodules/TextFormat/Info.plist rename submodules/{TelegramUI/TelegramUI => TextFormat/Sources}/ChatTextInputAttributes.swift (76%) rename submodules/{TelegramUI/TelegramUI => TextFormat/Sources}/GenerateTextEntities.swift (84%) rename submodules/{TelegramUI/TelegramUI => TextFormat/Sources}/Markdown.swift (79%) rename submodules/{TelegramUI/TelegramUI => TextFormat/Sources}/StringWithAppliedEntities.swift (61%) create mode 100644 submodules/TextFormat/Sources/TelegramAttributes.swift create mode 100644 submodules/TextFormat/Sources/TextFormat.h create mode 100644 submodules/TextFormat/TextFormat_Xcode.xcodeproj/project.pbxproj diff --git a/submodules/TextFormat/Info.plist b/submodules/TextFormat/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/TextFormat/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/TelegramUI/TelegramUI/ChatTextInputAttributes.swift b/submodules/TextFormat/Sources/ChatTextInputAttributes.swift similarity index 76% rename from submodules/TelegramUI/TelegramUI/ChatTextInputAttributes.swift rename to submodules/TextFormat/Sources/ChatTextInputAttributes.swift index 939a7918d6..db52c8c553 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTextInputAttributes.swift +++ b/submodules/TextFormat/Sources/ChatTextInputAttributes.swift @@ -7,19 +7,19 @@ import TelegramPresentationData private let alphanumericCharacters = CharacterSet.alphanumerics -struct ChatTextInputAttributes { - static let bold = NSAttributedStringKey(rawValue: "Attribute__Bold") - static let italic = NSAttributedStringKey(rawValue: "Attribute__Italic") - static let monospace = NSAttributedStringKey(rawValue: "Attribute__Monospace") - static let strikethrough = NSAttributedStringKey(rawValue: "Attribute__Strikethrough") - static let underline = NSAttributedStringKey(rawValue: "Attribute__Underline") - static let textMention = NSAttributedStringKey(rawValue: "Attribute__TextMention") - static let textUrl = NSAttributedStringKey(rawValue: "Attribute__TextUrl") +public struct ChatTextInputAttributes { + public static let bold = NSAttributedString.Key(rawValue: "Attribute__Bold") + public static let italic = NSAttributedString.Key(rawValue: "Attribute__Italic") + public static let monospace = NSAttributedString.Key(rawValue: "Attribute__Monospace") + public static let strikethrough = NSAttributedString.Key(rawValue: "Attribute__Strikethrough") + public static let underline = NSAttributedString.Key(rawValue: "Attribute__Underline") + public static let textMention = NSAttributedString.Key(rawValue: "Attribute__TextMention") + public static let textUrl = NSAttributedString.Key(rawValue: "Attribute__TextUrl") - static let allAttributes = [ChatTextInputAttributes.bold, ChatTextInputAttributes.italic, ChatTextInputAttributes.monospace, ChatTextInputAttributes.strikethrough, ChatTextInputAttributes.underline, ChatTextInputAttributes.textMention, ChatTextInputAttributes.textUrl] + public static let allAttributes = [ChatTextInputAttributes.bold, ChatTextInputAttributes.italic, ChatTextInputAttributes.monospace, ChatTextInputAttributes.strikethrough, ChatTextInputAttributes.underline, ChatTextInputAttributes.textMention, ChatTextInputAttributes.textUrl] } -func stateAttributedStringForText(_ text: NSAttributedString) -> NSAttributedString { +public func stateAttributedStringForText(_ text: NSAttributedString) -> NSAttributedString { let result = NSMutableAttributedString(string: text.string) let fullRange = NSRange(location: 0, length: result.length) @@ -33,21 +33,25 @@ func stateAttributedStringForText(_ text: NSAttributedString) -> NSAttributedStr return result } -struct ChatTextFontAttributes: OptionSet { - var rawValue: Int32 = 0 +public struct ChatTextFontAttributes: OptionSet { + public var rawValue: Int32 = 0 - static let bold = ChatTextFontAttributes(rawValue: 1 << 0) - static let italic = ChatTextFontAttributes(rawValue: 1 << 1) - static let monospace = ChatTextFontAttributes(rawValue: 1 << 2) - static let blockQuote = ChatTextFontAttributes(rawValue: 1 << 3) + public init(rawValue: Int32) { + self.rawValue = rawValue + } + + public static let bold = ChatTextFontAttributes(rawValue: 1 << 0) + public static let italic = ChatTextFontAttributes(rawValue: 1 << 1) + public static let monospace = ChatTextFontAttributes(rawValue: 1 << 2) + public static let blockQuote = ChatTextFontAttributes(rawValue: 1 << 3) } -func textAttributedStringForStateText(_ stateText: NSAttributedString, fontSize: CGFloat, textColor: UIColor, accentTextColor: UIColor) -> NSAttributedString { +public func textAttributedStringForStateText(_ stateText: NSAttributedString, fontSize: CGFloat, textColor: UIColor, accentTextColor: UIColor) -> NSAttributedString { let result = NSMutableAttributedString(string: stateText.string) let fullRange = NSRange(location: 0, length: result.length) - result.addAttribute(NSAttributedStringKey.font, value: Font.regular(fontSize), range: fullRange) - result.addAttribute(NSAttributedStringKey.foregroundColor, value: textColor, range: fullRange) + result.addAttribute(NSAttributedString.Key.font, value: Font.regular(fontSize), range: fullRange) + result.addAttribute(NSAttributedString.Key.foregroundColor, value: textColor, range: fullRange) stateText.enumerateAttributes(in: fullRange, options: [], using: { attributes, range, _ in var fontAttributes: ChatTextFontAttributes = [] @@ -55,9 +59,9 @@ func textAttributedStringForStateText(_ stateText: NSAttributedString, fontSize: for (key, value) in attributes { if key == ChatTextInputAttributes.textMention || key == ChatTextInputAttributes.textUrl { result.addAttribute(key, value: value, range: range) - result.addAttribute(NSAttributedStringKey.foregroundColor, value: accentTextColor, range: range) + result.addAttribute(NSAttributedString.Key.foregroundColor, value: accentTextColor, range: range) if accentTextColor.isEqual(textColor) { - result.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + result.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } } else if key == ChatTextInputAttributes.bold { result.addAttribute(key, value: value, range: range) @@ -70,10 +74,10 @@ func textAttributedStringForStateText(_ stateText: NSAttributedString, fontSize: fontAttributes.insert(.monospace) } else if key == ChatTextInputAttributes.strikethrough { result.addAttribute(key, value: value, range: range) - result.addAttribute(NSAttributedStringKey.strikethroughStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + result.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } else if key == ChatTextInputAttributes.underline { result.addAttribute(key, value: value, range: range) - result.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + result.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } } @@ -96,23 +100,23 @@ func textAttributedStringForStateText(_ stateText: NSAttributedString, fontSize: } if let font = font { - result.addAttribute(NSAttributedStringKey.font, value: font, range: range) + result.addAttribute(NSAttributedString.Key.font, value: font, range: range) } } }) return result } -final class ChatTextInputTextMentionAttribute: NSObject { - let peerId: PeerId +public final class ChatTextInputTextMentionAttribute: NSObject { + public let peerId: PeerId - init(peerId: PeerId) { + public init(peerId: PeerId) { self.peerId = peerId super.init() } - override func isEqual(_ object: Any?) -> Bool { + override public func isEqual(_ object: Any?) -> Bool { if let other = object as? ChatTextInputTextMentionAttribute { return self.peerId == other.peerId } else { @@ -133,16 +137,16 @@ private func textMentionRangesEqual(_ lhs: [(NSRange, ChatTextInputTextMentionAt return true } -final class ChatTextInputTextUrlAttribute: NSObject { - let url: String +public final class ChatTextInputTextUrlAttribute: NSObject { + public let url: String - init(url: String) { + public init(url: String) { self.url = url super.init() } - override func isEqual(_ object: Any?) -> Bool { + override public func isEqual(_ object: Any?) -> Bool { if let other = object as? ChatTextInputTextUrlAttribute { return self.url == other.url } else { @@ -395,7 +399,7 @@ private func refreshTextUrls(text: NSString, initialAttributedText: NSAttributed } } -func refreshChatTextInputAttributes(_ textNode: ASEditableTextNode, theme: PresentationTheme, baseFontSize: CGFloat) { +public func refreshChatTextInputAttributes(_ textNode: ASEditableTextNode, theme: PresentationTheme, baseFontSize: CGFloat) { guard let initialAttributedText = textNode.attributedText, initialAttributedText.length != 0 else { return } @@ -415,15 +419,15 @@ func refreshChatTextInputAttributes(_ textNode: ASEditableTextNode, theme: Prese resultAttributedText = textAttributedStringForStateText(attributedText, fontSize: baseFontSize, textColor: theme.chat.inputPanel.primaryTextColor, accentTextColor: theme.chat.inputPanel.panelControlAccentColor) if !resultAttributedText.isEqual(to: initialAttributedText) { - textNode.textView.textStorage.removeAttribute(NSAttributedStringKey.font, range: fullRange) - textNode.textView.textStorage.removeAttribute(NSAttributedStringKey.foregroundColor, range: fullRange) - textNode.textView.textStorage.removeAttribute(NSAttributedStringKey.underlineStyle, range: fullRange) - textNode.textView.textStorage.removeAttribute(NSAttributedStringKey.strikethroughStyle, range: fullRange) + textNode.textView.textStorage.removeAttribute(NSAttributedString.Key.font, range: fullRange) + textNode.textView.textStorage.removeAttribute(NSAttributedString.Key.foregroundColor, range: fullRange) + textNode.textView.textStorage.removeAttribute(NSAttributedString.Key.underlineStyle, range: fullRange) + textNode.textView.textStorage.removeAttribute(NSAttributedString.Key.strikethroughStyle, range: fullRange) textNode.textView.textStorage.removeAttribute(ChatTextInputAttributes.textMention, range: fullRange) textNode.textView.textStorage.removeAttribute(ChatTextInputAttributes.textUrl, range: fullRange) - textNode.textView.textStorage.addAttribute(NSAttributedStringKey.font, value: Font.regular(baseFontSize), range: fullRange) - textNode.textView.textStorage.addAttribute(NSAttributedStringKey.foregroundColor, value: theme.chat.inputPanel.primaryTextColor, range: fullRange) + textNode.textView.textStorage.addAttribute(NSAttributedString.Key.font, value: Font.regular(baseFontSize), range: fullRange) + textNode.textView.textStorage.addAttribute(NSAttributedString.Key.foregroundColor, value: theme.chat.inputPanel.primaryTextColor, range: fullRange) attributedText.enumerateAttributes(in: fullRange, options: [], using: { attributes, range, _ in var fontAttributes: ChatTextFontAttributes = [] @@ -431,10 +435,10 @@ func refreshChatTextInputAttributes(_ textNode: ASEditableTextNode, theme: Prese for (key, value) in attributes { if key == ChatTextInputAttributes.textMention || key == ChatTextInputAttributes.textUrl { textNode.textView.textStorage.addAttribute(key, value: value, range: range) - textNode.textView.textStorage.addAttribute(NSAttributedStringKey.foregroundColor, value: theme.chat.inputPanel.panelControlAccentColor, range: range) + textNode.textView.textStorage.addAttribute(NSAttributedString.Key.foregroundColor, value: theme.chat.inputPanel.panelControlAccentColor, range: range) if theme.chat.inputPanel.panelControlAccentColor.isEqual(theme.chat.inputPanel.primaryTextColor) { - textNode.textView.textStorage.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + textNode.textView.textStorage.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } } else if key == ChatTextInputAttributes.bold { textNode.textView.textStorage.addAttribute(key, value: value, range: range) @@ -447,10 +451,10 @@ func refreshChatTextInputAttributes(_ textNode: ASEditableTextNode, theme: Prese fontAttributes.insert(.monospace) } else if key == ChatTextInputAttributes.strikethrough { textNode.textView.textStorage.addAttribute(key, value: value, range: range) - textNode.textView.textStorage.addAttribute(NSAttributedStringKey.strikethroughStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + textNode.textView.textStorage.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } else if key == ChatTextInputAttributes.underline { textNode.textView.textStorage.addAttribute(key, value: value, range: range) - textNode.textView.textStorage.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + textNode.textView.textStorage.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } } @@ -473,109 +477,35 @@ func refreshChatTextInputAttributes(_ textNode: ASEditableTextNode, theme: Prese } if let font = font { - textNode.textView.textStorage.addAttribute(NSAttributedStringKey.font, value: font, range: range) + textNode.textView.textStorage.addAttribute(NSAttributedString.Key.font, value: font, range: range) } } }) } } -func refreshChatTextInputTypingAttributes(_ textNode: ASEditableTextNode, theme: PresentationTheme, baseFontSize: CGFloat) { - var filteredAttributes: [String: Any] = [ - NSAttributedStringKey.font.rawValue: Font.regular(baseFontSize), - NSAttributedStringKey.foregroundColor.rawValue: theme.chat.inputPanel.primaryTextColor +public func refreshChatTextInputTypingAttributes(_ textNode: ASEditableTextNode, theme: PresentationTheme, baseFontSize: CGFloat) { + var filteredAttributes: [NSAttributedString.Key: Any] = [ + NSAttributedString.Key.font: Font.regular(baseFontSize), + NSAttributedString.Key.foregroundColor: theme.chat.inputPanel.primaryTextColor ] if let attributedText = textNode.attributedText, attributedText.length != 0 { let attributes = attributedText.attributes(at: max(0, min(textNode.selectedRange.location - 1, attributedText.length - 1)), effectiveRange: nil) for (key, value) in attributes { if key == ChatTextInputAttributes.bold { - filteredAttributes[key.rawValue] = value + filteredAttributes[key] = value } else if key == ChatTextInputAttributes.italic { - filteredAttributes[key.rawValue] = value + filteredAttributes[key] = value } else if key == ChatTextInputAttributes.monospace { - filteredAttributes[key.rawValue] = value - } else if key == NSAttributedStringKey.font { - filteredAttributes[key.rawValue] = value + filteredAttributes[key] = value + } else if key == NSAttributedString.Key.font { + filteredAttributes[key] = value } } } textNode.textView.typingAttributes = filteredAttributes } -func chatTextInputAddFormattingAttribute(_ state: ChatTextInputState, attribute: NSAttributedStringKey) -> ChatTextInputState { - if !state.selectionRange.isEmpty { - let nsRange = NSRange(location: state.selectionRange.lowerBound, length: state.selectionRange.count) - var addAttribute = true - var attributesToRemove: [NSAttributedStringKey] = [] - state.inputText.enumerateAttributes(in: nsRange, options: .longestEffectiveRangeNotRequired) { attributes, range, stop in - for (key, _) in attributes { - if key == attribute && range == nsRange { - addAttribute = false - attributesToRemove.append(key) - } - } - } - - let result = NSMutableAttributedString(attributedString: state.inputText) - for attribute in attributesToRemove { - result.removeAttribute(attribute, range: nsRange) - } - if addAttribute { - result.addAttribute(attribute, value: true as Bool, range: nsRange) - } - return ChatTextInputState(inputText: result, selectionRange: state.selectionRange) - } else { - return state - } -} - -func chatTextInputClearFormattingAttributes(_ state: ChatTextInputState) -> ChatTextInputState { - if !state.selectionRange.isEmpty { - let nsRange = NSRange(location: state.selectionRange.lowerBound, length: state.selectionRange.count) - var attributesToRemove: [NSAttributedStringKey] = [] - state.inputText.enumerateAttributes(in: nsRange, options: .longestEffectiveRangeNotRequired) { attributes, range, stop in - for (key, _) in attributes { - attributesToRemove.append(key) - } - } - - let result = NSMutableAttributedString(attributedString: state.inputText) - for attribute in attributesToRemove { - result.removeAttribute(attribute, range: nsRange) - } - return ChatTextInputState(inputText: result, selectionRange: state.selectionRange) - } else { - return state - } -} - -func chatTextInputAddLinkAttribute(_ state: ChatTextInputState, url: String) -> ChatTextInputState { - if !state.selectionRange.isEmpty { - let nsRange = NSRange(location: state.selectionRange.lowerBound, length: state.selectionRange.count) - var linkRange = nsRange - var attributesToRemove: [(NSAttributedStringKey, NSRange)] = [] - state.inputText.enumerateAttributes(in: nsRange, options: .longestEffectiveRangeNotRequired) { attributes, range, stop in - for (key, _) in attributes { - if key == ChatTextInputAttributes.textUrl { - attributesToRemove.append((key, range)) - linkRange = linkRange.union(range) - } else { - attributesToRemove.append((key, nsRange)) - } - } - } - - let result = NSMutableAttributedString(attributedString: state.inputText) - for (attribute, range) in attributesToRemove { - result.removeAttribute(attribute, range: range) - } - result.addAttribute(ChatTextInputAttributes.textUrl, value: ChatTextInputTextUrlAttribute(url: url), range: nsRange) - return ChatTextInputState(inputText: result, selectionRange: state.selectionRange) - } else { - return state - } -} - private func trimRangesForChatInputText(_ text: NSAttributedString) -> (Int, Int) { var lower = 0 var upper = 0 @@ -611,7 +541,7 @@ private func trimRangesForChatInputText(_ text: NSAttributedString) -> (Int, Int return (lower, upper) } -func trimChatInputText(_ text: NSAttributedString) -> NSAttributedString { +public func trimChatInputText(_ text: NSAttributedString) -> NSAttributedString { let (lower, upper) = trimRangesForChatInputText(text) if lower == 0 && upper == 0 { return text @@ -627,7 +557,7 @@ func trimChatInputText(_ text: NSAttributedString) -> NSAttributedString { return result } -func breakChatInputText(_ text: NSAttributedString) -> [NSAttributedString] { +public func breakChatInputText(_ text: NSAttributedString) -> [NSAttributedString] { if text.length <= 4000 { return [text] } else { @@ -656,7 +586,7 @@ func breakChatInputText(_ text: NSAttributedString) -> [NSAttributedString] { private let markdownRegexFormat = "(^|\\s|\\n)(````?)([\\s\\S]+?)(````?)([\\s\\n\\.,:?!;]|$)|(^|\\s)(`|\\*\\*|__|~~)([^\\n]+?)\\7([\\s\\.,:?!;]|$)|@(\\d+)\\s*\\((.+?)\\)" private let markdownRegex = try? NSRegularExpression(pattern: markdownRegexFormat, options: [.caseInsensitive, .anchorsMatchLines]) -func convertMarkdownToAttributes(_ text: NSAttributedString) -> NSAttributedString { +public func convertMarkdownToAttributes(_ text: NSAttributedString) -> NSAttributedString { var string = text.string as NSString var offsetRanges:[(NSRange, Int)] = [] diff --git a/submodules/TelegramUI/TelegramUI/GenerateTextEntities.swift b/submodules/TextFormat/Sources/GenerateTextEntities.swift similarity index 84% rename from submodules/TelegramUI/TelegramUI/GenerateTextEntities.swift rename to submodules/TextFormat/Sources/GenerateTextEntities.swift index b43d368a06..0fb56fbb4b 100644 --- a/submodules/TelegramUI/TelegramUI/GenerateTextEntities.swift +++ b/submodules/TextFormat/Sources/GenerateTextEntities.swift @@ -40,7 +40,7 @@ private let validTimecodeSet: CharacterSet = { return set }() -struct ApplicationSpecificEntityType { +public struct ApplicationSpecificEntityType { public static let Timecode: Int32 = 1 } @@ -53,16 +53,16 @@ private enum CurrentEntityType { var type: EnabledEntityTypes { switch self { - case .command: - return .command - case .mention: - return .mention - case .hashtag: - return .hashtag - case .phoneNumber: - return .phoneNumber - case .timecode: - return .timecode + case .command: + return .command + case .mention: + return .mention + case .hashtag: + return .hashtag + case .phoneNumber: + return .phoneNumber + case .timecode: + return .timecode } } } @@ -99,17 +99,17 @@ private func commitEntity(_ utf16: String.UTF16View, _ type: CurrentEntityType, } if !overlaps { let entityType: MessageTextEntityType - switch type { - case .command: - entityType = .BotCommand - case .mention: - entityType = .Mention - case .hashtag: - entityType = .Hashtag - case .phoneNumber: - entityType = .PhoneNumber - case .timecode: - entityType = .Custom(type: ApplicationSpecificEntityType.Timecode) + switch type { + case .command: + entityType = .BotCommand + case .mention: + entityType = .Mention + case .hashtag: + entityType = .Hashtag + case .phoneNumber: + entityType = .PhoneNumber + case .timecode: + entityType = .Custom(type: ApplicationSpecificEntityType.Timecode) } if case .timecode = type { @@ -122,7 +122,7 @@ private func commitEntity(_ utf16: String.UTF16View, _ type: CurrentEntityType, } } -func generateChatInputTextEntities(_ text: NSAttributedString) -> [MessageTextEntity] { +public func generateChatInputTextEntities(_ text: NSAttributedString) -> [MessageTextEntity] { var entities: [MessageTextEntity] = [] text.enumerateAttributes(in: NSRange(location: 0, length: text.length), options: [], using: { attributes, range, _ in for (key, value) in attributes { @@ -220,30 +220,30 @@ public func generateTextEntities(_ text: String, enabledTypes: EnabledEntityType } currentEntity = (.hashtag, index ..< index) } - + if notFound { if let (type, range) = currentEntity { switch type { - case .command, .mention: - if validIdentifierSet.contains(scalar) { - currentEntity = (type, range.lowerBound ..< utf16.index(after: index)) - } else if delimiterSet.contains(scalar) { - if let (type, range) = currentEntity { - commitEntity(utf16, type, range, enabledTypes, &entities) - } - currentEntity = nil + case .command, .mention: + if validIdentifierSet.contains(scalar) { + currentEntity = (type, range.lowerBound ..< utf16.index(after: index)) + } else if delimiterSet.contains(scalar) { + if let (type, range) = currentEntity { + commitEntity(utf16, type, range, enabledTypes, &entities) } - case .hashtag: - if validHashtagSet.contains(scalar) { - currentEntity = (type, range.lowerBound ..< utf16.index(after: index)) - } else if delimiterSet.contains(scalar) { - if let (type, range) = currentEntity { - commitEntity(utf16, type, range, enabledTypes, &entities) - } - currentEntity = nil + currentEntity = nil + } + case .hashtag: + if validHashtagSet.contains(scalar) { + currentEntity = (type, range.lowerBound ..< utf16.index(after: index)) + } else if delimiterSet.contains(scalar) { + if let (type, range) = currentEntity { + commitEntity(utf16, type, range, enabledTypes, &entities) } - default: - break + currentEntity = nil + } + default: + break } } } @@ -258,7 +258,7 @@ public func generateTextEntities(_ text: String, enabledTypes: EnabledEntityType return entities } -func addLocallyGeneratedEntities(_ text: String, enabledTypes: EnabledEntityTypes, entities: [MessageTextEntity], mediaDuration: Double? = nil) -> [MessageTextEntity]? { +public func addLocallyGeneratedEntities(_ text: String, enabledTypes: EnabledEntityTypes, entities: [MessageTextEntity], mediaDuration: Double? = nil) -> [MessageTextEntity]? { var resultEntities = entities var hasDigits = false @@ -324,13 +324,13 @@ func addLocallyGeneratedEntities(_ text: String, enabledTypes: EnabledEntityType if notFound { if let (type, range) = currentEntity { switch type { - case .timecode: - if delimiterSet.contains(scalar) { - commitEntity(utf16, type, range, enabledTypes, &resultEntities, mediaDuration: mediaDuration) - currentEntity = nil - } - default: - break + case .timecode: + if delimiterSet.contains(scalar) { + commitEntity(utf16, type, range, enabledTypes, &resultEntities, mediaDuration: mediaDuration) + currentEntity = nil + } + default: + break } } } @@ -351,7 +351,7 @@ func addLocallyGeneratedEntities(_ text: String, enabledTypes: EnabledEntityType } } -func parseTimecodeString(_ string: String?) -> Double? { +public func parseTimecodeString(_ string: String?) -> Double? { if let string = string, string.rangeOfCharacter(from: validTimecodeSet.inverted) == nil { let components = string.components(separatedBy: ":") if components.count > 1 && components.count <= 3 { diff --git a/submodules/TelegramUI/TelegramUI/Markdown.swift b/submodules/TextFormat/Sources/Markdown.swift similarity index 79% rename from submodules/TelegramUI/TelegramUI/Markdown.swift rename to submodules/TextFormat/Sources/Markdown.swift index a100a73966..1857305339 100644 --- a/submodules/TelegramUI/TelegramUI/Markdown.swift +++ b/submodules/TextFormat/Sources/Markdown.swift @@ -5,25 +5,25 @@ import Display private let controlStartCharactersSet = CharacterSet(charactersIn: "[*") private let controlCharactersSet = CharacterSet(charactersIn: "[]()*_-\\") -final class MarkdownAttributeSet { - let font: UIFont - let textColor: UIColor - let additionalAttributes: [String: Any] +public final class MarkdownAttributeSet { + public let font: UIFont + public let textColor: UIColor + public let additionalAttributes: [String: Any] - init(font: UIFont, textColor: UIColor, additionalAttributes: [String: Any] = [:]) { + public init(font: UIFont, textColor: UIColor, additionalAttributes: [String: Any] = [:]) { self.font = font self.textColor = textColor self.additionalAttributes = additionalAttributes } } -final class MarkdownAttributes { - let body: MarkdownAttributeSet - let bold: MarkdownAttributeSet - let link: MarkdownAttributeSet - let linkAttribute: (String) -> (String, Any)? +public final class MarkdownAttributes { + public let body: MarkdownAttributeSet + public let bold: MarkdownAttributeSet + public let link: MarkdownAttributeSet + public let linkAttribute: (String) -> (String, Any)? - init(body: MarkdownAttributeSet, bold: MarkdownAttributeSet, link: MarkdownAttributeSet, linkAttribute: @escaping (String) -> (String, Any)?) { + public init(body: MarkdownAttributeSet, bold: MarkdownAttributeSet, link: MarkdownAttributeSet, linkAttribute: @escaping (String) -> (String, Any)?) { self.body = body self.link = link self.bold = bold @@ -31,7 +31,7 @@ final class MarkdownAttributes { } } -func escapedPlaintextForMarkdown(_ string: String) -> String { +public func escapedPlaintextForMarkdown(_ string: String) -> String { let nsString = string as NSString var remainingRange = NSMakeRange(0, nsString.length) let result = NSMutableString() @@ -52,21 +52,21 @@ func escapedPlaintextForMarkdown(_ string: String) -> String { return result as String } -func paragraphStyleWithAlignment(_ alignment: NSTextAlignment) -> NSParagraphStyle { +public func paragraphStyleWithAlignment(_ alignment: NSTextAlignment) -> NSParagraphStyle { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = alignment return paragraphStyle } -func parseMarkdownIntoAttributedString(_ string: String, attributes: MarkdownAttributes, textAlignment: NSTextAlignment = .natural) -> NSAttributedString { +public func parseMarkdownIntoAttributedString(_ string: String, attributes: MarkdownAttributes, textAlignment: NSTextAlignment = .natural) -> NSAttributedString { let nsString = string as NSString let result = NSMutableAttributedString() var remainingRange = NSMakeRange(0, nsString.length) - var bodyAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: attributes.body.font, NSAttributedStringKey.foregroundColor: attributes.body.textColor, NSAttributedStringKey.paragraphStyle: paragraphStyleWithAlignment(textAlignment)] + var bodyAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: attributes.body.font, NSAttributedString.Key.foregroundColor: attributes.body.textColor, NSAttributedString.Key.paragraphStyle: paragraphStyleWithAlignment(textAlignment)] if !attributes.body.additionalAttributes.isEmpty { for (key, value) in attributes.body.additionalAttributes { - bodyAttributes[NSAttributedStringKey(rawValue: key)] = value + bodyAttributes[NSAttributedString.Key(rawValue: key)] = value } } @@ -82,14 +82,14 @@ func parseMarkdownIntoAttributedString(_ string: String, attributes: MarkdownAtt if character == UInt16(("[" as UnicodeScalar).value) { remainingRange = NSMakeRange(range.location + range.length, remainingRange.location + remainingRange.length - (range.location + range.length)) if let (parsedLinkText, parsedLinkContents) = parseLink(string: nsString, remainingRange: &remainingRange) { - var linkAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: attributes.link.font, NSAttributedStringKey.foregroundColor: attributes.link.textColor, NSAttributedStringKey.paragraphStyle: paragraphStyleWithAlignment(textAlignment)] + var linkAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: attributes.link.font, NSAttributedString.Key.foregroundColor: attributes.link.textColor, NSAttributedString.Key.paragraphStyle: paragraphStyleWithAlignment(textAlignment)] if !attributes.link.additionalAttributes.isEmpty { for (key, value) in attributes.link.additionalAttributes { - linkAttributes[NSAttributedStringKey(rawValue: key)] = value + linkAttributes[NSAttributedString.Key(rawValue: key)] = value } } if let (attributeName, attributeValue) = attributes.linkAttribute(parsedLinkContents) { - linkAttributes[NSAttributedStringKey(rawValue: attributeName)] = attributeValue + linkAttributes[NSAttributedString.Key(rawValue: attributeName)] = attributeValue } result.append(NSAttributedString(string: parsedLinkText, attributes: linkAttributes)) } @@ -100,10 +100,10 @@ func parseMarkdownIntoAttributedString(_ string: String, attributes: MarkdownAtt remainingRange = NSMakeRange(range.location + range.length + 1, remainingRange.location + remainingRange.length - (range.location + range.length + 1)) if let bold = parseBold(string: nsString, remainingRange: &remainingRange) { - var boldAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: attributes.bold.font, NSAttributedStringKey.foregroundColor: attributes.bold.textColor, NSAttributedStringKey.paragraphStyle: paragraphStyleWithAlignment(textAlignment)] + var boldAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: attributes.bold.font, NSAttributedString.Key.foregroundColor: attributes.bold.textColor, NSAttributedString.Key.paragraphStyle: paragraphStyleWithAlignment(textAlignment)] if !attributes.body.additionalAttributes.isEmpty { for (key, value) in attributes.bold.additionalAttributes { - boldAttributes[NSAttributedStringKey(rawValue: key)] = value + boldAttributes[NSAttributedString.Key(rawValue: key)] = value } } result.append(NSAttributedString(string: bold, attributes: boldAttributes)) @@ -163,6 +163,6 @@ private func parseBold(string: NSString, remainingRange: inout NSRange) -> Strin return nil } -func foldMultipleLineBreaks(_ string: String) -> String { +public func foldMultipleLineBreaks(_ string: String) -> String { return string.replacingOccurrences(of: "(([\n\r]\\s*){2,})+", with: "\n\n", options: .regularExpression, range: nil) } diff --git a/submodules/TelegramUI/TelegramUI/StringWithAppliedEntities.swift b/submodules/TextFormat/Sources/StringWithAppliedEntities.swift similarity index 61% rename from submodules/TelegramUI/TelegramUI/StringWithAppliedEntities.swift rename to submodules/TextFormat/Sources/StringWithAppliedEntities.swift index 511b6534de..89a92e0a1a 100644 --- a/submodules/TelegramUI/TelegramUI/StringWithAppliedEntities.swift +++ b/submodules/TextFormat/Sources/StringWithAppliedEntities.swift @@ -2,7 +2,7 @@ import Foundation import UIKit import TelegramCore -func chatInputStateStringWithAppliedEntities(_ text: String, entities: [MessageTextEntity]) -> NSAttributedString { +public func chatInputStateStringWithAppliedEntities(_ text: String, entities: [MessageTextEntity]) -> NSAttributedString { var nsString: NSString? let string = NSMutableAttributedString(string: text) var skipEntity = false @@ -45,9 +45,9 @@ func chatInputStateStringWithAppliedEntities(_ text: String, entities: [MessageT return string } -func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], baseColor: UIColor, linkColor: UIColor, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false) -> NSAttributedString { +public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], baseColor: UIColor, linkColor: UIColor, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false) -> NSAttributedString { var nsString: NSString? - let string = NSMutableAttributedString(string: text, attributes: [NSAttributedStringKey.font: baseFont, NSAttributedStringKey.foregroundColor: baseColor]) + let string = NSMutableAttributedString(string: text, attributes: [NSAttributedString.Key.font: baseFont, NSAttributedString.Key.foregroundColor: baseColor]) var skipEntity = false var underlineAllLinks = false if linkColor.isEqual(baseColor) { @@ -73,44 +73,44 @@ func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], ba } switch entity.type { case .Url: - string.addAttribute(NSAttributedStringKey.foregroundColor, value: linkColor, range: range) + string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range) if underlineLinks { - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } if nsString == nil { nsString = text as NSString } - string.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.URL), value: nsString!.substring(with: range), range: range) + string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: nsString!.substring(with: range), range: range) case .Email: - string.addAttribute(NSAttributedStringKey.foregroundColor, value: linkColor, range: range) + string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range) if nsString == nil { nsString = text as NSString } if underlineLinks && underlineAllLinks { - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } - string.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.URL), value: "mailto:\(nsString!.substring(with: range))", range: range) + string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: "mailto:\(nsString!.substring(with: range))", range: range) case .PhoneNumber: - string.addAttribute(NSAttributedStringKey.foregroundColor, value: linkColor, range: range) + string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range) if nsString == nil { nsString = text as NSString } if underlineLinks && underlineAllLinks { - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } - string.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.URL), value: "tel:\(nsString!.substring(with: range))", range: range) + string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: "tel:\(nsString!.substring(with: range))", range: range) case let .TextUrl(url): - string.addAttribute(NSAttributedStringKey.foregroundColor, value: linkColor, range: range) + string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range) if nsString == nil { nsString = text as NSString } if underlineLinks && underlineAllLinks { - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } if external { - string.addAttribute(NSAttributedStringKey.link, value: url, range: range) + string.addAttribute(NSAttributedString.Key.link, value: url, range: range) } else { - string.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.URL), value: url, range: range) + string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: url, range: range) } case .Bold: if let fontAttribute = fontAttributes[range] { @@ -125,31 +125,31 @@ func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], ba fontAttributes[range] = .italic } case .Mention: - string.addAttribute(NSAttributedStringKey.foregroundColor, value: linkColor, range: range) + string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range) if underlineLinks && underlineAllLinks { - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } if linkFont !== baseFont { - string.addAttribute(NSAttributedStringKey.font, value: linkFont, range: range) + string.addAttribute(NSAttributedString.Key.font, value: linkFont, range: range) } if nsString == nil { nsString = text as NSString } - string.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention), value: nsString!.substring(with: range), range: range) + string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention), value: nsString!.substring(with: range), range: range) case .Strikethrough: - string.addAttribute(NSAttributedStringKey.strikethroughStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) case .Underline: - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) case let .TextMention(peerId): - string.addAttribute(NSAttributedStringKey.foregroundColor, value: linkColor, range: range) + string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range) if underlineLinks && underlineAllLinks { - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } if linkFont !== baseFont { - string.addAttribute(NSAttributedStringKey.font, value: linkFont, range: range) + string.addAttribute(NSAttributedString.Key.font, value: linkFont, range: range) } let mention = nsString!.substring(with: range) - string.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention), value: TelegramPeerMention(peerId: peerId, mention: mention), range: range) + string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention), value: TelegramPeerMention(peerId: peerId, mention: mention), range: range) case .Hashtag: if nsString == nil { nsString = text as NSString @@ -163,32 +163,32 @@ func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], ba skipEntity = true let combinedRange = NSRange(location: range.location, length: nextRange.location + nextRange.length - range.location) - string.addAttribute(NSAttributedStringKey.foregroundColor, value: linkColor, range: combinedRange) + string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: combinedRange) if linkColor.isEqual(baseColor) { - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: combinedRange) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: combinedRange) } - string.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag), value: TelegramHashtag(peerName: peerName, hashtag: hashtag), range: combinedRange) + string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag), value: TelegramHashtag(peerName: peerName, hashtag: hashtag), range: combinedRange) } } } if !skipEntity { - string.addAttribute(NSAttributedStringKey.foregroundColor, value: linkColor, range: range) + string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range) if underlineLinks && underlineAllLinks { - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } - string.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag), value: TelegramHashtag(peerName: nil, hashtag: hashtag), range: range) + string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag), value: TelegramHashtag(peerName: nil, hashtag: hashtag), range: range) } case .BotCommand: - string.addAttribute(NSAttributedStringKey.foregroundColor, value: linkColor, range: range) + string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range) if underlineLinks && underlineAllLinks { - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } if nsString == nil { nsString = text as NSString } - string.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.BotCommand), value: nsString!.substring(with: range), range: range) + string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.BotCommand), value: nsString!.substring(with: range), range: range) case .Code, .Pre: - string.addAttribute(NSAttributedStringKey.font, value: fixedFont, range: range) + string.addAttribute(NSAttributedString.Key.font, value: fixedFont, range: range) case .BlockQuote: if let fontAttribute = fontAttributes[range] { fontAttributes[range] = fontAttribute.union(.blockQuote) @@ -204,22 +204,22 @@ func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], ba let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.headIndent = 10.0 paragraphStyle.tabStops = [NSTextTab(textAlignment: .left, location: paragraphStyle.headIndent, options: [:])] - string.addAttribute(NSAttributedStringKey.paragraphStyle, value: paragraphStyle, range: paragraphRange) + string.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: paragraphRange) string.insert(NSAttributedString(string: paragraphBreak), at: paragraphRange.upperBound) rangeOffset += paragraphBreak.count case let .Custom(type): if type == ApplicationSpecificEntityType.Timecode { - string.addAttribute(NSAttributedStringKey.foregroundColor, value: linkColor, range: range) + string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range) if underlineLinks && underlineAllLinks { - string.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: range) + string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: range) } if nsString == nil { nsString = text as NSString } let text = nsString!.substring(with: range) if let time = parseTimecodeString(text) { - string.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.Timecode), value: TelegramTimecode(time: time, text: text), range: range) + string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.Timecode), value: TelegramTimecode(time: time, text: text), range: range) } } default: @@ -238,7 +238,7 @@ func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], ba font = italicFont } if let font = font { - string.addAttribute(NSAttributedStringKey.font, value: font, range: range) + string.addAttribute(NSAttributedString.Key.font, value: font, range: range) } } } diff --git a/submodules/TextFormat/Sources/TelegramAttributes.swift b/submodules/TextFormat/Sources/TelegramAttributes.swift new file mode 100644 index 0000000000..b05f982d82 --- /dev/null +++ b/submodules/TextFormat/Sources/TelegramAttributes.swift @@ -0,0 +1,42 @@ +import Foundation +import Postbox + +public final class TelegramHashtag { + public let peerName: String? + public let hashtag: String + + public init(peerName: String?, hashtag: String) { + self.peerName = peerName + self.hashtag = hashtag + } +} + +public final class TelegramPeerMention { + public let peerId: PeerId + public let mention: String + + public init(peerId: PeerId, mention: String) { + self.peerId = peerId + self.mention = mention + } +} + +public final class TelegramTimecode { + public let time: Double + public let text: String + + public init(time: Double, text: String) { + self.time = time + self.text = text + } +} + +public struct TelegramTextAttributes { + public static let URL = "UrlAttributeT" + public static let PeerMention = "TelegramPeerMention" + public static let PeerTextMention = "TelegramPeerTextMention" + public static let BotCommand = "TelegramBotCommand" + public static let Hashtag = "TelegramHashtag" + public static let Timecode = "TelegramTimecode" + public static let BlockQuote = "TelegramBlockQuote" +} diff --git a/submodules/TextFormat/Sources/TextFormat.h b/submodules/TextFormat/Sources/TextFormat.h new file mode 100644 index 0000000000..dee068c1cc --- /dev/null +++ b/submodules/TextFormat/Sources/TextFormat.h @@ -0,0 +1,19 @@ +// +// TextFormat.h +// TextFormat +// +// Created by Peter on 8/1/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for TextFormat. +FOUNDATION_EXPORT double TextFormatVersionNumber; + +//! Project version string for TextFormat. +FOUNDATION_EXPORT const unsigned char TextFormatVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/TextFormat/TextFormat_Xcode.xcodeproj/project.pbxproj b/submodules/TextFormat/TextFormat_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..e506a48304 --- /dev/null +++ b/submodules/TextFormat/TextFormat_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,575 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D06018B122F364DC00796784 /* GenerateTextEntities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06018B022F364DC00796784 /* GenerateTextEntities.swift */; }; + D06018B322F3650C00796784 /* ChatTextInputAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06018B222F3650C00796784 /* ChatTextInputAttributes.swift */; }; + D06018B722F365D800796784 /* StringWithAppliedEntities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06018B622F365D700796784 /* StringWithAppliedEntities.swift */; }; + D0A0B53B22F3714F00628AF3 /* TelegramCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0A0B53A22F3714F00628AF3 /* TelegramCore.framework */; }; + D0A0B53D22F3726300628AF3 /* TelegramPresentationData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0A0B53C22F3726300628AF3 /* TelegramPresentationData.framework */; }; + D0D328CA22F3495C00D07EE2 /* TextFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D328C822F3495C00D07EE2 /* TextFormat.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0D328D522F349CB00D07EE2 /* Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D328D422F349CB00D07EE2 /* Markdown.swift */; }; + D0D328D822F349F400D07EE2 /* Display.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D328D722F349F400D07EE2 /* Display.framework */; }; + D0D328DA22F349F800D07EE2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D328D922F349F800D07EE2 /* Foundation.framework */; }; + D0D328DC22F349FB00D07EE2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D328DB22F349FB00D07EE2 /* UIKit.framework */; }; + D0D328E022F3526000D07EE2 /* TelegramAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D328DF22F3526000D07EE2 /* TelegramAttributes.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D06018B022F364DC00796784 /* GenerateTextEntities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateTextEntities.swift; sourceTree = ""; }; + D06018B222F3650C00796784 /* ChatTextInputAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatTextInputAttributes.swift; sourceTree = ""; }; + D06018B622F365D700796784 /* StringWithAppliedEntities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringWithAppliedEntities.swift; sourceTree = ""; }; + D0A0B53A22F3714F00628AF3 /* TelegramCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TelegramCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0A0B53C22F3726300628AF3 /* TelegramPresentationData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TelegramPresentationData.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D328C522F3495C00D07EE2 /* TextFormat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TextFormat.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D328C822F3495C00D07EE2 /* TextFormat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextFormat.h; sourceTree = ""; }; + D0D328C922F3495C00D07EE2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D0D328D422F349CB00D07EE2 /* Markdown.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Markdown.swift; sourceTree = ""; }; + D0D328D722F349F400D07EE2 /* Display.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Display.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D328D922F349F800D07EE2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D0D328DB22F349FB00D07EE2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D0D328DF22F3526000D07EE2 /* TelegramAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelegramAttributes.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D0D328C222F3495C00D07EE2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D0A0B53D22F3726300628AF3 /* TelegramPresentationData.framework in Frameworks */, + D0A0B53B22F3714F00628AF3 /* TelegramCore.framework in Frameworks */, + D0D328DC22F349FB00D07EE2 /* UIKit.framework in Frameworks */, + D0D328DA22F349F800D07EE2 /* Foundation.framework in Frameworks */, + D0D328D822F349F400D07EE2 /* Display.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D0D328BB22F3495C00D07EE2 = { + isa = PBXGroup; + children = ( + D0D328C922F3495C00D07EE2 /* Info.plist */, + D0D328C722F3495C00D07EE2 /* Sources */, + D0D328C622F3495C00D07EE2 /* Products */, + D0D328D622F349F400D07EE2 /* Frameworks */, + ); + sourceTree = ""; + }; + D0D328C622F3495C00D07EE2 /* Products */ = { + isa = PBXGroup; + children = ( + D0D328C522F3495C00D07EE2 /* TextFormat.framework */, + ); + name = Products; + sourceTree = ""; + }; + D0D328C722F3495C00D07EE2 /* Sources */ = { + isa = PBXGroup; + children = ( + D06018B622F365D700796784 /* StringWithAppliedEntities.swift */, + D06018B222F3650C00796784 /* ChatTextInputAttributes.swift */, + D06018B022F364DC00796784 /* GenerateTextEntities.swift */, + D0D328D422F349CB00D07EE2 /* Markdown.swift */, + D0D328C822F3495C00D07EE2 /* TextFormat.h */, + D0D328DF22F3526000D07EE2 /* TelegramAttributes.swift */, + ); + path = Sources; + sourceTree = ""; + }; + D0D328D622F349F400D07EE2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D0A0B53C22F3726300628AF3 /* TelegramPresentationData.framework */, + D0A0B53A22F3714F00628AF3 /* TelegramCore.framework */, + D0D328DB22F349FB00D07EE2 /* UIKit.framework */, + D0D328D922F349F800D07EE2 /* Foundation.framework */, + D0D328D722F349F400D07EE2 /* Display.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D0D328C022F3495C00D07EE2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D0D328CA22F3495C00D07EE2 /* TextFormat.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D0D328C422F3495C00D07EE2 /* TextFormat */ = { + isa = PBXNativeTarget; + buildConfigurationList = D0D328CD22F3495C00D07EE2 /* Build configuration list for PBXNativeTarget "TextFormat" */; + buildPhases = ( + D0D328C022F3495C00D07EE2 /* Headers */, + D0D328C122F3495C00D07EE2 /* Sources */, + D0D328C222F3495C00D07EE2 /* Frameworks */, + D0D328C322F3495C00D07EE2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TextFormat; + productName = TextFormat; + productReference = D0D328C522F3495C00D07EE2 /* TextFormat.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D0D328BC22F3495C00D07EE2 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D0D328C422F3495C00D07EE2 = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1010; + }; + }; + }; + buildConfigurationList = D0D328BF22F3495C00D07EE2 /* Build configuration list for PBXProject "TextFormat_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D0D328BB22F3495C00D07EE2; + productRefGroup = D0D328C622F3495C00D07EE2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D0D328C422F3495C00D07EE2 /* TextFormat */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D0D328C322F3495C00D07EE2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D0D328C122F3495C00D07EE2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D06018B722F365D800796784 /* StringWithAppliedEntities.swift in Sources */, + D06018B322F3650C00796784 /* ChatTextInputAttributes.swift in Sources */, + D0D328D522F349CB00D07EE2 /* Markdown.swift in Sources */, + D0D328E022F3526000D07EE2 /* TelegramAttributes.swift in Sources */, + D06018B122F364DC00796784 /* GenerateTextEntities.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D0D328CB22F3495C00D07EE2 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D0D328CC22F3495C00D07EE2 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D0D328CE22F3495C00D07EE2 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.TextFormat; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D0D328CF22F3495C00D07EE2 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.TextFormat; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D0D328D022F3498E00D07EE2 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D0D328D122F3498E00D07EE2 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.TextFormat; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D0D328D222F3499900D07EE2 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D0D328D322F3499900D07EE2 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.TextFormat; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D0D328BF22F3495C00D07EE2 /* Build configuration list for PBXProject "TextFormat_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0D328CB22F3495C00D07EE2 /* DebugAppStoreLLC */, + D0D328D022F3498E00D07EE2 /* DebugHockeyapp */, + D0D328CC22F3495C00D07EE2 /* ReleaseAppStoreLLC */, + D0D328D222F3499900D07EE2 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D0D328CD22F3495C00D07EE2 /* Build configuration list for PBXNativeTarget "TextFormat" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0D328CE22F3495C00D07EE2 /* DebugAppStoreLLC */, + D0D328D122F3498E00D07EE2 /* DebugHockeyapp */, + D0D328CF22F3495C00D07EE2 /* ReleaseAppStoreLLC */, + D0D328D322F3499900D07EE2 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D0D328BC22F3495C00D07EE2 /* Project object */; +} From 0688983c52a8dbc261abc30e11dce80c3a0176eb Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:25:50 +0300 Subject: [PATCH 38/41] Refactor TelegramUpdateUI --- submodules/TelegramUpdateUI/Info.plist | 22 + .../Sources/TelegramUpdateUI.h | 19 + .../Sources}/UpdateInfoController.swift | 18 +- .../Sources}/UpdateInfoItem.swift | 11 +- .../project.pbxproj | 575 ++++++++++++++++++ 5 files changed, 633 insertions(+), 12 deletions(-) create mode 100644 submodules/TelegramUpdateUI/Info.plist create mode 100644 submodules/TelegramUpdateUI/Sources/TelegramUpdateUI.h rename submodules/{TelegramUI/TelegramUI => TelegramUpdateUI/Sources}/UpdateInfoController.swift (86%) rename submodules/{TelegramUI/TelegramUI => TelegramUpdateUI/Sources}/UpdateInfoItem.swift (98%) create mode 100644 submodules/TelegramUpdateUI/TelegramUpdateUI_Xcode.xcodeproj/project.pbxproj diff --git a/submodules/TelegramUpdateUI/Info.plist b/submodules/TelegramUpdateUI/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/TelegramUpdateUI/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/TelegramUpdateUI/Sources/TelegramUpdateUI.h b/submodules/TelegramUpdateUI/Sources/TelegramUpdateUI.h new file mode 100644 index 0000000000..b423213831 --- /dev/null +++ b/submodules/TelegramUpdateUI/Sources/TelegramUpdateUI.h @@ -0,0 +1,19 @@ +// +// TelegramUpdateUI.h +// TelegramUpdateUI +// +// Created by Peter on 8/1/19. +// Copyright © 2019 Telegram Messenger LLP. All rights reserved. +// + +#import + +//! Project version number for TelegramUpdateUI. +FOUNDATION_EXPORT double TelegramUpdateUIVersionNumber; + +//! Project version string for TelegramUpdateUI. +FOUNDATION_EXPORT const unsigned char TelegramUpdateUIVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/submodules/TelegramUI/TelegramUI/UpdateInfoController.swift b/submodules/TelegramUpdateUI/Sources/UpdateInfoController.swift similarity index 86% rename from submodules/TelegramUI/TelegramUI/UpdateInfoController.swift rename to submodules/TelegramUpdateUI/Sources/UpdateInfoController.swift index 04a1dd054c..2dbb0a709a 100644 --- a/submodules/TelegramUI/TelegramUI/UpdateInfoController.swift +++ b/submodules/TelegramUpdateUI/Sources/UpdateInfoController.swift @@ -5,6 +5,8 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import AccountContext +import ItemListUI private final class UpdateInfoControllerArguments { let openAppStorePage: () -> Void @@ -97,17 +99,17 @@ public func updateInfoController(context: AccountContext, appUpdateInfo: AppUpda actionsDisposable.add(navigateDisposable) let arguments = UpdateInfoControllerArguments(openAppStorePage: { - context.sharedContext.applicationBindings.openAppStorePage() + context.genericSharedContext.applicationBindings.openAppStorePage() }, linkAction: { action, itemLink in linkActionImpl?(action, itemLink) }) - let signal = context.sharedContext.presentationData + let signal = context.genericSharedContext.presentationData |> deliverOnMainQueue |> map { presentationData -> (ItemListControllerState, (ItemListNodeState, UpdateInfoControllerEntry.ItemGenerationArguments)) in let appIcon: PresentationAppIcon? - let appIcons = context.sharedContext.applicationBindings.getAvailableAlternateIcons() - if let alternateIconName = context.sharedContext.applicationBindings.getAlternateIconName() { + let appIcons = context.genericSharedContext.applicationBindings.getAvailableAlternateIcons() + if let alternateIconName = context.genericSharedContext.applicationBindings.getAlternateIconName() { appIcon = appIcons.filter { $0.name == alternateIconName }.first } else { appIcon = appIcons.filter { $0.isDefault }.first @@ -125,10 +127,10 @@ public func updateInfoController(context: AccountContext, appUpdateInfo: AppUpda actionsDisposable.dispose() } - let controller = ItemListController(sharedContext: context.sharedContext, state: signal) - linkActionImpl = { [weak controller] action, itemLink in - if let strongController = controller { - handleTextLinkAction(context: context, peerId: nil, navigateDisposable: navigateDisposable, controller: strongController, action: action, itemLink: itemLink) + let controller = ItemListController(sharedContext: context.genericSharedContext, state: signal) + linkActionImpl = { [weak controller, weak context] action, itemLink in + if let strongController = controller, let context = context { + context.genericSharedContext.handleTextLinkAction(context: context, peerId: nil, navigateDisposable: navigateDisposable, controller: strongController, action: action, itemLink: itemLink) } } dismissImpl = { [weak controller] in diff --git a/submodules/TelegramUI/TelegramUI/UpdateInfoItem.swift b/submodules/TelegramUpdateUI/Sources/UpdateInfoItem.swift similarity index 98% rename from submodules/TelegramUI/TelegramUI/UpdateInfoItem.swift rename to submodules/TelegramUpdateUI/Sources/UpdateInfoItem.swift index aaab7a0921..d3d58c903e 100644 --- a/submodules/TelegramUI/TelegramUI/UpdateInfoItem.swift +++ b/submodules/TelegramUpdateUI/Sources/UpdateInfoItem.swift @@ -5,6 +5,9 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ItemListUI +import TextFormat +import AccountContext private func generateBorderImage(theme: PresentationTheme, bordered: Bool) -> UIImage? { return generateImage(CGSize(width: 30.0, height: 30.0), rotatedContext: { size, context in @@ -386,11 +389,11 @@ class UpdateInfoItemNode: ListViewItemNode { private func linkItemAtPoint(_ point: CGPoint) -> TextLinkItem? { let textNodeFrame = self.textNode.frame if let (_, attributes) = self.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { return .url(url) - } else if let peerName = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let peerName = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { return .mention(peerName) - } else if let hashtag = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { + } else if let hashtag = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { return .hashtag(hashtag.peerName, hashtag.hashtag) } else { return nil @@ -413,7 +416,7 @@ class UpdateInfoItemNode: ListViewItemNode { TelegramTextAttributes.Hashtag ] for name in possibleNames { - if let _ = attributes[NSAttributedStringKey(rawValue: name)] { + if let _ = attributes[NSAttributedString.Key(rawValue: name)] { rects = self.textNode.attributeRects(name: name, at: index) break } diff --git a/submodules/TelegramUpdateUI/TelegramUpdateUI_Xcode.xcodeproj/project.pbxproj b/submodules/TelegramUpdateUI/TelegramUpdateUI_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..349c2ecdee --- /dev/null +++ b/submodules/TelegramUpdateUI/TelegramUpdateUI_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,575 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D060184822F35DBB00796784 /* ItemListUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060184722F35DBB00796784 /* ItemListUI.framework */; }; + D0D327F622F31A7800D07EE2 /* TelegramUpdateUI.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D327F422F31A7800D07EE2 /* TelegramUpdateUI.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0D3280222F31AE500D07EE2 /* UpdateInfoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3280022F31AE500D07EE2 /* UpdateInfoItem.swift */; }; + D0D3280322F31AE500D07EE2 /* UpdateInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D3280122F31AE500D07EE2 /* UpdateInfoController.swift */; }; + D0D3280622F31AF300D07EE2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3280522F31AF300D07EE2 /* Foundation.framework */; }; + D0D3280822F31AF700D07EE2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3280722F31AF700D07EE2 /* UIKit.framework */; }; + D0D3280A22F31AFC00D07EE2 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3280922F31AFC00D07EE2 /* SwiftSignalKit.framework */; }; + D0D3280C22F31AFF00D07EE2 /* Postbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3280B22F31AFF00D07EE2 /* Postbox.framework */; }; + D0D3280E22F31B0C00D07EE2 /* Display.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3280D22F31B0C00D07EE2 /* Display.framework */; }; + D0D3281022F31B1100D07EE2 /* TelegramCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3280F22F31B1100D07EE2 /* TelegramCore.framework */; }; + D0D3281222F31B1700D07EE2 /* TelegramPresentationData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3281122F31B1700D07EE2 /* TelegramPresentationData.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D060184722F35DBB00796784 /* ItemListUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = ItemListUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D327F122F31A7800D07EE2 /* TelegramUpdateUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TelegramUpdateUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D327F422F31A7800D07EE2 /* TelegramUpdateUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TelegramUpdateUI.h; sourceTree = ""; }; + D0D327F522F31A7800D07EE2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D0D3280022F31AE500D07EE2 /* UpdateInfoItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateInfoItem.swift; sourceTree = ""; }; + D0D3280122F31AE500D07EE2 /* UpdateInfoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateInfoController.swift; sourceTree = ""; }; + D0D3280522F31AF300D07EE2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D0D3280722F31AF700D07EE2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D0D3280922F31AFC00D07EE2 /* SwiftSignalKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwiftSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3280B22F31AFF00D07EE2 /* Postbox.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Postbox.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3280D22F31B0C00D07EE2 /* Display.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Display.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3280F22F31B1100D07EE2 /* TelegramCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TelegramCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0D3281122F31B1700D07EE2 /* TelegramPresentationData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TelegramPresentationData.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D0D327EE22F31A7800D07EE2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D060184822F35DBB00796784 /* ItemListUI.framework in Frameworks */, + D0D3281222F31B1700D07EE2 /* TelegramPresentationData.framework in Frameworks */, + D0D3281022F31B1100D07EE2 /* TelegramCore.framework in Frameworks */, + D0D3280E22F31B0C00D07EE2 /* Display.framework in Frameworks */, + D0D3280C22F31AFF00D07EE2 /* Postbox.framework in Frameworks */, + D0D3280A22F31AFC00D07EE2 /* SwiftSignalKit.framework in Frameworks */, + D0D3280822F31AF700D07EE2 /* UIKit.framework in Frameworks */, + D0D3280622F31AF300D07EE2 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D0D327E722F31A7800D07EE2 = { + isa = PBXGroup; + children = ( + D0D327F522F31A7800D07EE2 /* Info.plist */, + D0D327F322F31A7800D07EE2 /* Sources */, + D0D327F222F31A7800D07EE2 /* Products */, + D0D3280422F31AF300D07EE2 /* Frameworks */, + ); + sourceTree = ""; + }; + D0D327F222F31A7800D07EE2 /* Products */ = { + isa = PBXGroup; + children = ( + D0D327F122F31A7800D07EE2 /* TelegramUpdateUI.framework */, + ); + name = Products; + sourceTree = ""; + }; + D0D327F322F31A7800D07EE2 /* Sources */ = { + isa = PBXGroup; + children = ( + D0D3280122F31AE500D07EE2 /* UpdateInfoController.swift */, + D0D3280022F31AE500D07EE2 /* UpdateInfoItem.swift */, + D0D327F422F31A7800D07EE2 /* TelegramUpdateUI.h */, + ); + path = Sources; + sourceTree = ""; + }; + D0D3280422F31AF300D07EE2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D060184722F35DBB00796784 /* ItemListUI.framework */, + D0D3281122F31B1700D07EE2 /* TelegramPresentationData.framework */, + D0D3280F22F31B1100D07EE2 /* TelegramCore.framework */, + D0D3280D22F31B0C00D07EE2 /* Display.framework */, + D0D3280B22F31AFF00D07EE2 /* Postbox.framework */, + D0D3280922F31AFC00D07EE2 /* SwiftSignalKit.framework */, + D0D3280722F31AF700D07EE2 /* UIKit.framework */, + D0D3280522F31AF300D07EE2 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D0D327EC22F31A7800D07EE2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D0D327F622F31A7800D07EE2 /* TelegramUpdateUI.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D0D327F022F31A7800D07EE2 /* TelegramUpdateUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = D0D327F922F31A7800D07EE2 /* Build configuration list for PBXNativeTarget "TelegramUpdateUI" */; + buildPhases = ( + D0D327EC22F31A7800D07EE2 /* Headers */, + D0D327ED22F31A7800D07EE2 /* Sources */, + D0D327EE22F31A7800D07EE2 /* Frameworks */, + D0D327EF22F31A7800D07EE2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TelegramUpdateUI; + productName = TelegramUpdateUI; + productReference = D0D327F122F31A7800D07EE2 /* TelegramUpdateUI.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D0D327E822F31A7800D07EE2 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram Messenger LLP"; + TargetAttributes = { + D0D327F022F31A7800D07EE2 = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1010; + }; + }; + }; + buildConfigurationList = D0D327EB22F31A7800D07EE2 /* Build configuration list for PBXProject "TelegramUpdateUI_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D0D327E722F31A7800D07EE2; + productRefGroup = D0D327F222F31A7800D07EE2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D0D327F022F31A7800D07EE2 /* TelegramUpdateUI */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D0D327EF22F31A7800D07EE2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D0D327ED22F31A7800D07EE2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D0D3280322F31AE500D07EE2 /* UpdateInfoController.swift in Sources */, + D0D3280222F31AE500D07EE2 /* UpdateInfoItem.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D0D327F722F31A7800D07EE2 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugAppStoreLLC; + }; + D0D327F822F31A7800D07EE2 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseAppStoreLLC; + }; + D0D327FA22F31A7800D07EE2 /* DebugAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.TelegramUpdateUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugAppStoreLLC; + }; + D0D327FB22F31A7800D07EE2 /* ReleaseAppStoreLLC */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.TelegramUpdateUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseAppStoreLLC; + }; + D0D327FC22F31AA200D07EE2 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D0D327FD22F31AA200D07EE2 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.TelegramUpdateUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D0D327FE22F31AAE00D07EE2 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = ReleaseHockeyappInternal; + }; + D0D327FF22F31AAE00D07EE2 /* ReleaseHockeyappInternal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.TelegramUpdateUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = ReleaseHockeyappInternal; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D0D327EB22F31A7800D07EE2 /* Build configuration list for PBXProject "TelegramUpdateUI_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0D327F722F31A7800D07EE2 /* DebugAppStoreLLC */, + D0D327FC22F31AA200D07EE2 /* DebugHockeyapp */, + D0D327F822F31A7800D07EE2 /* ReleaseAppStoreLLC */, + D0D327FE22F31AAE00D07EE2 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; + D0D327F922F31A7800D07EE2 /* Build configuration list for PBXNativeTarget "TelegramUpdateUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0D327FA22F31A7800D07EE2 /* DebugAppStoreLLC */, + D0D327FD22F31AA200D07EE2 /* DebugHockeyapp */, + D0D327FB22F31A7800D07EE2 /* ReleaseAppStoreLLC */, + D0D327FF22F31AAE00D07EE2 /* ReleaseHockeyappInternal */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ReleaseAppStoreLLC; + }; +/* End XCConfigurationList section */ + }; + rootObject = D0D327E822F31A7800D07EE2 /* Project object */; +} From 54b6402c720a42c29b7276497ddbc91481cf9979 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:26:15 +0300 Subject: [PATCH 39/41] Cleanup --- .../TelegramCore/TelegramCore/BotInfo.swift | 6 +----- .../TelegramCore/PeerCommands.swift | 7 ++++++- .../project.pbxproj | 18 +++++++++--------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/submodules/TelegramCore/TelegramCore/BotInfo.swift b/submodules/TelegramCore/TelegramCore/BotInfo.swift index 76e78942bf..b139c6258c 100644 --- a/submodules/TelegramCore/TelegramCore/BotInfo.swift +++ b/submodules/TelegramCore/TelegramCore/BotInfo.swift @@ -7,7 +7,7 @@ import Foundation import TelegramApi #endif -public struct BotCommand: PostboxCoding, Equatable { +public struct BotCommand: PostboxCoding, Hashable { public let text: String public let description: String @@ -25,10 +25,6 @@ public struct BotCommand: PostboxCoding, Equatable { encoder.encodeString(self.text, forKey: "t") encoder.encodeString(self.description, forKey: "d") } - - public static func ==(lhs: BotCommand, rhs: BotCommand) -> Bool { - return lhs.text == rhs.text && lhs.description == rhs.description - } } public final class BotInfo: PostboxCoding, Equatable { diff --git a/submodules/TelegramCore/TelegramCore/PeerCommands.swift b/submodules/TelegramCore/TelegramCore/PeerCommands.swift index 2f73efe746..2c5f0dd6db 100644 --- a/submodules/TelegramCore/TelegramCore/PeerCommands.swift +++ b/submodules/TelegramCore/TelegramCore/PeerCommands.swift @@ -7,13 +7,18 @@ import Foundation import SwiftSignalKit #endif -public struct PeerCommand: Equatable { +public struct PeerCommand: Hashable { public let peer: Peer public let command: BotCommand public static func ==(lhs: PeerCommand, rhs: PeerCommand) -> Bool { return lhs.peer.isEqual(rhs.peer) && lhs.command == rhs.command } + + public func hash(into hasher: inout Hasher) { + hasher.combine(self.peer.id) + hasher.combine(self.command) + } } public struct PeerCommands: Equatable { diff --git a/submodules/TelegramCore/TelegramCore_Xcode.xcodeproj/project.pbxproj b/submodules/TelegramCore/TelegramCore_Xcode.xcodeproj/project.pbxproj index 5cdbd6676f..8d7c8e386c 100644 --- a/submodules/TelegramCore/TelegramCore_Xcode.xcodeproj/project.pbxproj +++ b/submodules/TelegramCore/TelegramCore_Xcode.xcodeproj/project.pbxproj @@ -3081,7 +3081,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = all; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = ReleaseHockeyapp; @@ -3210,7 +3210,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = all; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = DebugFork; @@ -3345,7 +3345,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = all; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = HockeyappMacAlpha; @@ -3473,7 +3473,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = all; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = ReleaseAppStore; @@ -3567,7 +3567,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = all; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = ReleaseHockeyappInternal; @@ -3744,7 +3744,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = all; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = DebugHockeyapp; @@ -3784,7 +3784,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = all; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = DebugAppStore; @@ -3893,7 +3893,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_REFLECTION_METADATA_LEVEL = all; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = DebugAppStoreLLC; @@ -4110,7 +4110,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_REFLECTION_METADATA_LEVEL = all; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = ReleaseAppStoreLLC; From f8c2c13e28a35f1d95f2ac9edd8aab9216ba0326 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:26:53 +0300 Subject: [PATCH 40/41] Update TelegramUI to Swift 4.2 --- .../TelegramUI/TelegramUI/Accessibility.swift | 8 +- .../TelegramUI/AccountContext.swift | 68 +---- .../TelegramUI/TelegramUI/AccountUtils.swift | 2 +- .../AddFormatToStringWithRanges.swift | 9 +- .../TelegramUI/TelegramUI/AppDelegate.swift | 151 ++--------- .../TelegramUI/ApplicationContext.swift | 9 +- .../ArchivedStickerPacksController.swift | 3 +- .../TelegramUI/AudioRecordningToneData.swift | 2 +- ...quenceAwaitingAccountResetController.swift | 1 + ...orizationSequenceCodeEntryController.swift | 1 + ...ationSequenceCodeEntryControllerNode.swift | 1 + .../AuthorizationSequenceController.swift | 9 +- ...quenceCountrySelectionControllerNode.swift | 4 +- ...ationSequencePasswordEntryController.swift | 1 + ...onSequencePasswordRecoveryController.swift | 1 + ...rizationSequencePhoneEntryController.swift | 5 +- ...tionSequencePhoneEntryControllerNode.swift | 2 - ...uthorizationSequenceSignUpController.swift | 1 + ...rizationSequenceSignUpControllerNode.swift | 7 +- ...AutodownloadConnectionTypeController.swift | 3 +- .../AutodownloadDataUsagePickerItem.swift | 5 +- .../AutodownloadMediaCategoryController.swift | 3 +- .../AutodownloadSizeLimitItem.swift | 7 +- .../TelegramUI/AvatarGalleryController.swift | 4 +- .../AvatarGalleryItemFooterContentNode.swift | 4 +- .../TelegramUI/TelegramUI/AvatarNode.swift | 5 +- .../TelegramUI/BlockedPeersController.swift | 3 +- .../TelegramUI/BlurredImageNode.swift | 2 +- .../TelegramUI/BotCheckoutActionButton.swift | 8 +- .../TelegramUI/BotCheckoutController.swift | 4 +- .../BotCheckoutControllerNode.swift | 5 +- .../TelegramUI/BotCheckoutHeaderItem.swift | 1 + .../BotCheckoutInfoController.swift | 5 +- .../BotCheckoutInfoControllerNode.swift | 6 +- ...BotCheckoutNativeCardEntryController.swift | 5 +- ...heckoutNativeCardEntryControllerNode.swift | 2 +- .../BotCheckoutPasswordEntryController.swift | 8 +- .../BotCheckoutPaymentMethodSheet.swift | 2 +- ...PaymentShippingOptionSheetController.swift | 2 +- .../TelegramUI/BotCheckoutPriceItem.swift | 1 + .../BotCheckoutWebInteractionController.swift | 4 +- ...CheckoutWebInteractionControllerNode.swift | 2 +- .../TelegramUI/BotPaymentActionItemNode.swift | 2 +- .../BotPaymentDisclosureItemNode.swift | 2 +- .../TelegramUI/BotPaymentSwitchItemNode.swift | 2 - .../TelegramUI/BotReceiptController.swift | 4 +- .../TelegramUI/BotReceiptControllerNode.swift | 5 +- .../TelegramUI/CachedFaqInstantPage.swift | 4 +- .../TelegramUI/CalculatingCacheSizeItem.swift | 2 + .../TelegramUI/CallController.swift | 4 +- .../TelegramUI/CallControllerButton.swift | 2 +- .../CallControllerKeyPreviewNode.swift | 2 +- .../TelegramUI/CallControllerNode.swift | 8 +- .../TelegramUI/TelegramUI/CallDebugNode.swift | 12 +- .../TelegramUI/CallFeedbackController.swift | 3 +- .../TelegramUI/CallListCallItem.swift | 1 + .../TelegramUI/CallListController.swift | 5 +- .../TelegramUI/CallListControllerNode.swift | 5 +- .../TelegramUI/CallListNodeEntries.swift | 1 + .../TelegramUI/CallListViewTransition.swift | 1 + .../TelegramUI/CallRatingController.swift | 2 +- .../TelegramUI/CallSuggestTabController.swift | 2 +- .../ChangePhoneNumberCodeController.swift | 5 +- .../ChangePhoneNumberController.swift | 5 +- .../ChangePhoneNumberIntroController.swift | 7 +- .../TelegramUI/ChannelAdminController.swift | 3 +- .../TelegramUI/ChannelAdminsController.swift | 3 +- .../ChannelBannedMemberController.swift | 3 +- .../ChannelBlacklistController.swift | 3 +- ...hannelDiscussionGroupActionSheetItem.swift | 6 +- ...elDiscussionGroupSearchContainerNode.swift | 5 +- ...hannelDiscussionGroupSetupController.swift | 3 +- ...hannelDiscussionGroupSetupHeaderItem.swift | 2 + ...hannelDiscussionGroupSetupSearchItem.swift | 7 +- .../TelegramUI/ChannelInfoController.swift | 13 +- .../TelegramUI/ChannelMembersController.swift | 5 +- .../ChannelMembersSearchContainerNode.swift | 9 +- .../ChannelMembersSearchController.swift | 4 +- .../ChannelMembersSearchControllerNode.swift | 7 +- .../ChannelOwnershipTransferController.swift | 12 +- .../ChannelPermissionsController.swift | 3 +- .../TelegramUI/ChannelStatsController.swift | 5 +- .../ChannelStatsControllerNode.swift | 6 +- .../ChannelVisibilityController.swift | 3 +- .../TelegramUI/ChatAnimationGalleryItem.swift | 15 +- .../TelegramUI/ChatBotInfoItem.swift | 14 +- .../ChatBotStartInputPanelNode.swift | 2 +- .../ChatButtonKeyboardInputNode.swift | 4 +- .../ChatChannelSubscriberInputPanelNode.swift | 2 +- .../ChatContextResultPeekContentNode.swift | 10 +- .../TelegramUI/ChatController.swift | 15 +- .../TelegramUI/ChatControllerNode.swift | 7 +- .../TelegramUI/ChatDocumentGalleryItem.swift | 14 +- .../ChatExternalFileGalleryItem.swift | 14 +- .../TelegramUI/ChatHistoryEntry.swift | 1 + .../TelegramUI/ChatHistoryGridNode.swift | 10 +- .../TelegramUI/ChatHistoryListNode.swift | 10 +- .../ChatHistorySearchContainerNode.swift | 9 +- .../TelegramUI/ChatImageGalleryItem.swift | 14 +- .../TelegramUI/TelegramUI/ChatInfo.swift | 2 +- .../ChatInputContextPanelNode.swift | 4 +- .../TelegramUI/ChatInputPanelNode.swift | 2 +- .../ChatInterfaceInputContextPanels.swift | 4 +- .../ChatInterfaceInputContexts.swift | 2 +- .../TelegramUI/ChatInterfaceInputNodes.swift | 2 +- .../TelegramUI/ChatInterfaceState.swift | 1 + .../ChatInterfaceStateAccessoryPanels.swift | 2 +- .../ChatInterfaceStateContextMenus.swift | 4 +- .../ChatInterfaceStateContextQueries.swift | 9 +- .../ChatInterfaceStateInputPanels.swift | 2 +- .../ChatInterfaceTitlePanelNodes.swift | 2 +- .../ChatItemGalleryFooterContentNode.swift | 23 +- .../TelegramUI/ChatListBadgeNode.swift | 6 +- .../TelegramUI/ChatListController.swift | 14 +- .../TelegramUI/ChatListControllerNode.swift | 6 +- .../TelegramUI/TelegramUI/ChatListItem.swift | 7 +- .../TelegramUI/TelegramUI/ChatListNode.swift | 10 +- .../TelegramUI/ChatListNodeEntries.swift | 1 + .../ChatListSearchContainerNode.swift | 13 +- .../ChatListSearchRecentPeersNode.swift | 1 + .../TelegramUI/ChatListStatusNode.swift | 6 +- .../TelegramUI/ChatListTitleProxyNode.swift | 1 + .../TelegramUI/ChatListTitleView.swift | 5 +- .../TelegramUI/ChatListViewTransition.swift | 1 + .../TelegramUI/ChatLoadingNode.swift | 1 + .../ChatMediaInputGridEntries.swift | 1 + .../TelegramUI/ChatMediaInputNode.swift | 5 +- .../ChatMediaInputPanelEntries.swift | 1 + .../ChatMediaInputTrendingPane.swift | 5 +- .../ChatMessageActionButtonsNode.swift | 4 +- .../ChatMessageActionItemNode.swift | 13 +- .../ChatMessageActionUrlAuthController.swift | 4 +- .../ChatMessageAnimatedStickerItemNode.swift | 1 + .../ChatMessageAttachedContentNode.swift | 17 +- .../ChatMessageAvatarAccessoryItem.swift | 4 +- .../TelegramUI/ChatMessageBackground.swift | 1 + .../ChatMessageBubbleContentNode.swift | 4 +- .../ChatMessageBubbleItemNode.swift | 9 +- .../ChatMessageDateAndStatusNode.swift | 4 +- .../ChatMessageForwardInfoNode.swift | 4 +- .../ChatMessageInstantVideoItemNode.swift | 1 + .../ChatMessageInteractiveFileNode.swift | 10 +- .../ChatMessageInteractiveMediaBadge.swift | 1 + .../ChatMessageInteractiveMediaNode.swift | 9 +- .../TelegramUI/ChatMessageItem.swift | 4 +- .../TelegramUI/ChatMessageItemView.swift | 8 +- .../ChatMessageLiveLocationPositionNode.swift | 2 +- .../ChatMessageLiveLocationTextNode.swift | 4 +- .../ChatMessageLiveLocationTimerNode.swift | 4 +- .../ChatMessageNotificationItem.swift | 4 +- .../ChatMessagePollBubbleContentNode.swift | 15 +- .../TelegramUI/ChatMessageReplyInfoNode.swift | 2 +- .../TelegramUI/ChatMessageSelectionNode.swift | 1 + .../ChatMessageStickerItemNode.swift | 1 + .../ChatMessageTextBubbleContentNode.swift | 17 +- .../ChatMessageWebpageBubbleContentNode.swift | 1 + .../TelegramUI/ChatOverlayNavigationBar.swift | 2 +- .../ChatPinnedMessageTitlePanelNode.swift | 6 +- .../TelegramUI/ChatPresentationData.swift | 27 -- .../ChatRecentActionsController.swift | 4 +- .../ChatRecentActionsControllerNode.swift | 4 +- .../ChatRecentActionsEmptyNode.swift | 2 +- .../ChatRecentActionsFilterController.swift | 3 +- .../ChatRecentActionsHistoryTransition.swift | 5 +- .../ChatRecordingPreviewInputPanelNode.swift | 2 +- ...hatRecordingVideoActivityContentNode.swift | 2 +- .../ChatReportPeerTitlePanelNode.swift | 2 +- .../TelegramUI/ChatSearchInputPanelNode.swift | 1 + ...ChatSecretAutoremoveTimerActionSheet.swift | 2 +- ...ChatSendMessageActionSheetController.swift | 4 +- ...SendMessageActionSheetControllerNode.swift | 16 +- .../TelegramUI/ChatSlowmodeItem.swift | 5 +- .../TelegramUI/ChatTextFormat.swift | 76 ++++++ .../ChatTextInputActionButtonsNode.swift | 6 +- ...TextInputAudioRecordingOverlayButton.swift | 2 +- .../TelegramUI/ChatTextInputMenu.swift | 2 +- .../TelegramUI/ChatTextInputPanelNode.swift | 11 +- ...ChatTextInputSlowmodePlaceholderNode.swift | 4 +- .../ChatTextLinkEditController.swift | 4 +- .../ChatTitleActivityContentNode.swift | 2 +- .../TelegramUI/TelegramUI/ChatTitleView.swift | 3 +- .../ChatUnblockInputPanelNode.swift | 2 +- .../TelegramUI/ChatUnreadItem.swift | 1 + .../ChatUploadingActivityContentNode.swift | 2 +- .../TelegramUI/CheckDiskSpace.swift | 2 +- .../CommandChatInputContextPanelNode.swift | 11 +- .../TelegramUI/ComposeController.swift | 4 +- .../TelegramUI/ComposeControllerNode.swift | 4 +- .../ConfirmPhoneNumberController.swift | 5 +- .../TelegramUI/ContactListNode.swift | 6 +- .../ContactMultiselectionController.swift | 5 +- .../ContactMultiselectionControllerNode.swift | 7 +- .../ContactSelectionController.swift | 5 +- .../ContactSelectionControllerNode.swift | 6 +- .../TelegramUI/ContactsController.swift | 4 +- .../TelegramUI/ContactsControllerNode.swift | 4 +- .../TelegramUI/ContactsPeerItem.swift | 2 + .../ContactsSearchContainerNode.swift | 5 +- .../ConvertToSupergroupController.swift | 3 +- .../CounterContollerTitleView.swift | 2 +- .../TelegramUI/CreateChannelController.swift | 5 +- .../TelegramUI/CreateGroupController.swift | 5 +- .../TelegramUI/CreatePasswordController.swift | 3 +- .../TelegramUI/CreatePollController.swift | 3 +- .../CreatePollOptionActionItem.swift | 1 + .../TelegramUI/CreatePollOptionItem.swift | 5 +- .../TelegramUI/CustomWallpaperPicker.swift | 6 +- .../DataAndStorageSettingsController.swift | 3 +- .../DataPrivacySettingsController.swift | 3 +- .../DateSelectionActionSheetController.swift | 2 +- .../TelegramUI/DebugAccountsController.swift | 7 +- .../TelegramUI/DebugController.swift | 9 +- .../DeleteChatPeerActionSheetItem.swift | 6 +- .../DeviceContactInfoController.swift | 7 +- ...textResultsChatInputContextPanelNode.swift | 2 +- .../DocumentPreviewController.swift | 6 +- .../TelegramUI/EditAccessoryPanelNode.swift | 7 +- .../TelegramUI/EditSettingsController.swift | 9 +- .../TelegramUI/EditableTokenListNode.swift | 2 +- .../TelegramUI/EmojiResources.swift | 2 +- .../EmojisChatInputContextPanelNode.swift | 3 +- .../FeaturedStickerPacksController.swift | 3 +- .../FetchCachedRepresentations.swift | 2 +- .../TelegramUI/FetchMediaUtils.swift | 10 +- .../FetchPhotoLibraryImageResource.swift | 2 +- .../TelegramUI/FileMediaResourceStatus.swift | 6 +- .../TelegramUI/FormControllerItem.swift | 1 + .../TelegramUI/FormControllerNode.swift | 2 +- .../FormEditableBlockItemNode.swift | 3 +- .../ForwardAccessoryPanelNode.swift | 4 +- .../ForwardPrivacyChatPreviewItem.swift | 5 +- .../TelegramUI/GalleryController.swift | 7 +- .../TelegramUI/GalleryControllerNode.swift | 8 +- .../GalleryNavigationCheckNode.swift | 1 + .../GalleryThumbnailContainerNode.swift | 2 +- .../TelegramUI/GameController.swift | 4 +- .../TelegramUI/GameControllerNode.swift | 6 +- .../TelegramUI/GifPaneSearchContentNode.swift | 4 +- .../TelegramUI/TelegramUI/GridHoleItem.swift | 2 +- .../TelegramUI/GridMessageItem.swift | 8 +- .../TelegramUI/GridMessageSelectionNode.swift | 1 + .../TelegramUI/GroupInfoController.swift | 17 +- .../TelegramUI/GroupInfoSearchItem.swift | 7 +- ...GroupInfoSearchNavigationContentNode.swift | 1 + .../GroupPreHistorySetupController.swift | 3 +- .../GroupStickerPackCurrentItem.swift | 2 + .../GroupStickerPackSetupController.swift | 3 +- .../TelegramUI/GroupsInCommonController.swift | 3 +- .../HashtagChatInputContextPanelNode.swift | 11 +- .../TelegramUI/HashtagSearchController.swift | 4 +- .../HashtagSearchControllerNode.swift | 4 +- ...textResultsChatInputContextPanelNode.swift | 3 +- ...ListContextResultsChatInputPanelItem.swift | 12 +- ...rizontalStickersChatContextPanelNode.swift | 3 +- .../TelegramUI/ICloudResources.swift | 4 +- .../TelegramUI/InChatPrefetchManager.swift | 4 +- .../InstalledStickerPacksController.swift | 6 +- .../TelegramUI/InstantImageGalleryItem.swift | 14 +- .../TelegramUI/InstantPageAnchorItem.swift | 2 +- .../TelegramUI/InstantPageArticleItem.swift | 2 +- .../TelegramUI/InstantPageArticleNode.swift | 2 +- .../TelegramUI/InstantPageAudioItem.swift | 2 +- .../TelegramUI/InstantPageAudioNode.swift | 4 +- .../TelegramUI/InstantPageContentNode.swift | 4 +- .../TelegramUI/InstantPageController.swift | 4 +- .../InstantPageControllerNode.swift | 6 +- .../TelegramUI/InstantPageDetailsItem.swift | 2 +- .../TelegramUI/InstantPageDetailsNode.swift | 6 +- .../TelegramUI/InstantPageFeedbackItem.swift | 2 +- .../TelegramUI/InstantPageFeedbackNode.swift | 4 +- .../InstantPageGalleryController.swift | 6 +- .../InstantPageGalleryFooterContentNode.swift | 13 +- .../TelegramUI/InstantPageImageItem.swift | 2 +- .../TelegramUI/InstantPageImageNode.swift | 4 +- .../TelegramUI/InstantPageItem.swift | 2 +- .../InstantPagePeerReferenceItem.swift | 2 +- .../InstantPagePeerReferenceNode.swift | 5 +- .../InstantPagePlayableVideoItem.swift | 2 +- .../InstantPagePlayableVideoNode.swift | 4 +- .../InstantPageReferenceController.swift | 4 +- .../InstantPageReferenceControllerNode.swift | 4 +- .../InstantPageSettingsItemNode.swift | 2 +- .../TelegramUI/InstantPageShapeItem.swift | 2 +- .../TelegramUI/InstantPageSlideshowItem.swift | 2 +- .../InstantPageSlideshowItemNode.swift | 6 +- .../TelegramUI/InstantPageTableItem.swift | 4 +- .../TelegramUI/InstantPageTextItem.swift | 37 +-- .../InstantPageTextStyleStack.swift | 48 ++-- .../TelegramUI/InstantPageWebEmbedItem.swift | 2 +- .../InstantVideoRadialStatusNode.swift | 2 +- .../TelegramUI/InviteContactsController.swift | 4 +- .../InviteContactsControllerNode.swift | 6 +- .../TelegramUI/ItemListAddressItem.swift | 3 + .../ItemListAvatarAndNameItem.swift | 2 + .../TelegramUI/ItemListCallListItem.swift | 1 + .../TelegramUI/ItemListInfoItem.swift | 10 +- .../TelegramUI/ItemListPeerActionItem.swift | 1 + .../TelegramUI/ItemListPeerItem.swift | 1 + .../TelegramUI/ItemListPlaceholderItem.swift | 1 + .../ItemListRecentSessionItem.swift | 1 + .../ItemListSecretChatKeyItem.swift | 1 + .../ItemListSectionHeaderItem.swift | 4 +- .../ItemListSingleLineInputItem.swift | 7 +- .../TelegramUI/ItemListStickerPackItem.swift | 1 + .../ItemListTextEmptyStateItem.swift | 1 + .../TelegramUI/ItemListWebsiteItem.swift | 1 + .../JoinLinkPreviewController.swift | 4 +- .../JoinLinkPreviewControllerNode.swift | 8 +- .../JoinLinkPreviewPeerContentNode.swift | 2 +- .../LanguageLinkPreviewContentNode.swift | 9 +- .../LanguageLinkPreviewController.swift | 4 +- .../LanguageLinkPreviewControllerNode.swift | 9 +- .../LanguageSuggestionController.swift | 3 +- .../TelegramUI/LegacyAttachmentMenu.swift | 4 +- .../TelegramUI/TelegramUI/LegacyCamera.swift | 4 +- .../TelegramUI/LegacyControllerNode.swift | 2 +- .../TelegramUI/LegacyImagePicker.swift | 2 +- .../LegacyInstantVideoController.swift | 4 +- .../TelegramUI/LegacyLocationController.swift | 2 +- .../TelegramUI/LegacyLocationPicker.swift | 2 +- .../TelegramUI/LegacyMediaPickers.swift | 10 +- .../LegacySecureIdAttachmentMenu.swift | 2 +- .../TelegramUI/LegacyWallpaperPicker.swift | 2 +- .../TelegramUI/LegacyWebSearchEditor.swift | 2 +- .../TelegramUI/LegacyWebSearchGallery.swift | 2 +- .../TelegramUI/ListMessageDateHeader.swift | 2 +- .../TelegramUI/ListMessageFileItemNode.swift | 3 +- .../TelegramUI/ListMessageHoleItem.swift | 2 +- .../TelegramUI/ListMessageItem.swift | 4 +- .../ListMessagePlaybackOverlayNode.swift | 2 +- .../ListMessageSnippetItemNode.swift | 12 +- .../LocalizationListController.swift | 4 +- .../LocalizationListControllerNode.swift | 8 +- .../TelegramUI/LocalizationListItem.swift | 2 + .../LocationBroadcastActionSheetItem.swift | 4 +- ...ionBroadcastNavigationAccessoryPanel.swift | 3 +- .../LocationBroadcastPanelWavesNode.swift | 2 +- .../TelegramUI/LogoutOptionsController.swift | 3 +- .../TelegramUI/ManagedAudioRecorder.swift | 4 +- .../TelegramUI/MapResourceToAvatarSizes.swift | 2 +- .../TelegramUI/TelegramUI/MapResources.swift | 6 +- .../TelegramUI/TelegramUI/MediaManager.swift | 1 + ...ediaNavigationAccessoryContainerNode.swift | 2 +- .../MediaNavigationAccessoryHeaderNode.swift | 6 +- .../MediaNavigationAccessoryPanel.swift | 2 +- .../MentionChatInputContextPanelNode.swift | 4 +- .../TelegramUI/ModernCheckNode.swift | 2 +- .../TelegramUI/MultipleAvatarsNode.swift | 2 +- .../TelegramUI/MultiplexedVideoNode.swift | 10 +- .../TelegramUI/NavigateToChatController.swift | 2 +- .../NavigationBarSearchContentNode.swift | 2 +- .../NetworkUsageStatsController.swift | 3 +- .../NotificationContainerController.swift | 2 +- .../NotificationContentContext.swift | 5 +- .../NotificationExceptionControllerNode.swift | 8 +- ...ificationExceptionSettingsController.swift | 3 +- .../TelegramUI/NotificationExceptions.swift | 4 +- .../NotificationItemContainerNode.swift | 4 +- .../TelegramUI/NotificationSearchItem.swift | 1 + .../NotificationSoundSelection.swift | 5 +- .../TelegramUI/NotificationsAndSounds.swift | 9 +- .../TelegramUI/OpenAddContact.swift | 2 +- .../TelegramUI/OpenChatMessage.swift | 15 +- .../OpenInActionSheetController.swift | 10 +- .../TelegramUI/TelegramUI/OpenInOptions.swift | 4 +- .../TelegramUI/OpenResolvedUrl.swift | 2 +- .../TelegramUI/TelegramUI/OpenSettings.swift | 2 +- .../TelegramUI/TelegramUI/OpenUrl.swift | 3 +- .../TelegramUI/OverlayPlayerController.swift | 4 +- .../OverlayPlayerControllerNode.swift | 8 +- .../OverlayPlayerControlsNode.swift | 4 +- .../TelegramUI/PaneSearchBarNode.swift | 9 +- .../TelegramUI/PaneSearchContainerNode.swift | 4 +- .../TelegramUI/PasscodeEntryController.swift | 4 +- .../PasscodeEntryControllerNode.swift | 12 +- .../PasscodeEntryInputFieldNode.swift | 8 +- .../PasscodeEntryKeyboardNode.swift | 4 +- .../TelegramUI/PasscodeLockIconNode.swift | 4 +- .../PasscodeOptionsController.swift | 7 +- .../TelegramUI/PasscodeSetupController.swift | 4 +- .../TelegramUI/TelegramUI/Pasteboard.swift | 1 + .../PeerAvatarImageGalleryItem.swift | 14 +- .../TelegramUI/PeerBanTimeoutController.swift | 2 +- .../TelegramUI/PeerInfoController.swift | 2 +- .../PeerMediaCollectionController.swift | 4 +- .../PeerMediaCollectionControllerNode.swift | 6 +- .../PeerMediaCollectionEmptyNode.swift | 1 + .../TelegramUI/PeerReportController.swift | 5 +- .../TelegramUI/PeerSelectionController.swift | 5 +- .../PeerSelectionControllerNode.swift | 6 +- .../TelegramUI/PeersNearbyController.swift | 7 +- .../TelegramUI/PeersNearbyHeaderItem.swift | 1 + .../TelegramUI/PeersNearbyIconNode.swift | 2 +- .../TelegramUI/TelegramUI/Permission.swift | 2 +- .../TelegramUI/PermissionContentNode.swift | 1 + .../TelegramUI/PermissionController.swift | 4 +- .../TelegramUI/PermissionControllerNode.swift | 6 +- .../TelegramUI/PhoneLabelController.swift | 3 +- .../TelegramUI/PhotoResources.swift | 40 +-- .../TelegramUI/PrefetchManager.swift | 4 +- .../PrepareSecretThumbnailData.swift | 2 +- .../PreparedChatHistoryViewTransition.swift | 1 + .../PrivacyAndSecurityController.swift | 5 +- .../TelegramUI/PrivacyIntroController.swift | 4 +- .../PrivacyIntroControllerNode.swift | 6 +- .../ProxyListSettingsController.swift | 3 +- .../ProxyServerActionSheetController.swift | 3 +- .../ProxyServerSettingsController.swift | 3 +- .../TelegramUI/ProxySettingsActionItem.swift | 1 + .../TelegramUI/ProxySettingsServerItem.swift | 2 + .../TelegramUI/RadialCheckContentNode.swift | 2 +- .../RadialCloudProgressContentNode.swift | 8 +- .../RadialDownloadContentNode.swift | 16 +- .../RadialProgressContentNode.swift | 6 +- .../TelegramUI/RadialProgressNode.swift | 6 +- ...RadialStatusSecretTimeoutContentNode.swift | 2 +- .../TelegramUI/RadialTimeoutNode.swift | 2 +- .../TelegramUI/RecentSessionsController.swift | 3 +- .../RecentSessionsEmptyStateItem.swift | 1 + .../TelegramUI/ReplyAccessoryPanelNode.swift | 4 +- .../TelegramUI/ResetPasswordController.swift | 3 +- .../SaveIncomingMediaController.swift | 3 +- .../TelegramUI/SaveToCameraRoll.swift | 6 +- .../TelegramUI/ScreenCaptureDetection.swift | 2 +- .../TelegramUI/TelegramUI/SearchBarNode.swift | 13 +- .../TelegramUI/SearchBarPlaceholderNode.swift | 4 +- .../TelegramUI/SearchDisplayController.swift | 2 +- .../TelegramUI/SearchPeerMembers.swift | 2 +- .../TelegramUI/SecretChatKeyController.swift | 4 +- .../SecretChatKeyControllerNode.swift | 9 +- .../SecretMediaPreviewController.swift | 4 +- .../TelegramUI/SecureIdAuthController.swift | 6 +- .../SecureIdAuthControllerNode.swift | 7 +- .../SecureIdAuthFormContentNode.swift | 15 +- .../SecureIdAuthFormFieldNode.swift | 4 +- .../SecureIdAuthListFieldNode.swift | 2 +- ...ecureIdAuthPasswordOptionContentNode.swift | 1 + .../SecureIdDocumentFormController.swift | 5 +- .../SecureIdDocumentFormControllerNode.swift | 4 +- .../SecureIdDocumentGalleryController.swift | 6 +- ...reIdDocumentGalleryFooterContentNode.swift | 4 +- .../SecureIdDocumentImageGalleryItem.swift | 10 +- ...ureIdDocumentTypeSelectionController.swift | 2 +- .../TelegramUI/SecureIdLocalResource.swift | 2 +- .../SecureIdPlaintextFormController.swift | 5 +- .../SecureIdPlaintextFormControllerNode.swift | 4 +- .../SecureIdValueFormFileItem.swift | 1 + .../SelectivePrivacySettingsController.swift | 7 +- ...ectivePrivacySettingsPeersController.swift | 3 +- .../TelegramUI/SettingsController.swift | 21 +- .../TelegramUI/SettingsSearchItem.swift | 12 +- .../TelegramUI/SettingsSearchRecentItem.swift | 1 + .../TelegramUI/SettingsSearchResultItem.swift | 1 + .../TelegramUI/SettingsSearchableItems.swift | 44 ++-- .../SettingsThemeWallpaperNode.swift | 2 +- .../SetupTwoStepVerificationController.swift | 5 +- ...tupTwoStepVerificationControllerNode.swift | 7 +- .../TelegramUI/ShareController.swift | 21 +- .../TelegramUI/ShareControllerNode.swift | 8 +- .../TelegramUI/ShareExtensionContext.swift | 19 +- .../TelegramUI/ShareInputFieldNode.swift | 2 +- .../TelegramUI/TelegramUI/ShareItems.swift | 6 +- .../ShareLoadingContainerNode.swift | 1 + .../TelegramUI/SharePeersContainerNode.swift | 5 +- .../TelegramUI/ShareSearchBarNode.swift | 2 +- .../TelegramUI/ShareSearchContainerNode.swift | 5 +- .../TelegramUI/SharedAccountContext.swift | 20 +- .../SharedNotificationManager.swift | 2 +- .../SoftwareVideoThumbnailLayer.swift | 2 +- .../TelegramUI/SolidRoundedButtonNode.swift | 2 +- .../StickerPackPreviewController.swift | 4 +- .../StickerPackPreviewControllerNode.swift | 13 +- .../StickerPaneSearchContentNode.swift | 5 +- .../TelegramUI/StickerPreviewController.swift | 4 +- .../StickerPreviewControllerNode.swift | 4 +- .../StickersChatInputContextPanelNode.swift | 19 +- .../TelegramUI/StorageUsageController.swift | 3 +- .../TelegramUI/SuppressContactsWarning.swift | 2 +- .../TelegramUI/SystemVideoContent.swift | 4 +- .../TabBarAccountSwitchController.swift | 4 +- .../TabBarAccountSwitchControllerNode.swift | 8 +- ...pLongTapOrDoubleTapGestureRecognizer.swift | 6 +- .../TelegramUI/TelegramController.swift | 10 +- .../TelegramInitializeLegacyComponents.swift | 10 +- .../TelegramUI/TelegramRootController.swift | 4 +- .../TelegramUI/TermsOfServiceController.swift | 1 + .../TermsOfServiceControllerNode.swift | 27 +- .../TelegramUI/TextLinkHandling.swift | 3 +- .../TelegramUI/TelegramUI/TextNode.swift | 39 --- .../ThemeAccentColorActionSheet.swift | 2 +- .../ThemeAutoNightSettingsController.swift | 3 +- ...emeAutoNightTimeSelectionActionSheet.swift | 2 +- .../ThemeColorsGridController.swift | 4 +- .../ThemeColorsGridControllerItem.swift | 8 +- .../ThemeColorsGridControllerNode.swift | 10 +- .../TelegramUI/ThemeGridController.swift | 4 +- .../TelegramUI/ThemeGridControllerItem.swift | 8 +- .../TelegramUI/ThemeGridControllerNode.swift | 10 +- .../ThemeGridSearchContentNode.swift | 5 +- .../TelegramUI/ThemePreviewController.swift | 4 +- .../ThemePreviewControllerNode.swift | 6 +- .../ThemeSettingsAccentColorItem.swift | 3 +- .../TelegramUI/ThemeSettingsAppIconItem.swift | 3 +- .../ThemeSettingsBrightnessItem.swift | 1 + .../ThemeSettingsChatPreviewItem.swift | 5 +- .../ThemeSettingsColorSliderNode.swift | 2 +- .../TelegramUI/ThemeSettingsController.swift | 9 +- .../ThemeSettingsFontSizeItem.swift | 1 + .../TelegramUI/ThemeSettingsThemeItem.swift | 3 +- .../ThemedTextAlertController.swift | 4 +- .../TransformOutgoingMessageMedia.swift | 4 +- ...pVerificationPasswordEntryController.swift | 3 +- .../TwoStepVerificationResetController.swift | 4 +- .../TwoStepVerificationUnlockController.swift | 4 +- .../TelegramUI/UndoOverlayController.swift | 4 +- .../UndoOverlayControllerNode.swift | 6 +- .../UniversalVideoGalleryItem.swift | 12 +- .../TelegramUI/UserInfoController.swift | 11 +- .../UserInfoEditingPhoneActionItem.swift | 1 + .../TelegramUI/UserInfoEditingPhoneItem.swift | 1 + .../TelegramUI/UsernameSetupController.swift | 5 +- ...textResultsChatInputContextPanelNode.swift | 3 +- .../VoiceCallDataSavingController.swift | 3 +- .../TelegramUI/WallpaperColorPickerNode.swift | 4 +- .../TelegramUI/WallpaperCropNode.swift | 2 +- .../WallpaperGalleryController.swift | 6 +- .../TelegramUI/WallpaperGalleryItem.swift | 13 +- .../WallpaperPatternPanelNode.swift | 2 +- .../TelegramUI/WallpaperResources.swift | 2 +- .../TelegramUI/WallpaperUploadManager.swift | 4 +- .../WatchCommunicationManager.swift | 2 +- .../TelegramUI/WatchRequestHandlers.swift | 8 +- .../TelegramUI/WatchSettingsController.swift | 3 +- .../TelegramUI/WebSearchBadgeNode.swift | 2 +- .../TelegramUI/WebSearchController.swift | 4 +- .../TelegramUI/WebSearchControllerNode.swift | 7 +- .../WebSearchGalleryController.swift | 6 +- .../WebSearchGalleryFooterContentNode.swift | 4 +- .../TelegramUI/TelegramUI/WebSearchItem.swift | 1 + .../TelegramUI/WebSearchRecentQueryItem.swift | 1 + .../WebSearchVideoGalleryItem.swift | 8 +- .../WebpagePreviewAccessoryPanelNode.swift | 4 +- .../project.pbxproj | 236 +++--------------- 543 files changed, 1602 insertions(+), 1686 deletions(-) create mode 100644 submodules/TelegramUI/TelegramUI/ChatTextFormat.swift diff --git a/submodules/TelegramUI/TelegramUI/Accessibility.swift b/submodules/TelegramUI/TelegramUI/Accessibility.swift index c16e7217ee..7422ccb13e 100644 --- a/submodules/TelegramUI/TelegramUI/Accessibility.swift +++ b/submodules/TelegramUI/TelegramUI/Accessibility.swift @@ -2,7 +2,7 @@ import SwiftSignalKit import UIKit func smartInvertColorsEnabled() -> Bool { - if #available(iOSApplicationExtension 11.0, iOS 11.0, *), UIAccessibilityIsInvertColorsEnabled() { + if #available(iOSApplicationExtension 11.0, iOS 11.0, *), UIAccessibility.isInvertColorsEnabled { return true } else { return false @@ -13,7 +13,7 @@ func reduceMotionEnabled() -> Signal { return Signal { subscriber in subscriber.putNext(UIAccessibility.isReduceMotionEnabled) - let observer = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIAccessibilityReduceMotionStatusDidChange, object: nil, queue: .main, using: { _ in + let observer = NotificationCenter.default.addObserver(forName: UIAccessibility.reduceMotionStatusDidChangeNotification, object: nil, queue: .main, using: { _ in subscriber.putNext(UIAccessibility.isReduceMotionEnabled) }) @@ -29,7 +29,7 @@ func boldTextEnabled() -> Signal { return Signal { subscriber in subscriber.putNext(UIAccessibility.isBoldTextEnabled) - let observer = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIAccessibilityBoldTextStatusDidChange, object: nil, queue: .main, using: { _ in + let observer = NotificationCenter.default.addObserver(forName: UIAccessibility.boldTextStatusDidChangeNotification, object: nil, queue: .main, using: { _ in subscriber.putNext(UIAccessibility.isBoldTextEnabled) }) @@ -45,7 +45,7 @@ private func checkButtonShapes() -> Bool { let button = UIButton() button.setTitle("title", for: .normal) - if let attributes = button.titleLabel?.attributedText?.attributes(at: 0, effectiveRange: nil), let _ = attributes[NSAttributedStringKey.underlineStyle] { + if let attributes = button.titleLabel?.attributedText?.attributes(at: 0, effectiveRange: nil), let _ = attributes[NSAttributedString.Key.underlineStyle] { return true } else { return false diff --git a/submodules/TelegramUI/TelegramUI/AccountContext.swift b/submodules/TelegramUI/TelegramUI/AccountContext.swift index cfd6b6b6b5..3dfb00eada 100644 --- a/submodules/TelegramUI/TelegramUI/AccountContext.swift +++ b/submodules/TelegramUI/TelegramUI/AccountContext.swift @@ -6,14 +6,7 @@ import TelegramCore import Display import DeviceAccess import TelegramPresentationData - -public final class TelegramApplicationOpenUrlCompletion { - public let completion: (Bool) -> Void - - public init(completion: @escaping (Bool) -> Void) { - self.completion = completion - } -} +import AccountContext private final class DeviceSpecificContactImportContext { let disposable = MetaDisposable() @@ -100,60 +93,11 @@ private final class DeviceSpecificContactImportContexts { } } -public final class TelegramApplicationBindings { - public let isMainApp: Bool - public let containerPath: String - public let appSpecificScheme: String - public let openUrl: (String) -> Void - public let openUniversalUrl: (String, TelegramApplicationOpenUrlCompletion) -> Void - public let canOpenUrl: (String) -> Bool - public let getTopWindow: () -> UIWindow? - public let displayNotification: (String) -> Void - public let applicationInForeground: Signal - public let applicationIsActive: Signal - public let clearMessageNotifications: ([MessageId]) -> Void - public let pushIdleTimerExtension: () -> Disposable - public let openSettings: () -> Void - public let openAppStorePage: () -> Void - public let registerForNotifications: (@escaping (Bool) -> Void) -> Void - public let requestSiriAuthorization: (@escaping (Bool) -> Void) -> Void - public let siriAuthorization: () -> AccessType - public let getWindowHost: () -> WindowHost? - public let presentNativeController: (UIViewController) -> Void - public let dismissNativeController: () -> Void - public let getAvailableAlternateIcons: () -> [PresentationAppIcon] - public let getAlternateIconName: () -> String? - public let requestSetAlternateIconName: (String?, @escaping (Bool) -> Void) -> Void - - public init(isMainApp: Bool, containerPath: String, appSpecificScheme: String, openUrl: @escaping (String) -> Void, openUniversalUrl: @escaping (String, TelegramApplicationOpenUrlCompletion) -> Void, canOpenUrl: @escaping (String) -> Bool, getTopWindow: @escaping () -> UIWindow?, displayNotification: @escaping (String) -> Void, applicationInForeground: Signal, applicationIsActive: Signal, clearMessageNotifications: @escaping ([MessageId]) -> Void, pushIdleTimerExtension: @escaping () -> Disposable, openSettings: @escaping () -> Void, openAppStorePage: @escaping () -> Void, registerForNotifications: @escaping (@escaping (Bool) -> Void) -> Void, requestSiriAuthorization: @escaping (@escaping (Bool) -> Void) -> Void, siriAuthorization: @escaping () -> AccessType, getWindowHost: @escaping () -> WindowHost?, presentNativeController: @escaping (UIViewController) -> Void, dismissNativeController: @escaping () -> Void, getAvailableAlternateIcons: @escaping () -> [PresentationAppIcon], getAlternateIconName: @escaping () -> String?, requestSetAlternateIconName: @escaping (String?, @escaping (Bool) -> Void) -> Void) { - self.isMainApp = isMainApp - self.containerPath = containerPath - self.appSpecificScheme = appSpecificScheme - self.openUrl = openUrl - self.openUniversalUrl = openUniversalUrl - self.canOpenUrl = canOpenUrl - self.getTopWindow = getTopWindow - self.displayNotification = displayNotification - self.applicationInForeground = applicationInForeground - self.applicationIsActive = applicationIsActive - self.clearMessageNotifications = clearMessageNotifications - self.pushIdleTimerExtension = pushIdleTimerExtension - self.openSettings = openSettings - self.openAppStorePage = openAppStorePage - self.registerForNotifications = registerForNotifications - self.requestSiriAuthorization = requestSiriAuthorization - self.siriAuthorization = siriAuthorization - self.presentNativeController = presentNativeController - self.dismissNativeController = dismissNativeController - self.getWindowHost = getWindowHost - self.getAvailableAlternateIcons = getAvailableAlternateIcons - self.getAlternateIconName = getAlternateIconName - self.requestSetAlternateIconName = requestSetAlternateIconName +public final class AccountContextImpl: AccountContext { + public let sharedContext: SharedAccountContextImpl + public var genericSharedContext: SharedAccountContext { + return self.sharedContext } -} - -public final class AccountContext { - public let sharedContext: SharedAccountContext public let account: Account public let fetchManager: FetchManager @@ -182,7 +126,7 @@ public final class AccountContext { private let deviceSpecificContactImportContexts: QueueLocalObject private var managedAppSpecificContactsDisposable: Disposable? - public init(sharedContext: SharedAccountContext, account: Account, limitsConfiguration: LimitsConfiguration) { + public init(sharedContext: SharedAccountContextImpl, account: Account, limitsConfiguration: LimitsConfiguration) { self.sharedContext = sharedContext self.account = account diff --git a/submodules/TelegramUI/TelegramUI/AccountUtils.swift b/submodules/TelegramUI/TelegramUI/AccountUtils.swift index 1b304eb172..613e280f19 100644 --- a/submodules/TelegramUI/TelegramUI/AccountUtils.swift +++ b/submodules/TelegramUI/TelegramUI/AccountUtils.swift @@ -4,7 +4,7 @@ import Postbox import TelegramCore import TelegramUIPreferences -func activeAccountsAndPeers(context: AccountContext) -> Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError> { +func activeAccountsAndPeers(context: AccountContextImpl) -> Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError> { let sharedContext = context.sharedContext return context.sharedContext.activeAccounts |> mapToSignal { primary, activeAccounts, _ -> Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError> in diff --git a/submodules/TelegramUI/TelegramUI/AddFormatToStringWithRanges.swift b/submodules/TelegramUI/TelegramUI/AddFormatToStringWithRanges.swift index 5688ff6c2a..bce3a6d409 100644 --- a/submodules/TelegramUI/TelegramUI/AddFormatToStringWithRanges.swift +++ b/submodules/TelegramUI/TelegramUI/AddFormatToStringWithRanges.swift @@ -1,13 +1,14 @@ import Foundation import UIKit +import TextFormat func addAttributesToStringWithRanges(_ stringWithRanges: (String, [(Int, NSRange)]), body: MarkdownAttributeSet, argumentAttributes: [Int: MarkdownAttributeSet], textAlignment: NSTextAlignment = .natural) -> NSAttributedString { let result = NSMutableAttributedString() - var bodyAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: body.font, NSAttributedStringKey.foregroundColor: body.textColor, NSAttributedStringKey.paragraphStyle: paragraphStyleWithAlignment(textAlignment)] + var bodyAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: body.font, NSAttributedString.Key.foregroundColor: body.textColor, NSAttributedString.Key.paragraphStyle: paragraphStyleWithAlignment(textAlignment)] if !body.additionalAttributes.isEmpty { for (key, value) in body.additionalAttributes { - bodyAttributes[NSAttributedStringKey(rawValue: key)] = value + bodyAttributes[NSAttributedString.Key(rawValue: key)] = value } } @@ -15,10 +16,10 @@ func addAttributesToStringWithRanges(_ stringWithRanges: (String, [(Int, NSRange for (index, range) in stringWithRanges.1 { if let attributes = argumentAttributes[index] { - var argumentAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: attributes.font, NSAttributedStringKey.foregroundColor: attributes.textColor, NSAttributedStringKey.paragraphStyle: paragraphStyleWithAlignment(textAlignment)] + var argumentAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: attributes.font, NSAttributedString.Key.foregroundColor: attributes.textColor, NSAttributedString.Key.paragraphStyle: paragraphStyleWithAlignment(textAlignment)] if !attributes.additionalAttributes.isEmpty { for (key, value) in attributes.additionalAttributes { - argumentAttributes[NSAttributedStringKey(rawValue: key)] = value + argumentAttributes[NSAttributedString.Key(rawValue: key)] = value } } result.addAttributes(argumentAttributes, range: range) diff --git a/submodules/TelegramUI/TelegramUI/AppDelegate.swift b/submodules/TelegramUI/TelegramUI/AppDelegate.swift index 799a63c299..f1259e2f48 100644 --- a/submodules/TelegramUI/TelegramUI/AppDelegate.swift +++ b/submodules/TelegramUI/TelegramUI/AppDelegate.swift @@ -15,6 +15,7 @@ import TelegramCallsUI import TelegramVoip import BuildConfig import DeviceCheck +import AccountContext private let handleVoipNotifications = false @@ -135,12 +136,12 @@ private enum QueuedWakeup: Int32 { } final class SharedApplicationContext { - let sharedContext: SharedAccountContext + let sharedContext: SharedAccountContextImpl let notificationManager: SharedNotificationManager let wakeupManager: SharedWakeupManager let overlayMediaController: OverlayMediaController - init(sharedContext: SharedAccountContext, notificationManager: SharedNotificationManager, wakeupManager: SharedWakeupManager) { + init(sharedContext: SharedAccountContextImpl, notificationManager: SharedNotificationManager, wakeupManager: SharedWakeupManager) { self.sharedContext = sharedContext self.notificationManager = notificationManager self.wakeupManager = wakeupManager @@ -215,7 +216,7 @@ final class SharedApplicationContext { private let deviceToken = Promise(nil) - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { precondition(!testIsLaunched) testIsLaunched = true @@ -464,11 +465,11 @@ final class SharedApplicationContext { } if let parsedUrl = parsedUrl { - return UIApplication.shared.open(parsedUrl, options: [UIApplicationOpenURLOptionUniversalLinksOnly: true as NSNumber], completionHandler: { value in + return UIApplication.shared.open(parsedUrl, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly: true as NSNumber], completionHandler: { value in completion.completion(value) }) } else if let escapedUrl = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let parsedUrl = URL(string: escapedUrl) { - return UIApplication.shared.open(parsedUrl, options: [UIApplicationOpenURLOptionUniversalLinksOnly: true as NSNumber], completionHandler: { value in + return UIApplication.shared.open(parsedUrl, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly: true as NSNumber], completionHandler: { value in completion.completion(value) }) } else { @@ -527,7 +528,7 @@ final class SharedApplicationContext { return disposable }, openSettings: { - if let url = URL(string: UIApplicationOpenSettingsURLString) { + if let url = URL(string: UIApplication.openSettingsURLString) { UIApplication.shared.openURL(url) } }, openAppStorePage: { @@ -651,7 +652,7 @@ final class SharedApplicationContext { let legacyCache = LegacyCache(path: legacyBasePath + "/Caches") var setPresentationCall: ((PresentationCall?) -> Void)? - let sharedContext = SharedAccountContext(mainWindow: self.mainWindow, basePath: rootPath, encryptionParameters: encryptionParameters, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings, networkArguments: networkArguments, rootPath: rootPath, legacyBasePath: legacyBasePath, legacyCache: legacyCache, apsNotificationToken: self.notificationTokenPromise.get() |> map(Optional.init), voipNotificationToken: self.voipTokenPromise.get() |> map(Optional.init), setNotificationCall: { call in + let sharedContext = SharedAccountContextImpl(mainWindow: self.mainWindow, basePath: rootPath, encryptionParameters: encryptionParameters, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings, networkArguments: networkArguments, rootPath: rootPath, legacyBasePath: legacyBasePath, legacyCache: legacyCache, apsNotificationToken: self.notificationTokenPromise.get() |> map(Optional.init), voipNotificationToken: self.voipTokenPromise.get() |> map(Optional.init), setNotificationCall: { call in setPresentationCall?(call) }, navigateToChat: { accountId, peerId, messageId in self.openChatWhenReady(accountId: accountId, peerId: peerId, messageId: messageId) @@ -870,7 +871,7 @@ final class SharedApplicationContext { |> deliverOnMainQueue |> map { accountAndSettings -> AuthorizedApplicationContext? in return accountAndSettings.flatMap { account, limitsConfiguration, callListSettings in - let context = AccountContext(sharedContext: sharedApplicationContext.sharedContext, account: account, limitsConfiguration: limitsConfiguration) + let context = AccountContextImpl(sharedContext: sharedApplicationContext.sharedContext, account: account, limitsConfiguration: limitsConfiguration) return AuthorizedApplicationContext(sharedApplicationContext: sharedApplicationContext, mainWindow: self.mainWindow, watchManagerArguments: watchManagerArgumentsPromise.get(), context: context, accountManager: sharedApplicationContext.sharedContext.accountManager, showCallsTab: callListSettings.showTab, reinitializedNotificationSettings: { let _ = (self.context.get() |> take(1) @@ -1173,7 +1174,7 @@ final class SharedApplicationContext { #endif } - NotificationCenter.default.addObserver(forName: NSNotification.Name.UIWindowDidBecomeHidden, object: nil, queue: nil, using: { notification in + NotificationCenter.default.addObserver(forName: UIWindow.didBecomeHiddenNotification, object: nil, queue: nil, using: { notification in if UIApplication.shared.isStatusBarHidden { UIApplication.shared.setStatusBarHidden(false, with: .none) } @@ -1226,7 +1227,7 @@ final class SharedApplicationContext { self.isActiveValue = false self.isActivePromise.set(false) - var taskId: Int? + var taskId: UIBackgroundTaskIdentifier? taskId = application.beginBackgroundTask(withName: "lock", expirationHandler: { if let taskId = taskId { UIApplication.shared.endBackgroundTask(taskId) @@ -1594,7 +1595,7 @@ final class SharedApplicationContext { return true } - func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { + func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { self.openUrl(url: url) return true } @@ -1607,11 +1608,11 @@ final class SharedApplicationContext { private func openUrl(url: URL) { let _ = (self.sharedContextPromise.get() |> take(1) - |> mapToSignal { sharedApplicationContext -> Signal<(SharedAccountContext, AuthorizedApplicationContext?, UnauthorizedApplicationContext?), NoError> in + |> mapToSignal { sharedApplicationContext -> Signal<(SharedAccountContextImpl, AuthorizedApplicationContext?, UnauthorizedApplicationContext?), NoError> in combineLatest(self.context.get(), self.authContext.get()) |> filter { $0 != nil || $1 != nil } |> take(1) - |> map { context, authContext -> (SharedAccountContext, AuthorizedApplicationContext?, UnauthorizedApplicationContext?) in + |> map { context, authContext -> (SharedAccountContextImpl, AuthorizedApplicationContext?, UnauthorizedApplicationContext?) in return (sharedApplicationContext.sharedContext, context, authContext) } } @@ -1638,7 +1639,7 @@ final class SharedApplicationContext { }) } - func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool { + func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { if #available(iOS 10.0, *) { if let startCallIntent = userActivity.interaction?.intent as? SupportedStartCallIntent { if let contact = startCallIntent.contacts?.first { @@ -1825,7 +1826,7 @@ final class SharedApplicationContext { }) } - private func registerForNotifications(context: AccountContext, authorize: Bool = true, completion: @escaping (Bool) -> Void = { _ in }) { + private func registerForNotifications(context: AccountContextImpl, authorize: Bool = true, completion: @escaping (Bool) -> Void = { _ in }) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let _ = (context.sharedContext.accountManager.transaction { transaction -> Bool in let settings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.inAppNotificationSettings) as? InAppNotificationSettings ?? InAppNotificationSettings.defaultSettings @@ -1941,130 +1942,12 @@ final class SharedApplicationContext { muteMediaMessageCategory.identifier = "withMuteMedia" let categories = [unknownMessageCategory, replyMessageCategory, replyLegacyMessageCategory, replyLegacyMediaMessageCategory, replyMediaMessageCategory, legacyChannelMessageCategory, muteMessageCategory, muteMediaMessageCategory] - let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories:[]) + let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: []) UIApplication.shared.registerUserNotificationSettings(settings) UIApplication.shared.registerForRemoteNotifications() } } - /*private func maybeDequeueNotificationPayloads() { - if let context = self.contextValue, !self.queuedNotifications.isEmpty { - let queuedNotifications = self.queuedNotifications - self.queuedNotifications = [] - for payload in queuedNotifications { - self.processPushPayload(payload, account: context.context.account) - } - } - } - - private func maybeDequeueNotificationRequests() { - if let context = self.contextValue { - let requests = self.queuedNotificationRequests - self.queuedNotificationRequests = [] - let queuedMutePolling = self.queuedMutePolling - self.queuedMutePolling = false - - let _ = (context.context.sharedContext.accountManager.transaction(ignoreDisabled: true, { transaction -> PostboxAccessChallengeData in - return transaction.getAccessChallengeData() - }) - |> deliverOnMainQueue).start(next: { accessChallengeData in - guard let context = self.contextValue else { - Logger.shared.log("App \(self.episodeId)", "Couldn't process remote notification request") - return - } - - let strings = context.context.sharedContext.currentPresentationData.with({ $0 }).strings - - for (title, body, apnsSound, requestId) in requests { - if handleVoipNotifications { - //context.notificationManager.enqueueRemoteNotification(title: title, text: body, apnsSound: apnsSound, requestId: requestId, strings: strings, accessChallengeData: accessChallengeData) - } - - /*context.wakeupManager.wakeupForIncomingMessages(account: context.context.account, completion: { messageIds -> Signal in - if let context = self.contextValue { - if handleVoipNotifications { - return context.notificationManager.commitRemoteNotification(context: context.context, originalRequestId: requestId, messageIds: messageIds) - } else { - return context.notificationManager.commitRemoteNotification(context: context.context, originalRequestId: nil, messageIds: []) - } - } else { - Logger.shared.log("App \(self.episodeId)", "Couldn't process remote notifications wakeup result") - return .complete() - } - })*/ - } - if queuedMutePolling { - /*context.wakeupManager.wakeupForIncomingMessages(account: context.context.account, completion: { messageIds -> Signal in - if let context = self.contextValue { - return .single(Void()) - } else { - Logger.shared.log("App \(self.episodeId)", "Couldn't process remote notifications wakeup result") - return .single(Void()) - } - })*/ - } - }) - } else { - Logger.shared.log("App \(self.episodeId)", "maybeDequeueNotificationRequests failed, no active context") - } - } - - private func maybeDequeueAnnouncements() { - if let context = self.contextValue, !self.queuedAnnouncements.isEmpty { - let queuedAnnouncements = self.queuedAnnouncements - self.queuedAnnouncements = [] - let _ = (context.context.account.postbox.transaction(ignoreDisabled: true, { transaction -> [MessageId: String] in - var result: [MessageId: String] = [:] - let timestamp = Int32(context.context.account.network.globalTime) - let servicePeer = TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: 777000), accessHash: nil, firstName: "Telegram", lastName: nil, username: nil, phone: "42777", photo: [], botInfo: nil, restrictionInfo: nil, flags: [.isVerified]) - if transaction.getPeer(servicePeer.id) == nil { - transaction.updatePeersInternal([servicePeer], update: { _, updated in - return updated - }) - } - for body in queuedAnnouncements { - let globalId = arc4random64() - var attributes: [MessageAttribute] = [] - let entities = generateTextEntities(body, enabledTypes: .all) - if !entities.isEmpty { - attributes.append(TextEntitiesMessageAttribute(entities: entities)) - } - let message = StoreMessage(id: .Partial(servicePeer.id, Namespaces.Message.Local), globallyUniqueId: globalId, groupingKey: nil, timestamp: timestamp, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, authorId: servicePeer.id, text: body, attributes: attributes, media: []) - let ids = transaction.addMessages([message], location: .Random) - if let id = ids[globalId] { - result[id] = body - } - } - return result - }) |> deliverOnMainQueue).start(next: { result in - if let context = self.contextValue { - for (id, text) in result { - //context.notificationManager.enqueueRemoteNotification(title: "", text: text, apnsSound: nil, requestId: .messageId(id), strings: context.context.sharedContext.currentPresentationData.with({ $0 }).strings, accessChallengeData: .none) - } - } - }) - } - } - - private func maybeDequeueWakeups() { - for wakeup in self.queuedWakeups { - switch wakeup { - case .call: - if let context = self.contextValue { - //context.wakeupManager.wakeupForIncomingMessages(account: context.context.account) - } - case .backgroundLocation: - if UIApplication.shared.applicationState == .background { - if let context = self.contextValue { - context.context.liveLocationManager?.pollOnce() - } - } - } - } - - self.queuedWakeups.removeAll() - }*/ - @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let _ = (accountIdFromNotification(notification, sharedContext: self.sharedContextPromise.get()) diff --git a/submodules/TelegramUI/TelegramUI/ApplicationContext.swift b/submodules/TelegramUI/TelegramUI/ApplicationContext.swift index a9bc9d1e58..294e15961c 100644 --- a/submodules/TelegramUI/TelegramUI/ApplicationContext.swift +++ b/submodules/TelegramUI/TelegramUI/ApplicationContext.swift @@ -8,6 +8,7 @@ import TelegramCore import Display import LegacyComponents import DeviceAccess +import TelegramUpdateUI func isAccessLocked(data: PostboxAccessChallengeData, at timestamp: Int32) -> Bool { if data.isLockable, let autolockDeadline = data.autolockDeadline, autolockDeadline <= timestamp { @@ -18,14 +19,14 @@ func isAccessLocked(data: PostboxAccessChallengeData, at timestamp: Int32) -> Bo } final class UnauthorizedApplicationContext { - let sharedContext: SharedAccountContext + let sharedContext: SharedAccountContextImpl let account: UnauthorizedAccount let rootController: AuthorizationSequenceController let isReady = Promise() - init(apiId: Int32, apiHash: String, sharedContext: SharedAccountContext, account: UnauthorizedAccount, otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)])) { + init(apiId: Int32, apiHash: String, sharedContext: SharedAccountContextImpl, account: UnauthorizedAccount, otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)])) { self.sharedContext = sharedContext self.account = account let presentationData = sharedContext.currentPresentationData.with { $0 } @@ -56,7 +57,7 @@ final class AuthorizedApplicationContext { let mainWindow: Window1 let lockedCoveringView: LockedWindowCoveringView - let context: AccountContext + let context: AccountContextImpl let rootController: TelegramRootController let notificationController: NotificationContainerController @@ -109,7 +110,7 @@ final class AuthorizedApplicationContext { private var showCallsTabDisposable: Disposable? private var enablePostboxTransactionsDiposable: Disposable? - init(sharedApplicationContext: SharedApplicationContext, mainWindow: Window1, watchManagerArguments: Signal, context: AccountContext, accountManager: AccountManager, showCallsTab: Bool, reinitializedNotificationSettings: @escaping () -> Void) { + init(sharedApplicationContext: SharedApplicationContext, mainWindow: Window1, watchManagerArguments: Signal, context: AccountContextImpl, accountManager: AccountManager, showCallsTab: Bool, reinitializedNotificationSettings: @escaping () -> Void) { self.sharedApplicationContext = sharedApplicationContext setupLegacyComponents(context: context) diff --git a/submodules/TelegramUI/TelegramUI/ArchivedStickerPacksController.swift b/submodules/TelegramUI/TelegramUI/ArchivedStickerPacksController.swift index 8f4d08b52c..f5a5650b82 100644 --- a/submodules/TelegramUI/TelegramUI/ArchivedStickerPacksController.swift +++ b/submodules/TelegramUI/TelegramUI/ArchivedStickerPacksController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI public enum ArchivedStickerPacksControllerMode { case stickers @@ -232,7 +233,7 @@ private func archivedStickerPacksControllerEntries(presentationData: Presentatio return entries } -public func archivedStickerPacksController(context: AccountContext, mode: ArchivedStickerPacksControllerMode, archived: [ArchivedStickerPackItem]?, updatedPacks: @escaping ([ArchivedStickerPackItem]?) -> Void) -> ViewController { +public func archivedStickerPacksController(context: AccountContextImpl, mode: ArchivedStickerPacksControllerMode, archived: [ArchivedStickerPackItem]?, updatedPacks: @escaping ([ArchivedStickerPackItem]?) -> Void) -> ViewController { let statePromise = ValuePromise(ArchivedStickerPacksControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: ArchivedStickerPacksControllerState()) let updateState: ((ArchivedStickerPacksControllerState) -> ArchivedStickerPacksControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/AudioRecordningToneData.swift b/submodules/TelegramUI/TelegramUI/AudioRecordningToneData.swift index 00d5009029..36fc878c01 100644 --- a/submodules/TelegramUI/TelegramUI/AudioRecordningToneData.swift +++ b/submodules/TelegramUI/TelegramUI/AudioRecordningToneData.swift @@ -39,7 +39,7 @@ private func loadAudioRecordingToneData() -> Data? { if let nextBuffer = readerOutput.copyNextSampleBuffer() { var abl = AudioBufferList() var blockBuffer: CMBlockBuffer? = nil - CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(nextBuffer, nil, &abl, MemoryLayout.size, nil, nil, kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, &blockBuffer) + CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(nextBuffer, bufferListSizeNeededOut: nil, bufferListOut: &abl, bufferListSize: MemoryLayout.size, blockBufferAllocator: nil, blockBufferMemoryAllocator: nil, flags: kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, blockBufferOut: &blockBuffer) let size = Int(CMSampleBufferGetTotalSampleSize(nextBuffer)) if size != 0, let mData = abl.mBuffers.mData { data.append(Data(bytes: mData, count: size)) diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceAwaitingAccountResetController.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceAwaitingAccountResetController.swift index d3f1d1de38..378e9875f5 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceAwaitingAccountResetController.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceAwaitingAccountResetController.swift @@ -3,6 +3,7 @@ import UIKit import Display import AsyncDisplayKit import TelegramPresentationData +import ProgressNavigationButtonNode final class AuthorizationSequenceAwaitingAccountResetController: ViewController { private var controllerNode: AuthorizationSequenceAwaitingAccountResetControllerNode { diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCodeEntryController.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCodeEntryController.swift index 3d2fbdb712..0e218780b8 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCodeEntryController.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCodeEntryController.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import TelegramCore import TelegramPresentationData +import ProgressNavigationButtonNode final class AuthorizationSequenceCodeEntryController: ViewController { private var controllerNode: AuthorizationSequenceCodeEntryControllerNode { diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCodeEntryControllerNode.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCodeEntryControllerNode.swift index eb636ef070..5824960368 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCodeEntryControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCodeEntryControllerNode.swift @@ -5,6 +5,7 @@ import Display import TelegramCore import SwiftSignalKit import TelegramPresentationData +import TextFormat func authorizationCurrentOptionText(_ type: SentAuthorizationCodeType, strings: PresentationStrings, primaryColor: UIColor, accentColor: UIColor) -> NSAttributedString { switch type { diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceController.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceController.swift index 5e46070eee..c5063240d6 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceController.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceController.swift @@ -13,6 +13,7 @@ import MtProtoKitDynamic import MessageUI import CoreTelephony import TelegramPresentationData +import TextFormat private enum InnerState: Equatable { case state(UnauthorizedAccountStateContents) @@ -24,7 +25,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail return NavigationBarTheme(buttonColor: theme.rootController.navigationBar.buttonColor, disabledButtonColor: theme.rootController.navigationBar.disabledButtonColor, primaryTextColor: theme.rootController.navigationBar.primaryTextColor, backgroundColor: .clear, separatorColor: .clear, badgeBackgroundColor: theme.rootController.navigationBar.badgeBackgroundColor, badgeStrokeColor: theme.rootController.navigationBar.badgeStrokeColor, badgeTextColor: theme.rootController.navigationBar.badgeTextColor) } - private let sharedContext: SharedAccountContext + private let sharedContext: SharedAccountContextImpl private var account: UnauthorizedAccount private let otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)]) private let apiId: Int32 @@ -44,7 +45,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail } private var didSetReady = false - public init(sharedContext: SharedAccountContext, account: UnauthorizedAccount, otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)]), strings: PresentationStrings, theme: PresentationTheme, openUrl: @escaping (String) -> Void, apiId: Int32, apiHash: String) { + public init(sharedContext: SharedAccountContextImpl, account: UnauthorizedAccount, otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)]), strings: PresentationStrings, theme: PresentationTheme, openUrl: @escaping (String) -> Void, apiId: Int32, apiHash: String) { self.sharedContext = sharedContext self.account = account self.otherAccountPhoneNumbers = otherAccountPhoneNumbers @@ -309,7 +310,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail })]), on: .root, blockInteraction: false, completion: {}) }) ], actionLayout: .vertical) - contentNode.textAttributeAction = (NSAttributedStringKey(rawValue: TelegramTextAttributes.URL), { value in + contentNode.textAttributeAction = (NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), { value in if let value = value as? String { strongSelf.openUrl(value) } @@ -811,7 +812,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail } private func animateOut(completion: (() -> Void)? = nil) { - self.view.layer.animatePosition(from: self.view.layer.position, to: CGPoint(x: self.view.layer.position.x, y: self.view.layer.position.y + self.view.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.view.layer.animatePosition(from: self.view.layer.position, to: CGPoint(x: self.view.layer.position.x, y: self.view.layer.position.y + self.view.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCountrySelectionControllerNode.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCountrySelectionControllerNode.swift index 35c1b147d7..4d3668640d 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCountrySelectionControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceCountrySelectionControllerNode.swift @@ -109,7 +109,7 @@ final class AuthorizationSequenceCountrySelectionControllerNode: ASDisplayNode, } self.sections = sections var sectionTitles = sections.map { $0.0 } - sectionTitles.insert(UITableViewIndexSearch, at: 0) + sectionTitles.insert(UITableView.indexSearch, at: 0) self.sectionTitles = sectionTitles super.init() @@ -154,7 +154,7 @@ final class AuthorizationSequenceCountrySelectionControllerNode: ASDisplayNode, } func animateOut(completion: @escaping () -> Void) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion() }) } diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequencePasswordEntryController.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequencePasswordEntryController.swift index a318fef593..228047eb24 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequencePasswordEntryController.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequencePasswordEntryController.swift @@ -3,6 +3,7 @@ import UIKit import Display import AsyncDisplayKit import TelegramPresentationData +import ProgressNavigationButtonNode final class AuthorizationSequencePasswordEntryController: ViewController { private var controllerNode: AuthorizationSequencePasswordEntryControllerNode { diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequencePasswordRecoveryController.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequencePasswordRecoveryController.swift index 1485b8ff5d..ba281377ed 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequencePasswordRecoveryController.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequencePasswordRecoveryController.swift @@ -3,6 +3,7 @@ import UIKit import Display import AsyncDisplayKit import TelegramPresentationData +import ProgressNavigationButtonNode final class AuthorizationSequencePasswordRecoveryController: ViewController { private var controllerNode: AuthorizationSequencePasswordRecoveryControllerNode { diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryController.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryController.swift index 8bb95b3cf6..dad88ef035 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryController.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryController.swift @@ -6,13 +6,14 @@ import SwiftSignalKit import TelegramCore import Postbox import TelegramPresentationData +import ProgressNavigationButtonNode final class AuthorizationSequencePhoneEntryController: ViewController { private var controllerNode: AuthorizationSequencePhoneEntryControllerNode { return self.displayNode as! AuthorizationSequencePhoneEntryControllerNode } - private let sharedContext: SharedAccountContext + private let sharedContext: SharedAccountContextImpl private let isTestingEnvironment: Bool private let otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)]) private let network: Network @@ -41,7 +42,7 @@ final class AuthorizationSequencePhoneEntryController: ViewController { private let hapticFeedback = HapticFeedback() - init(sharedContext: SharedAccountContext, isTestingEnvironment: Bool, otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)]), network: Network, strings: PresentationStrings, theme: PresentationTheme, openUrl: @escaping (String) -> Void, back: @escaping () -> Void) { + init(sharedContext: SharedAccountContextImpl, isTestingEnvironment: Bool, otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)]), network: Network, strings: PresentationStrings, theme: PresentationTheme, openUrl: @escaping (String) -> Void, back: @escaping () -> Void) { self.sharedContext = sharedContext self.isTestingEnvironment = isTestingEnvironment self.otherAccountPhoneNumbers = otherAccountPhoneNumbers diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryControllerNode.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryControllerNode.swift index 5dfa17ab7d..36fc8fe9b1 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryControllerNode.swift @@ -176,8 +176,6 @@ private final class ContactSyncNode: ASDisplayNode { self.switchNode.frameColor = theme.list.itemSwitchColors.frameColor self.switchNode.contentColor = theme.list.itemSwitchColors.contentColor self.switchNode.handleColor = theme.list.itemSwitchColors.handleColor - self.switchNode.positiveContentColor = theme.list.itemSwitchColors.positiveColor - self.switchNode.negativeContentColor = theme.list.itemSwitchColors.negativeColor self.switchNode.isOn = true super.init() diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceSignUpController.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceSignUpController.swift index 2fa4e80541..22ce1287a4 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceSignUpController.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceSignUpController.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import TelegramCore import TelegramPresentationData import LegacyComponents +import ProgressNavigationButtonNode final class AuthorizationSequenceSignUpController: ViewController { private var controllerNode: AuthorizationSequenceSignUpControllerNode { diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceSignUpControllerNode.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceSignUpControllerNode.swift index ed4dc81184..8c16e1952c 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceSignUpControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceSignUpControllerNode.swift @@ -3,6 +3,7 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import TextFormat private func roundCorners(diameter: CGFloat) -> UIImage { UIGraphicsBeginImageContextWithOptions(CGSize(width: diameter, height: diameter), false, 0.0) @@ -157,14 +158,14 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel self.termsNode.linkHighlightColor = self.theme.list.itemAccentColor.withAlphaComponent(0.5) self.termsNode.highlightAttributeAction = { attributes in - if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] { - return NSAttributedStringKey(rawValue: TelegramTextAttributes.URL) + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) } else { return nil } } self.termsNode.tapAttributeAction = { [weak self] attributes in - if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] { + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { self?.openTermsOfService?() } } diff --git a/submodules/TelegramUI/TelegramUI/AutodownloadConnectionTypeController.swift b/submodules/TelegramUI/TelegramUI/AutodownloadConnectionTypeController.swift index 3e6cd85188..f7c1ae8200 100644 --- a/submodules/TelegramUI/TelegramUI/AutodownloadConnectionTypeController.swift +++ b/submodules/TelegramUI/TelegramUI/AutodownloadConnectionTypeController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI enum AutomaticDownloadConnectionType { case cellular @@ -272,7 +273,7 @@ private func autodownloadMediaConnectionTypeControllerEntries(presentationData: return entries } -func autodownloadMediaConnectionTypeController(context: AccountContext, connectionType: AutomaticDownloadConnectionType) -> ViewController { +func autodownloadMediaConnectionTypeController(context: AccountContextImpl, connectionType: AutomaticDownloadConnectionType) -> ViewController { var pushControllerImpl: ((ViewController) -> Void)? var presentControllerImpl: ((ViewController) -> Void)? diff --git a/submodules/TelegramUI/TelegramUI/AutodownloadDataUsagePickerItem.swift b/submodules/TelegramUI/TelegramUI/AutodownloadDataUsagePickerItem.swift index 8471eac64a..cf0031b9f5 100644 --- a/submodules/TelegramUI/TelegramUI/AutodownloadDataUsagePickerItem.swift +++ b/submodules/TelegramUI/TelegramUI/AutodownloadDataUsagePickerItem.swift @@ -7,6 +7,7 @@ import TelegramCore import TelegramUIPreferences import TelegramPresentationData import LegacyComponents +import ItemListUI enum AutomaticDownloadDataUsage: Int { case low @@ -195,7 +196,7 @@ class AutodownloadDataUsagePickerItemNode: ListViewItemNode { sliderView.knobImage = generateKnobImage() sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + 15.0, y: 37.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - 15.0 * 2.0, height: 44.0)) - sliderView.hitTestEdgeInsets = UIEdgeInsetsMake(-sliderView.frame.minX, 0.0, 0.0, -sliderView.frame.minX) + sliderView.hitTestEdgeInsets = UIEdgeInsets(top: -sliderView.frame.minX, left: 0.0, bottom: 0.0, right: -sliderView.frame.minX) } self.view.addSubview(sliderView) sliderView.addTarget(self, action: #selector(self.sliderValueChanged), for: .valueChanged) @@ -308,7 +309,7 @@ class AutodownloadDataUsagePickerItemNode: ListViewItemNode { } sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + 15.0, y: 37.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - 15.0 * 2.0, height: 44.0)) - sliderView.hitTestEdgeInsets = UIEdgeInsetsMake(-sliderView.frame.minX, 0.0, 0.0, -sliderView.frame.minX) + sliderView.hitTestEdgeInsets = UIEdgeInsets(top: -sliderView.frame.minX, left: 0.0, bottom: 0.0, right: -sliderView.frame.minX) strongSelf.updateSliderView() } diff --git a/submodules/TelegramUI/TelegramUI/AutodownloadMediaCategoryController.swift b/submodules/TelegramUI/TelegramUI/AutodownloadMediaCategoryController.swift index 6326860415..40cc885d70 100644 --- a/submodules/TelegramUI/TelegramUI/AutodownloadMediaCategoryController.swift +++ b/submodules/TelegramUI/TelegramUI/AutodownloadMediaCategoryController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI public func autodownloadDataSizeString(_ size: Int64, decimalSeparator: String = ".") -> String { if size >= 1024 * 1024 * 1024 { @@ -284,7 +285,7 @@ private func autodownloadMediaCategoryControllerEntries(presentationData: Presen return entries } -func autodownloadMediaCategoryController(context: AccountContext, connectionType: AutomaticDownloadConnectionType, category: AutomaticDownloadCategory) -> ViewController { +func autodownloadMediaCategoryController(context: AccountContextImpl, connectionType: AutomaticDownloadConnectionType, category: AutomaticDownloadCategory) -> ViewController { let arguments = AutodownloadMediaCategoryControllerArguments(togglePeer: { type in let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in var settings = settings diff --git a/submodules/TelegramUI/TelegramUI/AutodownloadSizeLimitItem.swift b/submodules/TelegramUI/TelegramUI/AutodownloadSizeLimitItem.swift index 530a07738d..65920b9fdb 100644 --- a/submodules/TelegramUI/TelegramUI/AutodownloadSizeLimitItem.swift +++ b/submodules/TelegramUI/TelegramUI/AutodownloadSizeLimitItem.swift @@ -5,9 +5,8 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramCore import TelegramPresentationData -import TelegramPresentationData - import LegacyComponents +import ItemListUI private let autodownloadSizeValues: [(CGFloat, Int32)] = [ (0.000, 512 * 1024), @@ -172,7 +171,7 @@ class AutodownloadSizeLimitItemNode: ListViewItemNode { sliderView.knobImage = generateKnobImage() sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + 15.0, y: 37.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - 15.0 * 2.0, height: 44.0)) - sliderView.hitTestEdgeInsets = UIEdgeInsetsMake(-sliderView.frame.minX, 0.0, 0.0, -sliderView.frame.minX) + sliderView.hitTestEdgeInsets = UIEdgeInsets(top: -sliderView.frame.minX, left: 0.0, bottom: 0.0, right: -sliderView.frame.minX) } self.view.addSubview(sliderView) sliderView.addTarget(self, action: #selector(self.sliderValueChanged), for: .valueChanged) @@ -263,7 +262,7 @@ class AutodownloadSizeLimitItemNode: ListViewItemNode { } sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + 15.0, y: 37.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - 15.0 * 2.0, height: 44.0)) - sliderView.hitTestEdgeInsets = UIEdgeInsetsMake(-sliderView.frame.minX, 0.0, 0.0, -sliderView.frame.minX) + sliderView.hitTestEdgeInsets = UIEdgeInsets(top: -sliderView.frame.minX, left: 0.0, bottom: 0.0, right: -sliderView.frame.minX) } } }) diff --git a/submodules/TelegramUI/TelegramUI/AvatarGalleryController.swift b/submodules/TelegramUI/TelegramUI/AvatarGalleryController.swift index 04e514f71e..c402dc5f39 100644 --- a/submodules/TelegramUI/TelegramUI/AvatarGalleryController.swift +++ b/submodules/TelegramUI/TelegramUI/AvatarGalleryController.swift @@ -104,7 +104,7 @@ class AvatarGalleryController: ViewController { return self.displayNode as! GalleryControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let peer: Peer private var presentationData: PresentationData @@ -135,7 +135,7 @@ class AvatarGalleryController: ViewController { private let replaceRootController: (ViewController, ValuePromise?) -> Void - init(context: AccountContext, peer: Peer, remoteEntries: Promise<[AvatarGalleryEntry]>? = nil, replaceRootController: @escaping (ViewController, ValuePromise?) -> Void, synchronousLoad: Bool = false) { + init(context: AccountContextImpl, peer: Peer, remoteEntries: Promise<[AvatarGalleryEntry]>? = nil, replaceRootController: @escaping (ViewController, ValuePromise?) -> Void, synchronousLoad: Bool = false) { self.context = context self.peer = peer self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/AvatarGalleryItemFooterContentNode.swift b/submodules/TelegramUI/TelegramUI/AvatarGalleryItemFooterContentNode.swift index af06ebf138..655bcd9c45 100644 --- a/submodules/TelegramUI/TelegramUI/AvatarGalleryItemFooterContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/AvatarGalleryItemFooterContentNode.swift @@ -16,7 +16,7 @@ private let nameFont = Font.medium(15.0) private let dateFont = Font.regular(14.0) final class AvatarGalleryItemFooterContentNode: GalleryFooterContentNode { - private let context: AccountContext + private let context: AccountContextImpl private var strings: PresentationStrings private var dateTimeFormat: PresentationDateTimeFormat @@ -36,7 +36,7 @@ final class AvatarGalleryItemFooterContentNode: GalleryFooterContentNode { var share: ((GalleryControllerInteraction) -> Void)? - init(context: AccountContext, presentationData: PresentationData) { + init(context: AccountContextImpl, presentationData: PresentationData) { self.context = context self.strings = presentationData.strings self.dateTimeFormat = presentationData.dateTimeFormat diff --git a/submodules/TelegramUI/TelegramUI/AvatarNode.swift b/submodules/TelegramUI/TelegramUI/AvatarNode.swift index 2cf8ef47fe..69200b7cd5 100644 --- a/submodules/TelegramUI/TelegramUI/AvatarNode.swift +++ b/submodules/TelegramUI/TelegramUI/AvatarNode.swift @@ -6,6 +6,7 @@ import Display import TelegramCore import SwiftSignalKit import TelegramPresentationData +import AnimationUI private let deletedIcon = UIImage(bundleImageName: "Avatar/DeletedIcon")?.precomposed() private let savedMessagesIcon = UIImage(bundleImageName: "Avatar/SavedMessagesIcon")?.precomposed() @@ -491,7 +492,7 @@ public final class AvatarNode: ASDisplayNode { } else { let letters = parameters.letters let string = letters.count == 0 ? "" : (letters[0] + (letters.count == 1 ? "" : letters[1])) - let attributedString = NSAttributedString(string: string, attributes: [NSAttributedStringKey.font: parameters.font, NSAttributedStringKey.foregroundColor: UIColor.white]) + let attributedString = NSAttributedString(string: string, attributes: [NSAttributedString.Key.font: parameters.font, NSAttributedString.Key.foregroundColor: UIColor.white]) let line = CTLineCreateWithAttributedString(attributedString) let lineBounds = CTLineGetBoundsWithOptions(line, .useGlyphPathBounds) @@ -569,7 +570,7 @@ func drawPeerAvatarLetters(context: CGContext, size: CGSize, font: UIFont, lette context.setBlendMode(.normal) let string = letters.count == 0 ? "" : (letters[0] + (letters.count == 1 ? "" : letters[1])) - let attributedString = NSAttributedString(string: string, attributes: [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: UIColor.white]) + let attributedString = NSAttributedString(string: string, attributes: [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: UIColor.white]) let line = CTLineCreateWithAttributedString(attributedString) let lineBounds = CTLineGetBoundsWithOptions(line, .useGlyphPathBounds) diff --git a/submodules/TelegramUI/TelegramUI/BlockedPeersController.swift b/submodules/TelegramUI/TelegramUI/BlockedPeersController.swift index 96679afd4d..927817e1c1 100644 --- a/submodules/TelegramUI/TelegramUI/BlockedPeersController.swift +++ b/submodules/TelegramUI/TelegramUI/BlockedPeersController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class BlockedPeersControllerArguments { let account: Account @@ -193,7 +194,7 @@ private func blockedPeersControllerEntries(presentationData: PresentationData, s return entries } -public func blockedPeersController(context: AccountContext, blockedPeersContext: BlockedPeersContext) -> ViewController { +public func blockedPeersController(context: AccountContextImpl, blockedPeersContext: BlockedPeersContext) -> ViewController { let statePromise = ValuePromise(BlockedPeersControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: BlockedPeersControllerState()) let updateState: ((BlockedPeersControllerState) -> BlockedPeersControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/BlurredImageNode.swift b/submodules/TelegramUI/TelegramUI/BlurredImageNode.swift index 6cc43b26cf..3f1cc2917b 100644 --- a/submodules/TelegramUI/TelegramUI/BlurredImageNode.swift +++ b/submodules/TelegramUI/TelegramUI/BlurredImageNode.swift @@ -47,7 +47,7 @@ private class BlurLayer: CALayer { func draw(_ image: UIImage) { self.contents = image.cgImage self.contentsScale = image.scale - self.contentsGravity = kCAGravityResizeAspectFill + self.contentsGravity = .resizeAspectFill } func render(in context: CGContext, for layer: CALayer) { diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutActionButton.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutActionButton.swift index f319a829f6..70ccb3b58e 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutActionButton.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutActionButton.swift @@ -127,12 +127,12 @@ final class BotCheckoutActionButton: HighlightableButtonNode { self.progressBackgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = 0.8 basicAnimation.fromValue = NSNumber(value: Float(0.0)) basicAnimation.toValue = NSNumber(value: Float.pi * 2.0) basicAnimation.repeatCount = Float.infinity - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) self.progressBackgroundNode.layer.add(basicAnimation, forKey: "progressRotation") case let .active(title): @@ -192,12 +192,12 @@ final class BotCheckoutActionButton: HighlightableButtonNode { self.activeBackgroundNode.alpha = 0.0 let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = 0.8 basicAnimation.fromValue = NSNumber(value: Float(0.0)) basicAnimation.toValue = NSNumber(value: Float.pi * 2.0) basicAnimation.repeatCount = Float.infinity - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) self.progressBackgroundNode.layer.add(basicAnimation, forKey: "progressRotation") case .active: diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutController.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutController.swift index 405f8c1165..345b4adb7b 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutController.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutController.swift @@ -17,7 +17,7 @@ final class BotCheckoutController: ViewController { return self._ready } - private let context: AccountContext + private let context: AccountContextImpl private let invoice: TelegramMediaInvoice private let messageId: MessageId @@ -25,7 +25,7 @@ final class BotCheckoutController: ViewController { private var didPlayPresentationAnimation = false - init(context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId) { + init(context: AccountContextImpl, invoice: TelegramMediaInvoice, messageId: MessageId) { self.context = context self.invoice = invoice self.messageId = messageId diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutControllerNode.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutControllerNode.swift index 78b383571e..6e28feae0b 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutControllerNode.swift @@ -8,6 +8,7 @@ import SwiftSignalKit import PassKit import TelegramPresentationData import TelegramUIPrivateModule +import ItemListUI final class BotCheckoutControllerArguments { fileprivate let account: Account @@ -360,7 +361,7 @@ private func availablePaymentMethods(form: BotPaymentForm, current: BotCheckoutP } final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthorizationViewControllerDelegate { - private let context: AccountContext + private let context: AccountContextImpl private let messageId: MessageId private let present: (ViewController, Any?) -> Void private let dismissAnimated: () -> Void @@ -387,7 +388,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, private var applePayAuthrorizationCompletion: ((PKPaymentAuthorizationStatus) -> Void)? private var applePayController: PKPaymentAuthorizationViewController? - init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId, present: @escaping (ViewController, Any?) -> Void, dismissAnimated: @escaping () -> Void) { + init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContextImpl, invoice: TelegramMediaInvoice, messageId: MessageId, present: @escaping (ViewController, Any?) -> Void, dismissAnimated: @escaping () -> Void) { self.context = context self.messageId = messageId self.present = present diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutHeaderItem.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutHeaderItem.swift index a955210bfb..4d9d896cf2 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutHeaderItem.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutHeaderItem.swift @@ -5,6 +5,7 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ItemListUI class BotCheckoutHeaderItem: ListViewItem, ItemListItem { let account: Account diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutInfoController.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutInfoController.swift index a29c2de822..40bf0e48ad 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutInfoController.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutInfoController.swift @@ -5,6 +5,7 @@ import Display import TelegramCore import Postbox import TelegramPresentationData +import ProgressNavigationButtonNode enum BotCheckoutInfoControllerAddressFocus { case street1 @@ -26,7 +27,7 @@ final class BotCheckoutInfoController: ViewController { return super.displayNode as! BotCheckoutInfoControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let invoice: BotPaymentInvoice private let messageId: MessageId private let initialFormInfo: BotPaymentRequestedInfo @@ -41,7 +42,7 @@ final class BotCheckoutInfoController: ViewController { private var doneItem: UIBarButtonItem? private var activityItem: UIBarButtonItem? - public init(context: AccountContext, invoice: BotPaymentInvoice, messageId: MessageId, initialFormInfo: BotPaymentRequestedInfo, focus: BotCheckoutInfoControllerFocus, formInfoUpdated: @escaping (BotPaymentRequestedInfo, BotPaymentValidatedFormInfo) -> Void) { + public init(context: AccountContextImpl, invoice: BotPaymentInvoice, messageId: MessageId, initialFormInfo: BotPaymentRequestedInfo, focus: BotCheckoutInfoControllerFocus, formInfoUpdated: @escaping (BotPaymentRequestedInfo, BotPaymentValidatedFormInfo) -> Void) { self.context = context self.invoice = invoice self.messageId = messageId diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutInfoControllerNode.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutInfoControllerNode.swift index c0e365d95f..d0c1628f1d 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutInfoControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutInfoControllerNode.swift @@ -90,7 +90,7 @@ enum BotCheckoutInfoControllerStatus { } final class BotCheckoutInfoControllerNode: ViewControllerTracingNode, UIScrollViewDelegate { - private let context: AccountContext + private let context: AccountContextImpl private let invoice: BotPaymentInvoice private let messageId: MessageId private var focus: BotCheckoutInfoControllerFocus? @@ -120,7 +120,7 @@ final class BotCheckoutInfoControllerNode: ViewControllerTracingNode, UIScrollVi private let verifyDisposable = MetaDisposable() private var isVerifying = false - init(context: AccountContext, invoice: BotPaymentInvoice, messageId: MessageId, formInfo: BotPaymentRequestedInfo, focus: BotCheckoutInfoControllerFocus, theme: PresentationTheme, strings: PresentationStrings, dismiss: @escaping () -> Void, openCountrySelection: @escaping () -> Void, updateStatus: @escaping (BotCheckoutInfoControllerStatus) -> Void, formInfoUpdated: @escaping (BotPaymentRequestedInfo, BotPaymentValidatedFormInfo) -> Void, present: @escaping (ViewController, Any?) -> Void) { + init(context: AccountContextImpl, invoice: BotPaymentInvoice, messageId: MessageId, formInfo: BotPaymentRequestedInfo, focus: BotCheckoutInfoControllerFocus, theme: PresentationTheme, strings: PresentationStrings, dismiss: @escaping () -> Void, openCountrySelection: @escaping () -> Void, updateStatus: @escaping (BotCheckoutInfoControllerStatus) -> Void, formInfoUpdated: @escaping (BotPaymentRequestedInfo, BotPaymentValidatedFormInfo) -> Void, present: @escaping (ViewController, Any?) -> Void) { self.context = context self.invoice = invoice self.messageId = messageId @@ -501,7 +501,7 @@ final class BotCheckoutInfoControllerNode: ViewControllerTracingNode, UIScrollVi } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { [weak self] _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in if let strongSelf = self { strongSelf.dismiss() } diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutNativeCardEntryController.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutNativeCardEntryController.swift index eba0d2cfad..218df20192 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutNativeCardEntryController.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutNativeCardEntryController.swift @@ -6,6 +6,7 @@ import Display import TelegramCore import Postbox import TelegramPresentationData +import ProgressNavigationButtonNode enum BotCheckoutNativeCardEntryStatus { case notReady @@ -30,7 +31,7 @@ final class BotCheckoutNativeCardEntryController: ViewController { return super.displayNode as! BotCheckoutNativeCardEntryControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let additionalFields: BotCheckoutNativeCardEntryAdditionalFields private let publishableKey: String private let completion: (BotCheckoutPaymentMethod) -> Void @@ -42,7 +43,7 @@ final class BotCheckoutNativeCardEntryController: ViewController { private var doneItem: UIBarButtonItem? private var activityItem: UIBarButtonItem? - public init(context: AccountContext, additionalFields: BotCheckoutNativeCardEntryAdditionalFields, publishableKey: String, completion: @escaping (BotCheckoutPaymentMethod) -> Void) { + public init(context: AccountContextImpl, additionalFields: BotCheckoutNativeCardEntryAdditionalFields, publishableKey: String, completion: @escaping (BotCheckoutPaymentMethod) -> Void) { self.context = context self.additionalFields = additionalFields self.publishableKey = publishableKey diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutNativeCardEntryControllerNode.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutNativeCardEntryControllerNode.swift index d76018944b..8c8d14c5da 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutNativeCardEntryControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutNativeCardEntryControllerNode.swift @@ -379,7 +379,7 @@ final class BotCheckoutNativeCardEntryControllerNode: ViewControllerTracingNode, } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { [weak self] _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in if let strongSelf = self { strongSelf.dismiss() } diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutPasswordEntryController.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutPasswordEntryController.swift index f08da27cff..8216e30f74 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutPasswordEntryController.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutPasswordEntryController.swift @@ -68,7 +68,7 @@ private final class BotCheckoutPasswordAlertActionNode: HighlightableButtonNode } private final class BotCheckoutPasswordAlertContentNode: AlertContentNode { - private let context: AccountContext + private let context: AccountContextImpl private let period: Int32 private let requiresBiometrics: Bool private let completion: (TemporaryTwoStepPasswordToken) -> Void @@ -92,7 +92,7 @@ private final class BotCheckoutPasswordAlertContentNode: AlertContentNode { private let hapticFeedback = HapticFeedback() - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, cardTitle: String, period: Int32, requiresBiometrics: Bool, cancel: @escaping () -> Void, completion: @escaping (TemporaryTwoStepPasswordToken) -> Void) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings, cardTitle: String, period: Int32, requiresBiometrics: Bool, cancel: @escaping () -> Void, completion: @escaping (TemporaryTwoStepPasswordToken) -> Void) { self.context = context self.period = period self.requiresBiometrics = requiresBiometrics @@ -150,7 +150,7 @@ private final class BotCheckoutPasswordAlertContentNode: AlertContentNode { self.textFieldNode = TextFieldNode() self.textFieldNode.textField.textColor = theme.actionSheet.primaryTextColor self.textFieldNode.textField.font = Font.regular(12.0) - self.textFieldNode.textField.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(12.0)] + self.textFieldNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(12.0)] self.textFieldNode.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance self.textFieldNode.textField.isSecureTextEntry = true @@ -297,7 +297,7 @@ private final class BotCheckoutPasswordAlertContentNode: AlertContentNode { } } -func botCheckoutPasswordEntryController(context: AccountContext, strings: PresentationStrings, cartTitle: String, period: Int32, requiresBiometrics: Bool, completion: @escaping (TemporaryTwoStepPasswordToken) -> Void) -> AlertController { +func botCheckoutPasswordEntryController(context: AccountContextImpl, strings: PresentationStrings, cartTitle: String, period: Int32, requiresBiometrics: Bool, completion: @escaping (TemporaryTwoStepPasswordToken) -> Void) -> AlertController { var dismissImpl: (() -> Void)? let presentationData = context.sharedContext.currentPresentationData.with { $0 } let controller = AlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), contentNode: BotCheckoutPasswordAlertContentNode(context: context, theme: presentationData.theme, strings: strings, cardTitle: cartTitle, period: period, requiresBiometrics: requiresBiometrics, cancel: { diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutPaymentMethodSheet.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutPaymentMethodSheet.swift index 0ab7d87d99..6d6e01be03 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutPaymentMethodSheet.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutPaymentMethodSheet.swift @@ -34,7 +34,7 @@ enum BotCheckoutPaymentMethod: Equatable { final class BotCheckoutPaymentMethodSheetController: ActionSheetController { private var presentationDisposable: Disposable? - init(context: AccountContext, currentMethod: BotCheckoutPaymentMethod?, methods: [BotCheckoutPaymentMethod], applyValue: @escaping (BotCheckoutPaymentMethod) -> Void, newCard: @escaping () -> Void) { + init(context: AccountContextImpl, currentMethod: BotCheckoutPaymentMethod?, methods: [BotCheckoutPaymentMethod], applyValue: @escaping (BotCheckoutPaymentMethod) -> Void, newCard: @escaping () -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutPaymentShippingOptionSheetController.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutPaymentShippingOptionSheetController.swift index e0f9060e56..e2e6f32163 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutPaymentShippingOptionSheetController.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutPaymentShippingOptionSheetController.swift @@ -8,7 +8,7 @@ import TelegramCore final class BotCheckoutPaymentShippingOptionSheetController: ActionSheetController { private var presentationDisposable: Disposable? - init(context: AccountContext, currency: String, options: [BotPaymentShippingOption], currentId: String?, applyValue: @escaping (String) -> Void) { + init(context: AccountContextImpl, currency: String, options: [BotPaymentShippingOption], currentId: String?, applyValue: @escaping (String) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutPriceItem.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutPriceItem.swift index 4589cc25a0..cd6e6f7e66 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutPriceItem.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutPriceItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI class BotCheckoutPriceItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutWebInteractionController.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutWebInteractionController.swift index e88ce34306..42e572a60c 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutWebInteractionController.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutWebInteractionController.swift @@ -17,7 +17,7 @@ final class BotCheckoutWebInteractionController: ViewController { return self.displayNode as! BotCheckoutWebInteractionControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let url: String private let intent: BotCheckoutWebInteractionControllerIntent @@ -25,7 +25,7 @@ final class BotCheckoutWebInteractionController: ViewController { private var didPlayPresentationAnimation = false - init(context: AccountContext, url: String, intent: BotCheckoutWebInteractionControllerIntent) { + init(context: AccountContextImpl, url: String, intent: BotCheckoutWebInteractionControllerIntent) { self.context = context self.url = url self.intent = intent diff --git a/submodules/TelegramUI/TelegramUI/BotCheckoutWebInteractionControllerNode.swift b/submodules/TelegramUI/TelegramUI/BotCheckoutWebInteractionControllerNode.swift index 38b7e1cd7b..4352cb60a0 100644 --- a/submodules/TelegramUI/TelegramUI/BotCheckoutWebInteractionControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/BotCheckoutWebInteractionControllerNode.swift @@ -87,7 +87,7 @@ final class BotCheckoutWebInteractionControllerNode: ViewControllerTracingNode, } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/BotPaymentActionItemNode.swift b/submodules/TelegramUI/TelegramUI/BotPaymentActionItemNode.swift index 0e59a1bb92..c8063bbbf8 100644 --- a/submodules/TelegramUI/TelegramUI/BotPaymentActionItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/BotPaymentActionItemNode.swift @@ -38,7 +38,7 @@ final class BotPaymentActionItemNode: BotPaymentItemNode { if let strongSelf = self { if highlighted { if let supernode = strongSelf.supernode { - supernode.view.bringSubview(toFront: strongSelf.view) + supernode.view.bringSubviewToFront(strongSelf.view) } strongSelf.highlightedBackgroundNode.layer.removeAnimation(forKey: "opacity") diff --git a/submodules/TelegramUI/TelegramUI/BotPaymentDisclosureItemNode.swift b/submodules/TelegramUI/TelegramUI/BotPaymentDisclosureItemNode.swift index 4962eeeef7..6d599a12b7 100644 --- a/submodules/TelegramUI/TelegramUI/BotPaymentDisclosureItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/BotPaymentDisclosureItemNode.swift @@ -53,7 +53,7 @@ class BotPaymentDisclosureItemNode: BotPaymentItemNode { if let strongSelf = self { if highlighted { if let supernode = strongSelf.supernode { - supernode.view.bringSubview(toFront: strongSelf.view) + supernode.view.bringSubviewToFront(strongSelf.view) } strongSelf.highlightedBackgroundNode.layer.removeAnimation(forKey: "opacity") diff --git a/submodules/TelegramUI/TelegramUI/BotPaymentSwitchItemNode.swift b/submodules/TelegramUI/TelegramUI/BotPaymentSwitchItemNode.swift index b5114dc8ce..31c9d41455 100644 --- a/submodules/TelegramUI/TelegramUI/BotPaymentSwitchItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/BotPaymentSwitchItemNode.swift @@ -68,8 +68,6 @@ final class BotPaymentSwitchItemNode: BotPaymentItemNode { self.switchNode.frameColor = theme.list.itemSwitchColors.frameColor self.switchNode.contentColor = theme.list.itemSwitchColors.contentColor self.switchNode.handleColor = theme.list.itemSwitchColors.handleColor - self.switchNode.positiveContentColor = theme.list.itemSwitchColors.positiveColor - self.switchNode.negativeContentColor = theme.list.itemSwitchColors.negativeColor } let leftInset: CGFloat = 16.0 diff --git a/submodules/TelegramUI/TelegramUI/BotReceiptController.swift b/submodules/TelegramUI/TelegramUI/BotReceiptController.swift index a2e2b09748..426c3467b3 100644 --- a/submodules/TelegramUI/TelegramUI/BotReceiptController.swift +++ b/submodules/TelegramUI/TelegramUI/BotReceiptController.swift @@ -17,7 +17,7 @@ final class BotReceiptController: ViewController { return self._ready } - private let context: AccountContext + private let context: AccountContextImpl private let invoice: TelegramMediaInvoice private let messageId: MessageId @@ -25,7 +25,7 @@ final class BotReceiptController: ViewController { private var didPlayPresentationAnimation = false - init(context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId) { + init(context: AccountContextImpl, invoice: TelegramMediaInvoice, messageId: MessageId) { self.context = context self.invoice = invoice self.messageId = messageId diff --git a/submodules/TelegramUI/TelegramUI/BotReceiptControllerNode.swift b/submodules/TelegramUI/TelegramUI/BotReceiptControllerNode.swift index 2925e821d3..fe7626f7bb 100644 --- a/submodules/TelegramUI/TelegramUI/BotReceiptControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/BotReceiptControllerNode.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import ItemListUI final class BotReceiptControllerArguments { fileprivate let account: Account @@ -251,7 +252,7 @@ private func availablePaymentMethods(current: BotCheckoutPaymentMethod?) -> [Bot } final class BotReceiptControllerNode: ItemListControllerNode { - private let context: AccountContext + private let context: AccountContextImpl private let dismissAnimated: () -> Void private var presentationData: PresentationData @@ -261,7 +262,7 @@ final class BotReceiptControllerNode: ItemListControllerNode { private let actionButton: BotCheckoutActionButton - init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId, dismissAnimated: @escaping () -> Void) { + init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContextImpl, invoice: TelegramMediaInvoice, messageId: MessageId, dismissAnimated: @escaping () -> Void) { self.context = context self.dismissAnimated = dismissAnimated diff --git a/submodules/TelegramUI/TelegramUI/CachedFaqInstantPage.swift b/submodules/TelegramUI/TelegramUI/CachedFaqInstantPage.swift index 5c73a938a0..0fba30a5d1 100644 --- a/submodules/TelegramUI/TelegramUI/CachedFaqInstantPage.swift +++ b/submodules/TelegramUI/TelegramUI/CachedFaqInstantPage.swift @@ -23,7 +23,7 @@ private func extractAnchor(string: String) -> (String, String?) { private let refreshTimeout: Int32 = 60 * 60 * 12 -func cachedFaqInstantPage(context: AccountContext) -> Signal { +func cachedFaqInstantPage(context: AccountContextImpl) -> Signal { var faqUrl = context.sharedContext.currentPresentationData.with { $0 }.strings.Settings_FAQ_URL if faqUrl == "Settings.FAQ_URL" || faqUrl.isEmpty { faqUrl = "https://telegram.org/faq#general-questions" @@ -66,7 +66,7 @@ func cachedFaqInstantPage(context: AccountContext) -> Signal Signal<[SettingsSearchableItem], NoError> { +func faqSearchableItems(context: AccountContextImpl) -> Signal<[SettingsSearchableItem], NoError> { let strings = context.sharedContext.currentPresentationData.with { $0 }.strings return cachedFaqInstantPage(context: context) |> map { resolvedUrl -> [SettingsSearchableItem] in diff --git a/submodules/TelegramUI/TelegramUI/CalculatingCacheSizeItem.swift b/submodules/TelegramUI/TelegramUI/CalculatingCacheSizeItem.swift index 0f31efa963..73251a38da 100644 --- a/submodules/TelegramUI/TelegramUI/CalculatingCacheSizeItem.swift +++ b/submodules/TelegramUI/TelegramUI/CalculatingCacheSizeItem.swift @@ -4,6 +4,8 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI +import ActivityIndicator class CalculatingCacheSizeItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/CallController.swift b/submodules/TelegramUI/TelegramUI/CallController.swift index 3bf30fc5fb..4651474b57 100644 --- a/submodules/TelegramUI/TelegramUI/CallController.swift +++ b/submodules/TelegramUI/TelegramUI/CallController.swift @@ -21,7 +21,7 @@ public final class CallController: ViewController { return self._ready } - private let sharedContext: SharedAccountContext + private let sharedContext: SharedAccountContextImpl private let account: Account public let call: PresentationCall @@ -41,7 +41,7 @@ public final class CallController: ViewController { private var audioOutputStateDisposable: Disposable? private var audioOutputState: ([AudioSessionOutput], AudioSessionOutput?)? - public init(sharedContext: SharedAccountContext, account: Account, call: PresentationCall) { + public init(sharedContext: SharedAccountContextImpl, account: Account, call: PresentationCall) { self.sharedContext = sharedContext self.account = account self.call = call diff --git a/submodules/TelegramUI/TelegramUI/CallControllerButton.swift b/submodules/TelegramUI/TelegramUI/CallControllerButton.swift index 11f0f410b0..016e6db3e1 100644 --- a/submodules/TelegramUI/TelegramUI/CallControllerButton.swift +++ b/submodules/TelegramUI/TelegramUI/CallControllerButton.swift @@ -172,7 +172,7 @@ final class CallControllerButtonNode: HighlightTrackingButtonNode { self.backgroundNode.layer.removeAnimation(forKey: "contents") if let currentContents = currentContents, let image = image { self.backgroundNode.image = image - self.backgroundNode.layer.animate(from: currentContents as AnyObject, to: image.cgImage!, keyPath: "contents", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: image === self.currentImage || image === self.filledImage ? 0.25 : 0.15) + self.backgroundNode.layer.animate(from: currentContents as AnyObject, to: image.cgImage!, keyPath: "contents", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: image === self.currentImage || image === self.filledImage ? 0.25 : 0.15) } else { self.backgroundNode.image = image } diff --git a/submodules/TelegramUI/TelegramUI/CallControllerKeyPreviewNode.swift b/submodules/TelegramUI/TelegramUI/CallControllerKeyPreviewNode.swift index 6198e870b9..a95979375a 100644 --- a/submodules/TelegramUI/TelegramUI/CallControllerKeyPreviewNode.swift +++ b/submodules/TelegramUI/TelegramUI/CallControllerKeyPreviewNode.swift @@ -32,7 +32,7 @@ final class CallControllerKeyPreviewNode: ASDisplayNode { super.init() - self.keyTextNode.attributedText = NSAttributedString(string: keyText, attributes: [NSAttributedStringKey.font: Font.regular(58.0), NSAttributedStringKey.kern: 9.0 as NSNumber]) + self.keyTextNode.attributedText = NSAttributedString(string: keyText, attributes: [NSAttributedString.Key.font: Font.regular(58.0), NSAttributedString.Key.kern: 9.0 as NSNumber]) self.infoTextNode.attributedText = NSAttributedString(string: infoText, font: Font.regular(14.0), textColor: UIColor.white, paragraphAlignment: .center) diff --git a/submodules/TelegramUI/TelegramUI/CallControllerNode.swift b/submodules/TelegramUI/TelegramUI/CallControllerNode.swift index dc23280bb4..e80718588a 100644 --- a/submodules/TelegramUI/TelegramUI/CallControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/CallControllerNode.swift @@ -12,7 +12,7 @@ import TelegramUIPreferences import TelegramAudio final class CallControllerNode: ASDisplayNode { - private let sharedContext: SharedAccountContext + private let sharedContext: SharedAccountContextImpl private let account: Account private let statusBar: StatusBar @@ -60,7 +60,7 @@ final class CallControllerNode: ASDisplayNode { var callEnded: ((Bool) -> Void)? var dismissedInteractively: (() -> Void)? - init(sharedContext: SharedAccountContext, account: Account, presentationData: PresentationData, statusBar: StatusBar, debugInfo: Signal<(String, String), NoError>, shouldStayHiddenUntilConnection: Bool = false) { + init(sharedContext: SharedAccountContextImpl, account: Account, presentationData: PresentationData, statusBar: StatusBar, debugInfo: Signal<(String, String), NoError>, shouldStayHiddenUntilConnection: Bool = false) { self.sharedContext = sharedContext self.account = account self.presentationData = presentationData @@ -237,7 +237,7 @@ final class CallControllerNode: ASDisplayNode { let text = stringForEmojiHashOfData(keyVisualHash, 4)! self.keyTextData = (keyVisualHash, text) - self.keyButtonNode.setAttributedTitle(NSAttributedString(string: text, attributes: [NSAttributedStringKey.font: Font.regular(22.0), NSAttributedStringKey.kern: 2.5 as NSNumber]), for: []) + self.keyButtonNode.setAttributedTitle(NSAttributedString(string: text, attributes: [NSAttributedString.Key.font: Font.regular(22.0), NSAttributedString.Key.kern: 2.5 as NSNumber]), for: []) let keyTextSize = self.keyButtonNode.measure(CGSize(width: 200.0, height: 200.0)) self.keyButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) @@ -525,7 +525,7 @@ final class CallControllerNode: ASDisplayNode { let previous = bounds bounds.origin = CGPoint(x: 0.0, y: velocity > 0.0 ? -bounds.height: bounds.height) self.bounds = bounds - self.layer.animateBounds(from: previous, to: bounds, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseOut, completion: { [weak self] _ in + self.layer.animateBounds(from: previous, to: bounds, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, completion: { [weak self] _ in self?.dismissedInteractively?() }) } diff --git a/submodules/TelegramUI/TelegramUI/CallDebugNode.swift b/submodules/TelegramUI/TelegramUI/CallDebugNode.swift index 41384c2baa..c1a1710cd0 100644 --- a/submodules/TelegramUI/TelegramUI/CallDebugNode.swift +++ b/submodules/TelegramUI/TelegramUI/CallDebugNode.swift @@ -15,7 +15,7 @@ private func attributedStringForDebugInfo(_ info: String, version: String) -> NS string = string.replacingOccurrences(of: "Jitter ", with: "\nJitter ") string = string.replacingOccurrences(of: "Key fingerprint:\n", with: "Key fingerprint: ") - let attributedString = NSMutableAttributedString(string: string, attributes: [NSAttributedStringKey.font: Font.monospace(10), NSAttributedStringKey.foregroundColor: UIColor.white]) + let attributedString = NSMutableAttributedString(string: string, attributes: [NSAttributedString.Key.font: Font.monospace(10), NSAttributedString.Key.foregroundColor: UIColor.white]) let titleStyle = NSMutableParagraphStyle() titleStyle.alignment = .center @@ -27,11 +27,11 @@ private func attributedStringForDebugInfo(_ info: String, version: String) -> NS let secondaryColor = UIColor(rgb: 0xa6a9a8) let activeColor = UIColor(rgb: 0xa0d875) - let titleAttributes = [NSAttributedStringKey.font: Font.semiboldMonospace(15), NSAttributedStringKey.paragraphStyle: titleStyle] - let nameAttributes = [NSAttributedStringKey.font: Font.semiboldMonospace(10), NSAttributedStringKey.foregroundColor: secondaryColor] - let styleAttributes = [NSAttributedStringKey.paragraphStyle: style] - let typeAttributes = [NSAttributedStringKey.foregroundColor: secondaryColor] - let activeAttributes = [NSAttributedStringKey.font: Font.semiboldMonospace(10), NSAttributedStringKey.foregroundColor: activeColor] + let titleAttributes = [NSAttributedString.Key.font: Font.semiboldMonospace(15), NSAttributedString.Key.paragraphStyle: titleStyle] + let nameAttributes = [NSAttributedString.Key.font: Font.semiboldMonospace(10), NSAttributedString.Key.foregroundColor: secondaryColor] + let styleAttributes = [NSAttributedString.Key.paragraphStyle: style] + let typeAttributes = [NSAttributedString.Key.foregroundColor: secondaryColor] + let activeAttributes = [NSAttributedString.Key.font: Font.semiboldMonospace(10), NSAttributedString.Key.foregroundColor: activeColor] let range = string.startIndex ..< string.endIndex string.enumerateSubstrings(in: range, options: NSString.EnumerationOptions.byLines) { (line, range, _, _) in diff --git a/submodules/TelegramUI/TelegramUI/CallFeedbackController.swift b/submodules/TelegramUI/TelegramUI/CallFeedbackController.swift index 9d0156a765..fba56e67a6 100644 --- a/submodules/TelegramUI/TelegramUI/CallFeedbackController.swift +++ b/submodules/TelegramUI/TelegramUI/CallFeedbackController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private enum CallFeedbackReason: Int32, CaseIterable { case echo @@ -206,7 +207,7 @@ private func callFeedbackControllerEntries(theme: PresentationTheme, strings: Pr return entries } -public func callFeedbackController(sharedContext: SharedAccountContext, account: Account, callId: CallId, rating: Int, userInitiated: Bool) -> ViewController { +public func callFeedbackController(sharedContext: SharedAccountContextImpl, account: Account, callId: CallId, rating: Int, userInitiated: Bool) -> ViewController { let initialState = CallFeedbackState() let statePromise = ValuePromise(initialState, ignoreRepeated: true) let stateValue = Atomic(value: initialState) diff --git a/submodules/TelegramUI/TelegramUI/CallListCallItem.swift b/submodules/TelegramUI/TelegramUI/CallListCallItem.swift index 0f28398bf5..2e43b452e2 100644 --- a/submodules/TelegramUI/TelegramUI/CallListCallItem.swift +++ b/submodules/TelegramUI/TelegramUI/CallListCallItem.swift @@ -6,6 +6,7 @@ import Display import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ItemListUI private let titleFont = Font.regular(17.0) private let statusFont = Font.regular(14.0) diff --git a/submodules/TelegramUI/TelegramUI/CallListController.swift b/submodules/TelegramUI/TelegramUI/CallListController.swift index f303818a79..5bff7fc8c5 100644 --- a/submodules/TelegramUI/TelegramUI/CallListController.swift +++ b/submodules/TelegramUI/TelegramUI/CallListController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import ItemListUI public enum CallListControllerMode { case tab @@ -22,7 +23,7 @@ public final class CallListController: ViewController { return self._ready } - private let context: AccountContext + private let context: AccountContextImpl private let mode: CallListControllerMode private var presentationData: PresentationData @@ -37,7 +38,7 @@ public final class CallListController: ViewController { private let createActionDisposable = MetaDisposable() - public init(context: AccountContext, mode: CallListControllerMode) { + public init(context: AccountContextImpl, mode: CallListControllerMode) { self.context = context self.mode = mode self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/CallListControllerNode.swift b/submodules/TelegramUI/TelegramUI/CallListControllerNode.swift index 2c63e541d7..3988aca6cc 100644 --- a/submodules/TelegramUI/TelegramUI/CallListControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/CallListControllerNode.swift @@ -7,6 +7,7 @@ import TelegramCore import SwiftSignalKit import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private struct CallListNodeListViewTransition { let callListView: CallListNodeView @@ -155,7 +156,7 @@ private final class CallListOpaqueTransactionState { } final class CallListControllerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private let mode: CallListControllerMode private var presentationData: PresentationData @@ -194,7 +195,7 @@ final class CallListControllerNode: ASDisplayNode { private let emptyStatePromise = Promise() private let emptyStateDisposable = MetaDisposable() - init(context: AccountContext, mode: CallListControllerMode, presentationData: PresentationData, call: @escaping (PeerId) -> Void, openInfo: @escaping (PeerId, [Message]) -> Void, emptyStateUpdated: @escaping (Bool) -> Void) { + init(context: AccountContextImpl, mode: CallListControllerMode, presentationData: PresentationData, call: @escaping (PeerId) -> Void, openInfo: @escaping (PeerId, [Message]) -> Void, emptyStateUpdated: @escaping (Bool) -> Void) { self.context = context self.mode = mode self.presentationData = presentationData diff --git a/submodules/TelegramUI/TelegramUI/CallListNodeEntries.swift b/submodules/TelegramUI/TelegramUI/CallListNodeEntries.swift index d76f3147a9..bff7f0df2e 100644 --- a/submodules/TelegramUI/TelegramUI/CallListNodeEntries.swift +++ b/submodules/TelegramUI/TelegramUI/CallListNodeEntries.swift @@ -3,6 +3,7 @@ import UIKit import Postbox import TelegramCore import TelegramPresentationData +import MergeLists enum CallListNodeEntryId: Hashable { case setting(Int32) diff --git a/submodules/TelegramUI/TelegramUI/CallListViewTransition.swift b/submodules/TelegramUI/TelegramUI/CallListViewTransition.swift index f4417ff6f7..d16b6665d9 100644 --- a/submodules/TelegramUI/TelegramUI/CallListViewTransition.swift +++ b/submodules/TelegramUI/TelegramUI/CallListViewTransition.swift @@ -4,6 +4,7 @@ import Postbox import TelegramCore import SwiftSignalKit import Display +import MergeLists struct CallListNodeView { let originalView: CallListView diff --git a/submodules/TelegramUI/TelegramUI/CallRatingController.swift b/submodules/TelegramUI/TelegramUI/CallRatingController.swift index be97c259b4..ccdd9a1c71 100644 --- a/submodules/TelegramUI/TelegramUI/CallRatingController.swift +++ b/submodules/TelegramUI/TelegramUI/CallRatingController.swift @@ -263,7 +263,7 @@ func rateCallAndSendLogs(account: Account, callId: CallId, starsCount: Int, comm } } -func callRatingController(sharedContext: SharedAccountContext, account: Account, callId: CallId, userInitiated: Bool, present: @escaping (ViewController, Any) -> Void) -> AlertController { +func callRatingController(sharedContext: SharedAccountContextImpl, account: Account, callId: CallId, userInitiated: Bool, present: @escaping (ViewController, Any) -> Void) -> AlertController { let presentationData = sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/CallSuggestTabController.swift b/submodules/TelegramUI/TelegramUI/CallSuggestTabController.swift index 0c55d41b08..18ad26c7d6 100644 --- a/submodules/TelegramUI/TelegramUI/CallSuggestTabController.swift +++ b/submodules/TelegramUI/TelegramUI/CallSuggestTabController.swift @@ -200,7 +200,7 @@ private final class CallSuggestTabAlertContentNode: AlertContentNode { } } -func callSuggestTabController(sharedContext: SharedAccountContext) -> AlertController { +func callSuggestTabController(sharedContext: SharedAccountContextImpl) -> AlertController { let presentationData = sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/ChangePhoneNumberCodeController.swift b/submodules/TelegramUI/TelegramUI/ChangePhoneNumberCodeController.swift index 439926dff0..6a20d64c4b 100644 --- a/submodules/TelegramUI/TelegramUI/ChangePhoneNumberCodeController.swift +++ b/submodules/TelegramUI/TelegramUI/ChangePhoneNumberCodeController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private final class ChangePhoneNumberCodeControllerArguments { let updateEntryText: (String) -> Void @@ -170,7 +171,7 @@ protocol ChangePhoneNumberCodeController: class { private final class ChangePhoneNumberCodeControllerImpl: ItemListController, ChangePhoneNumberCodeController { private let applyCodeImpl: (Int) -> Void - init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, ChangePhoneNumberCodeEntry.ItemGenerationArguments)), NoError>, applyCodeImpl: @escaping (Int) -> Void) { + init(context: AccountContextImpl, state: Signal<(ItemListControllerState, (ItemListNodeState, ChangePhoneNumberCodeEntry.ItemGenerationArguments)), NoError>, applyCodeImpl: @escaping (Int) -> Void) { self.applyCodeImpl = applyCodeImpl let presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -186,7 +187,7 @@ private final class ChangePhoneNumberCodeControllerImpl: ItemListController ViewController { +func changePhoneNumberCodeController(context: AccountContextImpl, phoneNumber: String, codeData: ChangeAccountPhoneNumberData) -> ViewController { let initialState = ChangePhoneNumberCodeControllerState(codeText: "", checking: false) let statePromise = ValuePromise(initialState, ignoreRepeated: true) diff --git a/submodules/TelegramUI/TelegramUI/ChangePhoneNumberController.swift b/submodules/TelegramUI/TelegramUI/ChangePhoneNumberController.swift index a9d1979fb0..b280c0d0db 100644 --- a/submodules/TelegramUI/TelegramUI/ChangePhoneNumberController.swift +++ b/submodules/TelegramUI/TelegramUI/ChangePhoneNumberController.swift @@ -5,13 +5,14 @@ import AsyncDisplayKit import TelegramCore import SwiftSignalKit import TelegramPresentationData +import ProgressNavigationButtonNode final class ChangePhoneNumberController: ViewController { private var controllerNode: ChangePhoneNumberControllerNode { return self.displayNode as! ChangePhoneNumberControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private var currentData: (Int32, String?, String)? private let requestDisposable = MetaDisposable() @@ -33,7 +34,7 @@ final class ChangePhoneNumberController: ViewController { private var presentationData: PresentationData - init(context: AccountContext) { + init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/ChangePhoneNumberIntroController.swift b/submodules/TelegramUI/TelegramUI/ChangePhoneNumberIntroController.swift index 1e54001786..bf550f1322 100644 --- a/submodules/TelegramUI/TelegramUI/ChangePhoneNumberIntroController.swift +++ b/submodules/TelegramUI/TelegramUI/ChangePhoneNumberIntroController.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import TelegramCore import TelegramPresentationData +import TextFormat private final class ChangePhoneNumberIntroControllerNode: ASDisplayNode { var presentationData: PresentationData @@ -46,7 +47,7 @@ private final class ChangePhoneNumberIntroControllerNode: ASDisplayNode { } func animateOut() { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { [weak self] _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in if let strongSelf = self { strongSelf.dismiss?() } @@ -78,12 +79,12 @@ private final class ChangePhoneNumberIntroControllerNode: ASDisplayNode { } final class ChangePhoneNumberIntroController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private var didPlayPresentationAnimation = false private var presentationData: PresentationData - init(context: AccountContext, phoneNumber: String) { + init(context: AccountContextImpl, phoneNumber: String) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift b/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift index f2f180eacb..1613874f38 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private let rankMaxLength: Int32 = 16 @@ -742,7 +743,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s return entries } -public func channelAdminController(context: AccountContext, peerId: PeerId, adminId: PeerId, initialParticipant: ChannelParticipant?, updated: @escaping (TelegramChatAdminRights) -> Void, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void, transferedOwnership: @escaping (PeerId) -> Void) -> ViewController { +public func channelAdminController(context: AccountContextImpl, peerId: PeerId, adminId: PeerId, initialParticipant: ChannelParticipant?, updated: @escaping (TelegramChatAdminRights) -> Void, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void, transferedOwnership: @escaping (PeerId) -> Void) -> ViewController { let statePromise = ValuePromise(ChannelAdminControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: ChannelAdminControllerState()) let updateState: ((ChannelAdminControllerState) -> ChannelAdminControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/ChannelAdminsController.swift b/submodules/TelegramUI/TelegramUI/ChannelAdminsController.swift index e48d51d41a..4a4559987b 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelAdminsController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelAdminsController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class ChannelAdminsControllerArguments { let account: Account @@ -478,7 +479,7 @@ private func channelAdminsControllerEntries(presentationData: PresentationData, return entries } -public func channelAdminsController(context: AccountContext, peerId: PeerId, loadCompleted: @escaping () -> Void = {}) -> ViewController { +public func channelAdminsController(context: AccountContextImpl, peerId: PeerId, loadCompleted: @escaping () -> Void = {}) -> ViewController { let statePromise = ValuePromise(ChannelAdminsControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: ChannelAdminsControllerState()) let updateState: ((ChannelAdminsControllerState) -> ChannelAdminsControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/ChannelBannedMemberController.swift b/submodules/TelegramUI/TelegramUI/ChannelBannedMemberController.swift index 2a0da2efda..2b3558b570 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelBannedMemberController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelBannedMemberController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private final class ChannelBannedMemberControllerArguments { let account: Account @@ -367,7 +368,7 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation return entries } -public func channelBannedMemberController(context: AccountContext, peerId: PeerId, memberId: PeerId, initialParticipant: ChannelParticipant?, updated: @escaping (TelegramChatBannedRights?) -> Void, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void) -> ViewController { +public func channelBannedMemberController(context: AccountContextImpl, peerId: PeerId, memberId: PeerId, initialParticipant: ChannelParticipant?, updated: @escaping (TelegramChatBannedRights?) -> Void, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void) -> ViewController { let initialState = ChannelBannedMemberControllerState(referenceTimestamp: Int32(Date().timeIntervalSince1970), updatedFlags: nil, updatedTimeout: nil, updating: false) let statePromise = ValuePromise(initialState, ignoreRepeated: true) let stateValue = Atomic(value: initialState) diff --git a/submodules/TelegramUI/TelegramUI/ChannelBlacklistController.swift b/submodules/TelegramUI/TelegramUI/ChannelBlacklistController.swift index 01b1660f7c..1d492e20d6 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelBlacklistController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelBlacklistController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class ChannelBlacklistControllerArguments { let account: Account @@ -259,7 +260,7 @@ private func channelBlacklistControllerEntries(presentationData: PresentationDat return entries } -public func channelBlacklistController(context: AccountContext, peerId: PeerId) -> ViewController { +public func channelBlacklistController(context: AccountContextImpl, peerId: PeerId) -> ViewController { let statePromise = ValuePromise(ChannelBlacklistControllerState(referenceTimestamp: Int32(Date().timeIntervalSince1970)), ignoreRepeated: true) let stateValue = Atomic(value: ChannelBlacklistControllerState(referenceTimestamp: Int32(Date().timeIntervalSince1970))) let updateState: ((ChannelBlacklistControllerState) -> ChannelBlacklistControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupActionSheetItem.swift b/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupActionSheetItem.swift index 3c56493f56..0dbb49edf2 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupActionSheetItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupActionSheetItem.swift @@ -8,12 +8,12 @@ import TelegramCore import TelegramPresentationData final class ChannelDiscussionGroupActionSheetItem: ActionSheetItem { - let context: AccountContext + let context: AccountContextImpl let channelPeer: Peer let groupPeer: Peer let strings: PresentationStrings - init(context: AccountContext, channelPeer: Peer, groupPeer: Peer, strings: PresentationStrings) { + init(context: AccountContextImpl, channelPeer: Peer, groupPeer: Peer, strings: PresentationStrings) { self.context = context self.channelPeer = channelPeer self.groupPeer = groupPeer @@ -38,7 +38,7 @@ private final class ChannelDiscussionGroupActionSheetItemNode: ActionSheetItemNo private let groupAvatarNode: AvatarNode private let textNode: ImmediateTextNode - init(theme: ActionSheetControllerTheme, context: AccountContext, channelPeer: Peer, groupPeer: Peer, strings: PresentationStrings) { + init(theme: ActionSheetControllerTheme, context: AccountContextImpl, channelPeer: Peer, groupPeer: Peer, strings: PresentationStrings) { self.theme = theme self.channelAvatarNode = AvatarNode(font: avatarFont) diff --git a/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSearchContainerNode.swift b/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSearchContainerNode.swift index afa447837f..9ffa00e41b 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSearchContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSearchContainerNode.swift @@ -7,6 +7,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import MergeLists private enum ChannelDiscussionGroupSearchContent: Equatable { case peer(Peer) @@ -94,7 +95,7 @@ private struct ChannelDiscussionGroupSearchContainerState: Equatable { } final class ChannelDiscussionGroupSearchContainerNode: SearchDisplayControllerContentNode { - private let context: AccountContext + private let context: AccountContextImpl private let openPeer: (Peer) -> Void private let dimNode: ASDisplayNode @@ -111,7 +112,7 @@ final class ChannelDiscussionGroupSearchContainerNode: SearchDisplayControllerCo private let themeAndStringsPromise: Promise<(PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder, PresentationDateTimeFormat)> - init(context: AccountContext, peers: [Peer], openPeer: @escaping (Peer) -> Void) { + init(context: AccountContextImpl, peers: [Peer], openPeer: @escaping (Peer) -> Void) { self.context = context self.openPeer = openPeer diff --git a/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupController.swift b/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupController.swift index a683579b17..46b8d0bb38 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class ChannelDiscussionGroupSetupControllerArguments { let account: Account @@ -197,7 +198,7 @@ private struct ChannelDiscussionGroupSetupControllerState: Equatable { var searching: Bool = false } -public func channelDiscussionGroupSetupController(context: AccountContext, peerId: PeerId) -> ViewController { +public func channelDiscussionGroupSetupController(context: AccountContextImpl, peerId: PeerId) -> ViewController { let statePromise = ValuePromise(ChannelDiscussionGroupSetupControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: ChannelDiscussionGroupSetupControllerState()) let updateState: ((ChannelDiscussionGroupSetupControllerState) -> ChannelDiscussionGroupSetupControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupHeaderItem.swift b/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupHeaderItem.swift index 6fad4b7ba0..644872f784 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupHeaderItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupHeaderItem.swift @@ -4,6 +4,8 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI +import TextFormat class ChannelDiscussionGroupSetupHeaderItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupSearchItem.swift b/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupSearchItem.swift index 5472b4ebc6..6eff16a1b5 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupSearchItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelDiscussionGroupSetupSearchItem.swift @@ -6,15 +6,16 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import ItemListUI final class ChannelDiscussionGroupSetupSearchItem: ItemListControllerSearch { - let context: AccountContext + let context: AccountContextImpl let peers: [Peer] let cancel: () -> Void let dismissInput: () -> Void let openPeer: (Peer) -> Void - init(context: AccountContext, peers: [Peer], cancel: @escaping () -> Void, dismissInput: @escaping () -> Void, openPeer: @escaping (Peer) -> Void) { + init(context: AccountContextImpl, peers: [Peer], cancel: @escaping () -> Void, dismissInput: @escaping () -> Void, openPeer: @escaping (Peer) -> Void) { self.context = context self.peers = peers self.cancel = cancel @@ -56,7 +57,7 @@ final class ChannelDiscussionGroupSetupSearchItem: ItemListControllerSearch { private final class ChannelDiscussionGroupSetupSearchItemNode: ItemListControllerSearchNode { private let containerNode: ChannelDiscussionGroupSearchContainerNode - init(context: AccountContext, peers: [Peer], openPeer: @escaping (Peer) -> Void, cancel: @escaping () -> Void, updateActivity: @escaping (Bool) -> Void, dismissInput: @escaping () -> Void) { + init(context: AccountContextImpl, peers: [Peer], openPeer: @escaping (Peer) -> Void, cancel: @escaping () -> Void, updateActivity: @escaping (Bool) -> Void, dismissInput: @escaping () -> Void) { self.containerNode = ChannelDiscussionGroupSearchContainerNode(context: context, peers: peers, openPeer: { peer in openPeer(peer) }) diff --git a/submodules/TelegramUI/TelegramUI/ChannelInfoController.swift b/submodules/TelegramUI/TelegramUI/ChannelInfoController.swift index 2a3beaf74f..7e1b07dc17 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelInfoController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelInfoController.swift @@ -7,6 +7,9 @@ import Postbox import TelegramCore import LegacyComponents import TelegramPresentationData +import ItemListUI +import AccountContext +import TextFormat private final class ChannelInfoControllerArguments { let account: Account @@ -624,7 +627,7 @@ private func valuesRequiringUpdate(state: ChannelInfoState, view: PeerView) -> ( } } -public func channelInfoController(context: AccountContext, peerId: PeerId) -> ViewController { +public func channelInfoController(context: AccountContextImpl, peerId: PeerId) -> ViewController { let statePromise = ValuePromise(ChannelInfoState(), ignoreRepeated: true) let stateValue = Atomic(value: ChannelInfoState()) let updateState: ((ChannelInfoState) -> ChannelInfoState) -> Void = { f in @@ -711,7 +714,7 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi } let completedImpl: (UIImage) -> Void = { image in - if let data = UIImageJPEGRepresentation(image, 0.6) { + if let data = image.jpegData(compressionQuality: 0.6) { let resource = LocalFileMediaResource(fileId: arc4random64()) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) let representation = TelegramMediaImageRepresentation(dimensions: CGSize(width: 640.0, height: 640.0), resource: resource) @@ -1155,9 +1158,9 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi } } } - aboutLinkActionImpl = { [weak controller] action, itemLink in - if let controller = controller { - handleTextLinkAction(context: context, peerId: peerId, navigateDisposable: navigateDisposable, controller: controller, action: action, itemLink: itemLink) + aboutLinkActionImpl = { [weak context, weak controller] action, itemLink in + if let controller = controller, let context = context { + context.sharedContext.handleTextLinkAction(context: context, peerId: peerId, navigateDisposable: navigateDisposable, controller: controller, action: action, itemLink: itemLink) } } endEditingImpl = { diff --git a/submodules/TelegramUI/TelegramUI/ChannelMembersController.swift b/submodules/TelegramUI/TelegramUI/ChannelMembersController.swift index cdfb7ab7aa..de6c498f97 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelMembersController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelMembersController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class ChannelMembersControllerArguments { let account: Account @@ -254,7 +255,7 @@ private struct ChannelMembersControllerState: Equatable { } } -private func ChannelMembersControllerEntries(context: AccountContext, presentationData: PresentationData, view: PeerView, state: ChannelMembersControllerState, participants: [RenderedChannelParticipant]?) -> [ChannelMembersEntry] { +private func ChannelMembersControllerEntries(context: AccountContextImpl, presentationData: PresentationData, view: PeerView, state: ChannelMembersControllerState, participants: [RenderedChannelParticipant]?) -> [ChannelMembersEntry] { if participants == nil || participants?.count == nil { return [] } @@ -322,7 +323,7 @@ private func ChannelMembersControllerEntries(context: AccountContext, presentati return entries } -public func channelMembersController(context: AccountContext, peerId: PeerId) -> ViewController { +public func channelMembersController(context: AccountContextImpl, peerId: PeerId) -> ViewController { let statePromise = ValuePromise(ChannelMembersControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: ChannelMembersControllerState()) let updateState: ((ChannelMembersControllerState) -> ChannelMembersControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/ChannelMembersSearchContainerNode.swift b/submodules/TelegramUI/TelegramUI/ChannelMembersSearchContainerNode.swift index 77d57c7bf3..8908bc184c 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelMembersSearchContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelMembersSearchContainerNode.swift @@ -7,6 +7,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import MergeLists enum ChannelMembersSearchMode { case searchMembers @@ -190,7 +191,7 @@ private enum GroupMemberCategory { case members } -private func categorySignal(context: AccountContext, peerId: PeerId, category: GroupMemberCategory) -> Signal<[RenderedChannelParticipant], NoError> { +private func categorySignal(context: AccountContextImpl, peerId: PeerId, category: GroupMemberCategory) -> Signal<[RenderedChannelParticipant], NoError> { return Signal<[RenderedChannelParticipant], NoError> { subscriber in let disposableAndLoadMoreControl: (Disposable, PeerChannelMemberCategoryControl?) func processListState(_ listState: ChannelMemberListState) { @@ -233,7 +234,7 @@ private struct GroupMembersSearchContextState { final class GroupMembersSearchContext { fileprivate let state = Promise() - init(context: AccountContext, peerId: PeerId) { + init(context: AccountContextImpl, peerId: PeerId) { assert(Queue.mainQueue().isCurrent()) let combinedSignal = combineLatest(queue: .mainQueue(), categorySignal(context: context, peerId: peerId, category: .contacts), categorySignal(context: context, peerId: peerId, category: .bots), categorySignal(context: context, peerId: peerId, category: .admins), categorySignal(context: context, peerId: peerId, category: .members)) @@ -267,7 +268,7 @@ private struct ChannelMembersSearchContainerState: Equatable { } final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNode { - private let context: AccountContext + private let context: AccountContextImpl private let openPeer: (Peer, RenderedChannelParticipant?) -> Void private let mode: ChannelMembersSearchMode @@ -289,7 +290,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod private let themeAndStringsPromise: Promise<(PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder, PresentationDateTimeFormat)> - init(context: AccountContext, peerId: PeerId, mode: ChannelMembersSearchMode, filters: [ChannelMembersSearchFilter], searchContext: GroupMembersSearchContext?, openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, updateActivity: @escaping (Bool) -> Void, present: @escaping (ViewController, Any?) -> Void) { + init(context: AccountContextImpl, peerId: PeerId, mode: ChannelMembersSearchMode, filters: [ChannelMembersSearchFilter], searchContext: GroupMembersSearchContext?, openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, updateActivity: @escaping (Bool) -> Void, present: @escaping (ViewController, Any?) -> Void) { self.context = context self.openPeer = openPeer self.mode = mode diff --git a/submodules/TelegramUI/TelegramUI/ChannelMembersSearchController.swift b/submodules/TelegramUI/TelegramUI/ChannelMembersSearchController.swift index 0c88ce4987..85f60b1e55 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelMembersSearchController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelMembersSearchController.swift @@ -19,7 +19,7 @@ enum ChannelMembersSearchFilter { final class ChannelMembersSearchController: ViewController { private let queue = Queue() - private let context: AccountContext + private let context: AccountContextImpl private let peerId: PeerId private let mode: ChannelMembersSearchControllerMode private let filters: [ChannelMembersSearchFilter] @@ -35,7 +35,7 @@ final class ChannelMembersSearchController: ViewController { private var searchContentNode: NavigationBarSearchContentNode? - init(context: AccountContext, peerId: PeerId, mode: ChannelMembersSearchControllerMode, filters: [ChannelMembersSearchFilter] = [], openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void) { + init(context: AccountContextImpl, peerId: PeerId, mode: ChannelMembersSearchControllerMode, filters: [ChannelMembersSearchFilter] = [], openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void) { self.context = context self.peerId = peerId self.mode = mode diff --git a/submodules/TelegramUI/TelegramUI/ChannelMembersSearchControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChannelMembersSearchControllerNode.swift index 8df872bf6f..64472e0c28 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelMembersSearchControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelMembersSearchControllerNode.swift @@ -7,6 +7,7 @@ import TelegramCore import SwiftSignalKit import TelegramPresentationData import TelegramUIPreferences +import MergeLists private final class ChannelMembersSearchInteraction { let openPeer: (Peer, RenderedChannelParticipant?) -> Void @@ -86,7 +87,7 @@ private func preparedTransition(from fromEntries: [ChannelMembersSearchEntry]?, } class ChannelMembersSearchControllerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private let peerId: PeerId private let mode: ChannelMembersSearchControllerMode private let filters: [ChannelMembersSearchFilter] @@ -109,7 +110,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode { private var disposable: Disposable? private var listControl: PeerChannelMemberCategoryControl? - init(context: AccountContext, presentationData: PresentationData, peerId: PeerId, mode: ChannelMembersSearchControllerMode, filters: [ChannelMembersSearchFilter]) { + init(context: AccountContextImpl, presentationData: PresentationData, peerId: PeerId, mode: ChannelMembersSearchControllerMode, filters: [ChannelMembersSearchFilter]) { self.context = context self.listNode = ListView() self.peerId = peerId @@ -388,7 +389,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode { } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/ChannelOwnershipTransferController.swift b/submodules/TelegramUI/TelegramUI/ChannelOwnershipTransferController.swift index dfca4096cd..0a192358f1 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelOwnershipTransferController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelOwnershipTransferController.swift @@ -6,6 +6,8 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ActivityIndicator +import TextFormat private final class ChannelOwnershipTransferPasswordFieldNode: ASDisplayNode, UITextFieldDelegate { private var theme: PresentationTheme @@ -70,7 +72,7 @@ private final class ChannelOwnershipTransferPasswordFieldNode: ASDisplayNode, UI override func didLoad() { super.didLoad() - self.textInputNode.textField.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(14.0), NSAttributedStringKey.foregroundColor.rawValue: self.theme.actionSheet.inputTextColor] + self.textInputNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(14.0), NSAttributedString.Key.foregroundColor: self.theme.actionSheet.inputTextColor] self.textInputNode.textField.font = Font.regular(14.0) self.textInputNode.textField.textColor = self.theme.list.itemPrimaryTextColor self.textInputNode.textField.isSecureTextEntry = true @@ -88,7 +90,7 @@ private final class ChannelOwnershipTransferPasswordFieldNode: ASDisplayNode, UI self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 16.0, color: theme.actionSheet.inputHollowBackgroundColor, strokeColor: theme.actionSheet.inputBorderColor, strokeWidth: UIScreenPixel) self.textInputNode.textField.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance self.textInputNode.textField.textColor = theme.list.itemPrimaryTextColor - self.textInputNode.textField.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(14.0), NSAttributedStringKey.foregroundColor.rawValue: theme.actionSheet.inputTextColor] + self.textInputNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(14.0), NSAttributedString.Key.foregroundColor: theme.actionSheet.inputTextColor] self.placeholderNode.attributedText = NSAttributedString(string: self.placeholderNode.attributedText?.string ?? "", font: Font.regular(14.0), textColor: theme.actionSheet.inputPlaceholderColor) } @@ -397,7 +399,7 @@ private final class ChannelOwnershipTransferAlertContentNode: AlertContentNode { } } -private func commitChannelOwnershipTransferController(context: AccountContext, peer: Peer, member: TelegramUser, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (PeerId?) -> Void) -> ViewController { +private func commitChannelOwnershipTransferController(context: AccountContextImpl, peer: Peer, member: TelegramUser, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (PeerId?) -> Void) -> ViewController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } var dismissImpl: (() -> Void)? @@ -495,7 +497,7 @@ private func commitChannelOwnershipTransferController(context: AccountContext, p return controller } -private func confirmChannelOwnershipTransferController(context: AccountContext, peer: Peer, member: TelegramUser, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (PeerId?) -> Void) -> ViewController { +private func confirmChannelOwnershipTransferController(context: AccountContextImpl, peer: Peer, member: TelegramUser, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (PeerId?) -> Void) -> ViewController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = AlertControllerTheme(presentationTheme: presentationData.theme) @@ -526,7 +528,7 @@ private func confirmChannelOwnershipTransferController(context: AccountContext, return controller } -func channelOwnershipTransferController(context: AccountContext, peer: Peer, member: TelegramUser, initialError: ChannelOwnershipTransferError, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (PeerId?) -> Void) -> ViewController { +func channelOwnershipTransferController(context: AccountContextImpl, peer: Peer, member: TelegramUser, initialError: ChannelOwnershipTransferError, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (PeerId?) -> Void) -> ViewController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = AlertControllerTheme(presentationTheme: presentationData.theme) diff --git a/submodules/TelegramUI/TelegramUI/ChannelPermissionsController.swift b/submodules/TelegramUI/TelegramUI/ChannelPermissionsController.swift index d222f50741..670c580c65 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelPermissionsController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelPermissionsController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class ChannelPermissionsControllerArguments { let account: Account @@ -445,7 +446,7 @@ private func channelPermissionsControllerEntries(presentationData: PresentationD return entries } -public func channelPermissionsController(context: AccountContext, peerId originalPeerId: PeerId, loadCompleted: @escaping () -> Void = {}) -> ViewController { +public func channelPermissionsController(context: AccountContextImpl, peerId originalPeerId: PeerId, loadCompleted: @escaping () -> Void = {}) -> ViewController { let statePromise = ValuePromise(ChannelPermissionsControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: ChannelPermissionsControllerState()) let updateState: ((ChannelPermissionsControllerState) -> ChannelPermissionsControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/ChannelStatsController.swift b/submodules/TelegramUI/TelegramUI/ChannelStatsController.swift index c6f2099e2d..b3b8cc4277 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelStatsController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelStatsController.swift @@ -6,19 +6,20 @@ import TelegramCore import SwiftSignalKit import Postbox import TelegramPresentationData +import ProgressNavigationButtonNode final class ChannelStatsController: ViewController { private var controllerNode: ChannelStatsControllerNode { return self.displayNode as! ChannelStatsControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let url: String private let peerId: PeerId private var presentationData: PresentationData - init(context: AccountContext, url: String, peerId: PeerId) { + init(context: AccountContextImpl, url: String, peerId: PeerId) { self.context = context self.url = url self.peerId = peerId diff --git a/submodules/TelegramUI/TelegramUI/ChannelStatsControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChannelStatsControllerNode.swift index 947a6f280f..c029f27a93 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelStatsControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelStatsControllerNode.swift @@ -11,7 +11,7 @@ import TelegramPresentationData final class ChannelStatsControllerNode: ViewControllerTracingNode, WKNavigationDelegate { private var webView: WKWebView? - private let context: AccountContext + private let context: AccountContextImpl private let peerId: PeerId var presentationData: PresentationData private let present: (ViewController, Any?) -> Void @@ -19,7 +19,7 @@ final class ChannelStatsControllerNode: ViewControllerTracingNode, WKNavigationD private let refreshDisposable = MetaDisposable() - init(context: AccountContext, presentationData: PresentationData, peerId: PeerId, url: String, present: @escaping (ViewController, Any?) -> Void, updateActivity: @escaping (Bool) -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, peerId: PeerId, url: String, present: @escaping (ViewController, Any?) -> Void, updateActivity: @escaping (Bool) -> Void) { self.context = context self.presentationData = presentationData self.peerId = peerId @@ -69,7 +69,7 @@ final class ChannelStatsControllerNode: ViewControllerTracingNode, WKNavigationD } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/ChannelVisibilityController.swift b/submodules/TelegramUI/TelegramUI/ChannelVisibilityController.swift index b01007f86f..d474c71171 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelVisibilityController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelVisibilityController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class ChannelVisibilityControllerArguments { let account: Account @@ -794,7 +795,7 @@ public enum ChannelVisibilityControllerMode { case privateLink } -public func channelVisibilityController(context: AccountContext, peerId: PeerId, mode: ChannelVisibilityControllerMode, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void) -> ViewController { +public func channelVisibilityController(context: AccountContextImpl, peerId: PeerId, mode: ChannelVisibilityControllerMode, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void) -> ViewController { let statePromise = ValuePromise(ChannelVisibilityControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: ChannelVisibilityControllerState()) let updateState: ((ChannelVisibilityControllerState) -> ChannelVisibilityControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/ChatAnimationGalleryItem.swift b/submodules/TelegramUI/TelegramUI/ChatAnimationGalleryItem.swift index 25432b9be3..02404adf3b 100644 --- a/submodules/TelegramUI/TelegramUI/ChatAnimationGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatAnimationGalleryItem.swift @@ -7,14 +7,15 @@ import Postbox import TelegramCore import Lottie import TelegramPresentationData +import AnimationUI class ChatAnimationGalleryItem: GalleryItem { - let context: AccountContext + let context: AccountContextImpl let presentationData: PresentationData let message: Message let location: MessageHistoryEntryLocation? - init(context: AccountContext, presentationData: PresentationData, message: Message, location: MessageHistoryEntryLocation?) { + init(context: AccountContextImpl, presentationData: PresentationData, message: Message, location: MessageHistoryEntryLocation?) { self.context = context self.presentationData = presentationData self.message = message @@ -65,7 +66,7 @@ private var backgroundButtonIcon: UIImage = { }() final class ChatAnimationGalleryItemNode: ZoomableContentGalleryItemNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private var message: Message? @@ -79,14 +80,14 @@ final class ChatAnimationGalleryItemNode: ZoomableContentGalleryItemNode { private let statusNode: RadialStatusNode private let footerContentNode: ChatItemGalleryFooterContentNode - private var contextAndMedia: (AccountContext, AnyMediaReference)? + private var contextAndMedia: (AccountContextImpl, AnyMediaReference)? private var disposable = MetaDisposable() private var fetchDisposable = MetaDisposable() private let statusDisposable = MetaDisposable() private var status: MediaResourceStatus? - init(context: AccountContext, presentationData: PresentationData) { + init(context: AccountContextImpl, presentationData: PresentationData) { self.context = context self.presentationData = presentationData @@ -131,7 +132,7 @@ final class ChatAnimationGalleryItemNode: ZoomableContentGalleryItemNode { self.footerContentNode.setMessage(message) } - func setFile(context: AccountContext, fileReference: FileMediaReference) { + func setFile(context: AccountContextImpl, fileReference: FileMediaReference) { if self.contextAndMedia == nil || !self.contextAndMedia!.1.media.isEqual(to: fileReference.media) { let signal = chatMessageAnimatedStrickerBackingData(postbox: context.account.postbox, fileReference: fileReference, synchronousLoad: false) |> mapToSignal { value -> Signal in @@ -297,7 +298,7 @@ final class ChatAnimationGalleryItemNode: ZoomableContentGalleryItemNode { }) self.statusNodeContainer.layer.animatePosition(from: self.statusNodeContainer.position, to: CGPoint(x: transformedSuperFrame.midX, y: transformedSuperFrame.midY), duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false) - self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false) + self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false) } override func visibilityUpdated(isVisible: Bool) { diff --git a/submodules/TelegramUI/TelegramUI/ChatBotInfoItem.swift b/submodules/TelegramUI/TelegramUI/ChatBotInfoItem.swift index 993f51b18a..d99aa273e8 100644 --- a/submodules/TelegramUI/TelegramUI/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatBotInfoItem.swift @@ -5,6 +5,8 @@ import AsyncDisplayKit import SwiftSignalKit import Postbox import TelegramCore +import TelegramPresentationData +import TextFormat private let messageFont = Font.regular(17.0) private let messageBoldFont = Font.semibold(17.0) @@ -232,7 +234,7 @@ final class ChatBotInfoItemNode: ListViewItemNode { TelegramTextAttributes.Hashtag ] for name in possibleNames { - if let _ = attributes[NSAttributedStringKey(rawValue: name)] { + if let _ = attributes[NSAttributedString.Key(rawValue: name)] { rects = self.textNode.attributeRects(name: name, at: index) break } @@ -263,19 +265,19 @@ final class ChatBotInfoItemNode: ListViewItemNode { func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture) -> ChatMessageBubbleContentTapAction { let textNodeFrame = self.textNode.frame if let (index, attributes) = self.textNode.attributesAtPoint(CGPoint(x: point.x - self.offsetContainer.frame.minX - textNodeFrame.minX, y: point.y - self.offsetContainer.frame.minY - textNodeFrame.minY)) { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { var concealed = true if let attributeText = self.textNode.attributeSubstring(name: TelegramTextAttributes.URL, index: index) { concealed = !doesUrlMatchText(url: url, text: attributeText) } return .url(url: url, concealed: concealed) - } else if let peerMention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { + } else if let peerMention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { return .peerMention(peerMention.peerId, peerMention.mention) - } else if let peerName = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let peerName = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { return .textMention(peerName) - } else if let botCommand = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.BotCommand)] as? String { + } else if let botCommand = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.BotCommand)] as? String { return .botCommand(botCommand) - } else if let hashtag = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { + } else if let hashtag = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { return .hashtag(hashtag.peerName, hashtag.hashtag) } else { return .none diff --git a/submodules/TelegramUI/TelegramUI/ChatBotStartInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatBotStartInputPanelNode.swift index 450c47aebe..e72895bc29 100644 --- a/submodules/TelegramUI/TelegramUI/ChatBotStartInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatBotStartInputPanelNode.swift @@ -47,7 +47,7 @@ final class ChatBotStartInputPanelNode: ChatInputPanelNode { self.strings = strings self.button = HighlightableButtonNode() - self.activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray) + self.activityIndicator = UIActivityIndicatorView(style: .gray) self.activityIndicator.isHidden = true super.init() diff --git a/submodules/TelegramUI/TelegramUI/ChatButtonKeyboardInputNode.swift b/submodules/TelegramUI/TelegramUI/ChatButtonKeyboardInputNode.swift index cff70ae640..38c55bc98c 100644 --- a/submodules/TelegramUI/TelegramUI/ChatButtonKeyboardInputNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatButtonKeyboardInputNode.swift @@ -29,7 +29,7 @@ private final class ChatButtonKeyboardInputButtonNode: ASButtonNode { } final class ChatButtonKeyboardInputNode: ChatInputNode { - private let context: AccountContext + private let context: AccountContextImpl private let controllerInteraction: ChatControllerInteraction private let separatorNode: ASDisplayNode @@ -40,7 +40,7 @@ final class ChatButtonKeyboardInputNode: ChatInputNode { private var theme: PresentationTheme? - init(context: AccountContext, controllerInteraction: ChatControllerInteraction) { + init(context: AccountContextImpl, controllerInteraction: ChatControllerInteraction) { self.context = context self.controllerInteraction = controllerInteraction diff --git a/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift index 0e36f74726..e23dad016a 100644 --- a/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift @@ -68,7 +68,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode { override init() { self.button = HighlightableButtonNode() self.discussButton = HighlightableButtonNode() - self.activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray) + self.activityIndicator = UIActivityIndicatorView(style: .gray) self.activityIndicator.isHidden = true self.discussButtonText = ImmediateTextNode() diff --git a/submodules/TelegramUI/TelegramUI/ChatContextResultPeekContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatContextResultPeekContentNode.swift index a6c04b94ec..ffebcec6b4 100644 --- a/submodules/TelegramUI/TelegramUI/ChatContextResultPeekContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatContextResultPeekContentNode.swift @@ -83,19 +83,19 @@ private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerCont let displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent)) self.displayLink = displayLink - displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + displayLink.add(to: RunLoop.main, forMode: .common) if #available(iOS 10.0, *) { displayLink.preferredFramesPerSecond = 25 } else { displayLink.frameInterval = 2 } displayLink.isPaused = false - CMTimebaseSetRate(self.timebase, 1.0) + CMTimebaseSetRate(self.timebase, rate: 1.0) } else if let displayLink = self.displayLink { self.displayLink = nil displayLink.isPaused = true displayLink.invalidate() - CMTimebaseSetRate(self.timebase, 0.0) + CMTimebaseSetRate(self.timebase, rate: 0.0) } } } @@ -120,8 +120,8 @@ private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerCont self.imageNode.displaysAsynchronously = false var timebase: CMTimebase? - CMTimebaseCreateWithMasterClock(nil, CMClockGetHostTimeClock(), &timebase) - CMTimebaseSetRate(timebase!, 0.0) + CMTimebaseCreateWithMasterClock(allocator: nil, masterClock: CMClockGetHostTimeClock(), timebaseOut: &timebase) + CMTimebaseSetRate(timebase!, rate: 0.0) self.timebase = timebase! super.init() diff --git a/submodules/TelegramUI/TelegramUI/ChatController.swift b/submodules/TelegramUI/TelegramUI/ChatController.swift index 8cd5957d1b..f1f1d084f8 100644 --- a/submodules/TelegramUI/TelegramUI/ChatController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatController.swift @@ -12,6 +12,7 @@ import LegacyComponents import TelegramPresentationData import TelegramUIPreferences import DeviceAccess +import TextFormat public enum ChatControllerPeekActions { case standard @@ -108,7 +109,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget, public var peekActions: ChatControllerPeekActions = .standard private var didSetup3dTouch: Bool = false - private let context: AccountContext + private let context: AccountContextImpl public let chatLocation: ChatLocation private let messageId: MessageId? private let botStart: ChatControllerInitialBotStart? @@ -263,7 +264,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget, var purposefulAction: (() -> Void)? - public init(context: AccountContext, chatLocation: ChatLocation, messageId: MessageId? = nil, botStart: ChatControllerInitialBotStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false)) { + public init(context: AccountContextImpl, chatLocation: ChatLocation, messageId: MessageId? = nil, botStart: ChatControllerInitialBotStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false)) { let _ = ChatControllerCount.modify { value in return value + 1 } @@ -558,7 +559,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget, text = "\(count) messages selected" } DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1, execute: { - UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, text as NSString) + UIAccessibility.post(notification: UIAccessibility.Notification.announcement, argument: text as NSString) }) } }, sendCurrentMessage: { [weak self] silentPosting in @@ -2631,7 +2632,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget, } else { text = "\(count) messages selected" } - UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, text) + UIAccessibility.post(notification: UIAccessibility.Notification.announcement, argument: text) } } }, deleteSelectedMessages: { [weak self] in @@ -7033,7 +7034,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget, }) if canEdit, let message = self.chatDisplayNode.historyNode.firstMessageForEditInCurrentHistoryView() { - inputShortcuts.append(KeyShortcut(input: UIKeyInputUpArrow, action: { [weak self] in + inputShortcuts.append(KeyShortcut(input: UIKeyCommand.inputUpArrow, action: { [weak self] in if let strongSelf = self { strongSelf.interfaceInteraction?.setupEditMessage(message.id) } @@ -7041,12 +7042,12 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget, } let otherShortcuts: [KeyShortcut] = [ - KeyShortcut(title: strings.KeyCommand_ScrollUp, input: UIKeyInputUpArrow, modifiers: [.shift], action: { [weak self] in + KeyShortcut(title: strings.KeyCommand_ScrollUp, input: UIKeyCommand.inputUpArrow, modifiers: [.shift], action: { [weak self] in if let strongSelf = self { _ = strongSelf.chatDisplayNode.historyNode.scrollWithDirection(.down, distance: 75.0) } }), - KeyShortcut(title: strings.KeyCommand_ScrollDown, input: UIKeyInputDownArrow, modifiers: [.shift], action: { [weak self] in + KeyShortcut(title: strings.KeyCommand_ScrollDown, input: UIKeyCommand.inputDownArrow, modifiers: [.shift], action: { [weak self] in if let strongSelf = self { _ = strongSelf.chatDisplayNode.historyNode.scrollWithDirection(.up, distance: 75.0) } diff --git a/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift index bfcdb88dca..8cf595e6f1 100644 --- a/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift @@ -7,6 +7,7 @@ import Display import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import TextFormat private final class ChatControllerNodeView: UITracingLayerView, WindowInputAccessoryHeightProvider, PreviewingHostView { var inputAccessoryHeight: (() -> CGFloat)? @@ -52,7 +53,7 @@ private struct ChatControllerNodeDerivedLayoutState { } class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { - let context: AccountContext + let context: AccountContextImpl let chatLocation: ChatLocation let controllerInteraction: ChatControllerInteraction private weak var controller: ChatController? @@ -186,7 +187,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } }*/ - init(context: AccountContext, chatLocation: ChatLocation, messageId: MessageId?, controllerInteraction: ChatControllerInteraction, chatPresentationInterfaceState: ChatPresentationInterfaceState, automaticMediaDownloadSettings: MediaAutoDownloadSettings, navigationBar: NavigationBar?, controller: ChatController?) { + init(context: AccountContextImpl, chatLocation: ChatLocation, messageId: MessageId?, controllerInteraction: ChatControllerInteraction, chatPresentationInterfaceState: ChatPresentationInterfaceState, automaticMediaDownloadSettings: MediaAutoDownloadSettings, navigationBar: NavigationBar?, controller: ChatController?) { self.context = context self.chatLocation = chatLocation self.controllerInteraction = controllerInteraction @@ -847,7 +848,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } } - self.loadingNode.updateLayout(size: contentBounds.size, insets: UIEdgeInsetsMake(containerInsets.top, 0.0, containerInsets.bottom + contentBottomInset, 0.0), transition: transition) + self.loadingNode.updateLayout(size: contentBounds.size, insets: UIEdgeInsets(top: containerInsets.top, left: 0.0, bottom: containerInsets.bottom + contentBottomInset, right: 0.0), transition: transition) if let containerNode = self.containerNode { contentBottomInset += 8.0 diff --git a/submodules/TelegramUI/TelegramUI/ChatDocumentGalleryItem.swift b/submodules/TelegramUI/TelegramUI/ChatDocumentGalleryItem.swift index 9e994f6f7b..5ec96c62c0 100644 --- a/submodules/TelegramUI/TelegramUI/ChatDocumentGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatDocumentGalleryItem.swift @@ -9,12 +9,12 @@ import TelegramCore import TelegramPresentationData class ChatDocumentGalleryItem: GalleryItem { - let context: AccountContext + let context: AccountContextImpl let presentationData: PresentationData let message: Message let location: MessageHistoryEntryLocation? - init(context: AccountContext, presentationData: PresentationData, message: Message, location: MessageHistoryEntryLocation?) { + init(context: AccountContextImpl, presentationData: PresentationData, message: Message, location: MessageHistoryEntryLocation?) { self.context = context self.presentationData = presentationData self.message = message @@ -93,7 +93,7 @@ class ChatDocumentGalleryItemNode: ZoomableContentGalleryItemNode, WKNavigationD private let webView: UIView - private var contextAndFile: (AccountContext, FileMediaReference)? + private var contextAndFile: (AccountContextImpl, FileMediaReference)? private let dataDisposable = MetaDisposable() private var itemIsVisible = false @@ -106,7 +106,7 @@ class ChatDocumentGalleryItemNode: ZoomableContentGalleryItemNode, WKNavigationD private let statusDisposable = MetaDisposable() private var status: MediaResourceStatus? - init(context: AccountContext, presentationData: PresentationData) { + init(context: AccountContextImpl, presentationData: PresentationData) { if #available(iOSApplicationExtension 11.0, iOS 11.0, *) { let preferences = WKPreferences() preferences.javaScriptEnabled = false @@ -165,7 +165,7 @@ class ChatDocumentGalleryItemNode: ZoomableContentGalleryItemNode, WKNavigationD return .single(.dark) } - func setFile(context: AccountContext, fileReference: FileMediaReference) { + func setFile(context: AccountContextImpl, fileReference: FileMediaReference) { let updateFile = self.contextAndFile?.1.media != fileReference.media self.contextAndFile = (context, fileReference) if updateFile { @@ -179,7 +179,7 @@ class ChatDocumentGalleryItemNode: ZoomableContentGalleryItemNode, WKNavigationD } } - private func setupStatus(context: AccountContext, resource: MediaResource) { + private func setupStatus(context: AccountContextImpl, resource: MediaResource) { self.statusDisposable.set((context.account.postbox.mediaBox.resourceStatus(resource) |> deliverOnMainQueue).start(next: { [weak self] status in if let strongSelf = self { @@ -369,7 +369,7 @@ class ChatDocumentGalleryItemNode: ZoomableContentGalleryItemNode, WKNavigationD }) self.statusNodeContainer.layer.animatePosition(from: self.statusNodeContainer.position, to: CGPoint(x: transformedSuperFrame.midX, y: transformedSuperFrame.midY), duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false) - self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false) + self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false) } override func footerContent() -> Signal { diff --git a/submodules/TelegramUI/TelegramUI/ChatExternalFileGalleryItem.swift b/submodules/TelegramUI/TelegramUI/ChatExternalFileGalleryItem.swift index 9e925fb975..73190f37a3 100644 --- a/submodules/TelegramUI/TelegramUI/ChatExternalFileGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatExternalFileGalleryItem.swift @@ -9,12 +9,12 @@ import TelegramCore import TelegramPresentationData class ChatExternalFileGalleryItem: GalleryItem { - let context: AccountContext + let context: AccountContextImpl let presentationData: PresentationData let message: Message let location: MessageHistoryEntryLocation? - init(context: AccountContext, presentationData: PresentationData, message: Message, location: MessageHistoryEntryLocation?) { + init(context: AccountContextImpl, presentationData: PresentationData, message: Message, location: MessageHistoryEntryLocation?) { self.context = context self.presentationData = presentationData self.message = message @@ -67,7 +67,7 @@ class ChatExternalFileGalleryItemNode: GalleryItemNode { private let actionTitleNode: ImmediateTextNode private let actionButtonNode: HighlightableButtonNode - private var contextAndFile: (AccountContext, FileMediaReference)? + private var contextAndFile: (AccountContextImpl, FileMediaReference)? private let dataDisposable = MetaDisposable() private var itemIsVisible = false @@ -80,7 +80,7 @@ class ChatExternalFileGalleryItemNode: GalleryItemNode { private let statusDisposable = MetaDisposable() private var status: MediaResourceStatus? - init(context: AccountContext, presentationData: PresentationData) { + init(context: AccountContextImpl, presentationData: PresentationData) { self.containerNode = ASDisplayNode() self.containerNode.backgroundColor = .white @@ -167,7 +167,7 @@ class ChatExternalFileGalleryItemNode: GalleryItemNode { return .single(.dark) } - func setFile(context: AccountContext, fileReference: FileMediaReference) { + func setFile(context: AccountContextImpl, fileReference: FileMediaReference) { let updateFile = self.contextAndFile?.1.media != fileReference.media self.contextAndFile = (context, fileReference) if updateFile { @@ -176,7 +176,7 @@ class ChatExternalFileGalleryItemNode: GalleryItemNode { } } - private func setupStatus(context: AccountContext, resource: MediaResource) { + private func setupStatus(context: AccountContextImpl, resource: MediaResource) { self.statusDisposable.set((context.account.postbox.mediaBox.resourceStatus(resource) |> deliverOnMainQueue).start(next: { [weak self] status in if let strongSelf = self { @@ -303,7 +303,7 @@ class ChatExternalFileGalleryItemNode: GalleryItemNode { }) self.statusNodeContainer.layer.animatePosition(from: self.statusNodeContainer.position, to: CGPoint(x: transformedSuperFrame.midX, y: transformedSuperFrame.midY), duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false) - self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false) + self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false) } override func footerContent() -> Signal { diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryEntry.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryEntry.swift index 5bd86c2ab5..6c03908e49 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryEntry.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryEntry.swift @@ -1,6 +1,7 @@ import Postbox import TelegramCore import TelegramPresentationData +import MergeLists public enum ChatHistoryMessageSelection: Equatable { case none diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryGridNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryGridNode.swift index 8b92fce4e7..47d6bb11e4 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryGridNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryGridNode.swift @@ -71,7 +71,7 @@ struct ChatHistoryGridViewTransition { let stationaryItems: GridNodeStationaryItems } -private func mappedInsertEntries(context: AccountContext, peerId: PeerId, controllerInteraction: ChatControllerInteraction, entries: [ChatHistoryViewTransitionInsertEntry], theme: PresentationTheme, strings: PresentationStrings) -> [GridNodeInsertItem] { +private func mappedInsertEntries(context: AccountContextImpl, peerId: PeerId, controllerInteraction: ChatControllerInteraction, entries: [ChatHistoryViewTransitionInsertEntry], theme: PresentationTheme, strings: PresentationStrings) -> [GridNodeInsertItem] { return entries.map { entry -> GridNodeInsertItem in switch entry.entry { case let .MessageEntry(message, _, _, _, _, _): @@ -88,7 +88,7 @@ private func mappedInsertEntries(context: AccountContext, peerId: PeerId, contro } } -private func mappedUpdateEntries(context: AccountContext, peerId: PeerId, controllerInteraction: ChatControllerInteraction, entries: [ChatHistoryViewTransitionUpdateEntry], theme: PresentationTheme, strings: PresentationStrings) -> [GridNodeUpdateItem] { +private func mappedUpdateEntries(context: AccountContextImpl, peerId: PeerId, controllerInteraction: ChatControllerInteraction, entries: [ChatHistoryViewTransitionUpdateEntry], theme: PresentationTheme, strings: PresentationStrings) -> [GridNodeUpdateItem] { return entries.map { entry -> GridNodeUpdateItem in switch entry.entry { case let .MessageEntry(message, _, _, _, _, _): @@ -105,7 +105,7 @@ private func mappedUpdateEntries(context: AccountContext, peerId: PeerId, contro } } -private func mappedChatHistoryViewListTransition(context: AccountContext, peerId: PeerId, controllerInteraction: ChatControllerInteraction, transition: ChatHistoryViewTransition, from: ChatHistoryView?, presentationData: ChatPresentationData) -> ChatHistoryGridViewTransition { +private func mappedChatHistoryViewListTransition(context: AccountContextImpl, peerId: PeerId, controllerInteraction: ChatControllerInteraction, transition: ChatHistoryViewTransition, from: ChatHistoryView?, presentationData: ChatPresentationData) -> ChatHistoryGridViewTransition { var mappedScrollToItem: GridNodeScrollToItem? if let scrollToItem = transition.scrollToItem { let mappedPosition: GridNodeScrollToItemPosition @@ -196,7 +196,7 @@ private func gridNodeLayoutForContainerLayout(size: CGSize) -> GridNodeLayoutTyp } public final class ChatHistoryGridNode: GridNode, ChatHistoryNode { - private let context: AccountContext + private let context: AccountContextImpl private let peerId: PeerId private let messageId: MessageId? private let tagMask: MessageTags? @@ -236,7 +236,7 @@ public final class ChatHistoryGridNode: GridNode, ChatHistoryNode { private var loadStateUpdated: ((ChatHistoryNodeLoadState, Bool) -> Void)? private let controllerInteraction: ChatControllerInteraction - public init(context: AccountContext, peerId: PeerId, messageId: MessageId?, tagMask: MessageTags?, controllerInteraction: ChatControllerInteraction) { + public init(context: AccountContextImpl, peerId: PeerId, messageId: MessageId?, tagMask: MessageTags?, controllerInteraction: ChatControllerInteraction) { self.context = context self.peerId = peerId self.messageId = messageId diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift index 61c0929385..4c409c7488 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift @@ -173,7 +173,7 @@ private func maxMessageIndexForEntries(_ view: ChatHistoryView, indexRange: (Int return (incoming, overall) } -private func mappedInsertEntries(context: AccountContext, chatLocation: ChatLocation, associatedData: ChatMessageItemAssociatedData, controllerInteraction: ChatControllerInteraction, mode: ChatHistoryListMode, entries: [ChatHistoryViewTransitionInsertEntry]) -> [ListViewInsertItem] { +private func mappedInsertEntries(context: AccountContextImpl, chatLocation: ChatLocation, associatedData: ChatMessageItemAssociatedData, controllerInteraction: ChatControllerInteraction, mode: ChatHistoryListMode, entries: [ChatHistoryViewTransitionInsertEntry]) -> [ListViewInsertItem] { return entries.map { entry -> ListViewInsertItem in switch entry.entry { case let .MessageEntry(message, presentationData, read, _, selection, attributes): @@ -207,7 +207,7 @@ private func mappedInsertEntries(context: AccountContext, chatLocation: ChatLoca } } -private func mappedUpdateEntries(context: AccountContext, chatLocation: ChatLocation, associatedData: ChatMessageItemAssociatedData, controllerInteraction: ChatControllerInteraction, mode: ChatHistoryListMode, entries: [ChatHistoryViewTransitionUpdateEntry]) -> [ListViewUpdateItem] { +private func mappedUpdateEntries(context: AccountContextImpl, chatLocation: ChatLocation, associatedData: ChatMessageItemAssociatedData, controllerInteraction: ChatControllerInteraction, mode: ChatHistoryListMode, entries: [ChatHistoryViewTransitionUpdateEntry]) -> [ListViewUpdateItem] { return entries.map { entry -> ListViewUpdateItem in switch entry.entry { case let .MessageEntry(message, presentationData, read, _, selection, attributes): @@ -241,7 +241,7 @@ private func mappedUpdateEntries(context: AccountContext, chatLocation: ChatLoca } } -private func mappedChatHistoryViewListTransition(context: AccountContext, chatLocation: ChatLocation, associatedData: ChatMessageItemAssociatedData, controllerInteraction: ChatControllerInteraction, mode: ChatHistoryListMode, transition: ChatHistoryViewTransition) -> ChatHistoryListViewTransition { +private func mappedChatHistoryViewListTransition(context: AccountContextImpl, chatLocation: ChatLocation, associatedData: ChatMessageItemAssociatedData, controllerInteraction: ChatControllerInteraction, mode: ChatHistoryListMode, transition: ChatHistoryViewTransition) -> ChatHistoryListViewTransition { return ChatHistoryListViewTransition(historyView: transition.historyView, deleteItems: transition.deleteItems, insertItems: mappedInsertEntries(context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, mode: mode, entries: transition.insertEntries), updateItems: mappedUpdateEntries(context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, mode: mode, entries: transition.updateEntries), options: transition.options, scrollToItem: transition.scrollToItem, stationaryItemRange: transition.stationaryItemRange, initialData: transition.initialData, keyboardButtonsMessage: transition.keyboardButtonsMessage, cachedData: transition.cachedData, cachedDataMessages: transition.cachedDataMessages, readStateData: transition.readStateData, scrolledToIndex: transition.scrolledToIndex, peerType: associatedData.automaticDownloadPeerType, networkType: associatedData.automaticDownloadNetworkType, animateIn: transition.animateIn, reason: transition.reason, flashIndicators: transition.flashIndicators) } @@ -330,7 +330,7 @@ private struct ChatHistoryAnimatedEmojiConfiguration { } public final class ChatHistoryListNode: ListView, ChatHistoryNode { - private let context: AccountContext + private let context: AccountContextImpl private let chatLocation: ChatLocation private let messageId: MessageId? private let tagMask: MessageTags? @@ -440,7 +440,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { private var loadedMessagesFromCachedDataDisposable: Disposable? - public init(context: AccountContext, chatLocation: ChatLocation, tagMask: MessageTags?, messageId: MessageId?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal?, NoError>, mode: ChatHistoryListMode = .bubbles) { + public init(context: AccountContextImpl, chatLocation: ChatLocation, tagMask: MessageTags?, messageId: MessageId?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal?, NoError>, mode: ChatHistoryListMode = .bubbles) { self.context = context self.chatLocation = chatLocation self.messageId = messageId diff --git a/submodules/TelegramUI/TelegramUI/ChatHistorySearchContainerNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistorySearchContainerNode.swift index 12f094df35..14fc2e51bf 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistorySearchContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistorySearchContainerNode.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import MergeLists private enum ChatHistorySearchEntryStableId: Hashable { case messageId(MessageId) @@ -77,7 +78,7 @@ private enum ChatHistorySearchEntry: Comparable, Identifiable { } } - func item(context: AccountContext, peerId: PeerId, interaction: ChatControllerInteraction) -> ListViewItem { + func item(context: AccountContextImpl, peerId: PeerId, interaction: ChatControllerInteraction) -> ListViewItem { switch self { case let .message(message, theme, strings, dateTimeFormat): return ListMessageItem(theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, context: context, chatLocation: .peer(peerId), controllerInteraction: interaction, message: message, selection: .none, displayHeader: true) @@ -93,7 +94,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: AccountContextImpl, peerId: PeerId, interaction: ChatControllerInteraction) -> ChatHistorySearchContainerTransition { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } @@ -104,7 +105,7 @@ private func chatHistorySearchContainerPreparedTransition(from fromEntries: [Cha } final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode { - private let context: AccountContext + private let context: AccountContextImpl private let dimNode: ASDisplayNode private let listNode: ListView @@ -134,7 +135,7 @@ final class ChatHistorySearchContainerNode: SearchDisplayControllerContentNode { private var enqueuedTransitions: [(ChatHistorySearchContainerTransition, Bool)] = [] - init(context: AccountContext, peerId: PeerId, tagMask: MessageTags, interfaceInteraction: ChatControllerInteraction) { + init(context: AccountContextImpl, peerId: PeerId, tagMask: MessageTags, interfaceInteraction: ChatControllerInteraction) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/ChatImageGalleryItem.swift b/submodules/TelegramUI/TelegramUI/ChatImageGalleryItem.swift index 8b638b3172..a9c426c4bb 100644 --- a/submodules/TelegramUI/TelegramUI/ChatImageGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatImageGalleryItem.swift @@ -71,14 +71,14 @@ final class ChatMediaGalleryThumbnailItem: GalleryThumbnailItem { } class ChatImageGalleryItem: GalleryItem { - let context: AccountContext + let context: AccountContextImpl let presentationData: PresentationData let message: Message let location: MessageHistoryEntryLocation? let performAction: (GalleryControllerInteractionTapAction) -> Void let openActionOptions: (GalleryControllerInteractionTapAction) -> Void - init(context: AccountContext, presentationData: PresentationData, message: Message, location: MessageHistoryEntryLocation?, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void, openActionOptions: @escaping (GalleryControllerInteractionTapAction) -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, message: Message, location: MessageHistoryEntryLocation?, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void, openActionOptions: @escaping (GalleryControllerInteractionTapAction) -> Void) { self.context = context self.presentationData = presentationData self.message = message @@ -146,7 +146,7 @@ class ChatImageGalleryItem: GalleryItem { } final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { - private let context: AccountContext + private let context: AccountContextImpl private var message: Message? private let imageNode: TransformImageNode @@ -156,13 +156,13 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { private let statusNode: RadialStatusNode private let footerContentNode: ChatItemGalleryFooterContentNode - private var contextAndMedia: (AccountContext, AnyMediaReference)? + private var contextAndMedia: (AccountContextImpl, AnyMediaReference)? private var fetchDisposable = MetaDisposable() private let statusDisposable = MetaDisposable() private var status: MediaResourceStatus? - init(context: AccountContext, presentationData: PresentationData, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void, openActionOptions: @escaping (GalleryControllerInteractionTapAction) -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void, openActionOptions: @escaping (GalleryControllerInteractionTapAction) -> Void) { self.context = context self.imageNode = TransformImageNode() @@ -230,7 +230,7 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { self.contextAndMedia = (self.context, imageReference.abstract) } - func setFile(context: AccountContext, fileReference: FileMediaReference) { + func setFile(context: AccountContextImpl, fileReference: FileMediaReference) { if self.contextAndMedia == nil || !self.contextAndMedia!.1.media.isEqual(to: fileReference.media) { if var largestSize = fileReference.media.dimensions { var displaySize = largestSize.dividedByScreenScale() @@ -425,7 +425,7 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { }) self.statusNodeContainer.layer.animatePosition(from: self.statusNodeContainer.position, to: CGPoint(x: transformedSuperFrame.midX, y: transformedSuperFrame.midY), duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false) - self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false) + self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false) } override func visibilityUpdated(isVisible: Bool) { diff --git a/submodules/TelegramUI/TelegramUI/ChatInfo.swift b/submodules/TelegramUI/TelegramUI/ChatInfo.swift index 529dcac1a0..2ed9d49434 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInfo.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInfo.swift @@ -3,6 +3,6 @@ import Postbox import TelegramCore import Display -func peerSharedMediaController(context: AccountContext, peerId: PeerId) -> ViewController? { +func peerSharedMediaController(context: AccountContextImpl, peerId: PeerId) -> ViewController? { return PeerMediaCollectionController(context: context, peerId: peerId) } diff --git a/submodules/TelegramUI/TelegramUI/ChatInputContextPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatInputContextPanelNode.swift index 6495540c26..01c9ab3e0b 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInputContextPanelNode.swift @@ -11,12 +11,12 @@ enum ChatInputContextPanelPlacement { } class ChatInputContextPanelNode: ASDisplayNode { - let context: AccountContext + let context: AccountContextImpl var interfaceInteraction: ChatPanelInterfaceInteraction? var placement: ChatInputContextPanelPlacement = .overPanels var theme: PresentationTheme - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.context = context self.theme = theme diff --git a/submodules/TelegramUI/TelegramUI/ChatInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatInputPanelNode.swift index 5c0a12897f..b078affb91 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInputPanelNode.swift @@ -6,7 +6,7 @@ import Postbox import TelegramCore class ChatInputPanelNode: ASDisplayNode { - var context: AccountContext? + var context: AccountContextImpl? var interfaceInteraction: ChatPanelInterfaceInteraction? func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceInputContextPanels.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceInputContextPanels.swift index d611ae200e..d2b9042c7f 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceInputContextPanels.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceInputContextPanels.swift @@ -23,7 +23,7 @@ private func inputQueryResultPriority(_ result: ChatPresentationInputQueryResult } } -func inputContextPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatInputContextPanelNode?, controllerInteraction: ChatControllerInteraction?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> ChatInputContextPanelNode? { +func inputContextPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContextImpl, currentPanel: ChatInputContextPanelNode?, controllerInteraction: ChatControllerInteraction?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> ChatInputContextPanelNode? { guard let _ = chatPresentationInterfaceState.renderedPeer?.peer else { return nil } @@ -164,7 +164,7 @@ func inputContextPanelForChatPresentationIntefaceState(_ chatPresentationInterfa return nil } -func chatOverlayContextPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatInputContextPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> ChatInputContextPanelNode? { +func chatOverlayContextPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContextImpl, currentPanel: ChatInputContextPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> ChatInputContextPanelNode? { guard let searchQuerySuggestionResult = chatPresentationInterfaceState.searchQuerySuggestionResult, let _ = chatPresentationInterfaceState.renderedPeer?.peer else { return nil } diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceInputContexts.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceInputContexts.swift index a03145f877..1fc4ead68e 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceInputContexts.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceInputContexts.swift @@ -197,7 +197,7 @@ func inputContextQueriesForChatPresentationIntefaceState(_ chatPresentationInter return result } -func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext) -> ChatTextInputPanelState { +func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContextImpl) -> ChatTextInputPanelState { var contextPlaceholder: NSAttributedString? loop: for (_, result) in chatPresentationInterfaceState.inputQueryResults { if case let .contextRequestResult(peer, _) = result, let botUser = peer as? TelegramUser, let botInfo = botUser.botInfo, let inlinePlaceholder = botInfo.inlinePlaceholder { diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceInputNodes.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceInputNodes.swift index 1a100eba9a..dffebaaa93 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceInputNodes.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceInputNodes.swift @@ -4,7 +4,7 @@ import AsyncDisplayKit import TelegramCore import Postbox -func inputNodeForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentNode: ChatInputNode?, interfaceInteraction: ChatPanelInterfaceInteraction?, inputMediaNode: ChatMediaInputNode?, controllerInteraction: ChatControllerInteraction, inputPanelNode: ChatInputPanelNode?) -> ChatInputNode? { +func inputNodeForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContextImpl, currentNode: ChatInputNode?, interfaceInteraction: ChatPanelInterfaceInteraction?, inputMediaNode: ChatMediaInputNode?, controllerInteraction: ChatControllerInteraction, inputPanelNode: ChatInputPanelNode?) -> ChatInputNode? { if !(inputPanelNode is ChatTextInputPanelNode) { return nil } diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceState.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceState.swift index 76dd30c171..f254b131ce 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceState.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceState.swift @@ -2,6 +2,7 @@ import Foundation import UIKit import Postbox import TelegramCore +import TextFormat struct ChatInterfaceSelectionState: PostboxCoding, Equatable { let selectedIds: Set diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateAccessoryPanels.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateAccessoryPanels.swift index aae6defd0b..812c7e9bf4 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateAccessoryPanels.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateAccessoryPanels.swift @@ -3,7 +3,7 @@ import UIKit import AsyncDisplayKit import TelegramCore -func accessoryPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: AccessoryPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> AccessoryPanelNode? { +func accessoryPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContextImpl, currentPanel: AccessoryPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> AccessoryPanelNode? { if let _ = chatPresentationInterfaceState.interfaceState.selectionState { return nil } diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateContextMenus.swift index 00e5fa2707..94a23e56e9 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateContextMenus.swift @@ -18,7 +18,7 @@ private struct MessageContextMenuData { let messageActions: ChatAvailableMessageActions } -func canEditMessage(context: AccountContext, limitsConfiguration: LimitsConfiguration, message: Message) -> Bool { +func canEditMessage(context: AccountContextImpl, limitsConfiguration: LimitsConfiguration, message: Message) -> Bool { var hasEditRights = false var unlimitedInterval = false @@ -221,7 +221,7 @@ func updatedChatEditInterfaceMessagetState(state: ChatPresentationInterfaceState return updated } -func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, messages: [Message], controllerInteraction: ChatControllerInteraction?, selectAll: Bool, interfaceInteraction: ChatPanelInterfaceInteraction?) -> Signal<[ChatMessageContextMenuAction], NoError> { +func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContextImpl, messages: [Message], controllerInteraction: ChatControllerInteraction?, selectAll: Bool, interfaceInteraction: ChatPanelInterfaceInteraction?) -> Signal<[ChatMessageContextMenuAction], NoError> { guard let interfaceInteraction = interfaceInteraction, let controllerInteraction = controllerInteraction else { return .single([]) } diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateContextQueries.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateContextQueries.swift index fa47d0ff32..260a5c039e 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateContextQueries.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateContextQueries.swift @@ -6,6 +6,7 @@ import Postbox import TelegramUIPreferences import TelegramUIPrivateModule import LegacyComponents +import TextFormat enum ChatContextQueryError { case inlineBotLocationRequest(PeerId) @@ -16,7 +17,7 @@ enum ChatContextQueryUpdate { case update(ChatPresentationInputQuery, Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError>) } -func contextQueryResultStateForChatInterfacePresentationState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentQueryStates: inout [ChatPresentationInputQueryKind: (ChatPresentationInputQuery, Disposable)]) -> [ChatPresentationInputQueryKind: ChatContextQueryUpdate] { +func contextQueryResultStateForChatInterfacePresentationState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContextImpl, currentQueryStates: inout [ChatPresentationInputQueryKind: (ChatPresentationInputQuery, Disposable)]) -> [ChatPresentationInputQueryKind: ChatContextQueryUpdate] { guard let peer = chatPresentationInterfaceState.renderedPeer?.peer else { return [:] } @@ -59,7 +60,7 @@ func contextQueryResultStateForChatInterfacePresentationState(_ chatPresentation return updates } -private func updatedContextQueryResultStateForQuery(context: AccountContext, peer: Peer, inputQuery: ChatPresentationInputQuery, previousQuery: ChatPresentationInputQuery?) -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> { +private func updatedContextQueryResultStateForQuery(context: AccountContextImpl, peer: Peer, inputQuery: ChatPresentationInputQuery, previousQuery: ChatPresentationInputQuery?) -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> { switch inputQuery { case let .emoji(query): var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = .complete() @@ -309,7 +310,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee } } -func searchQuerySuggestionResultStateForChatInterfacePresentationState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentQuery: ChatPresentationInputQuery?) -> (ChatPresentationInputQuery?, Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError>)? { +func searchQuerySuggestionResultStateForChatInterfacePresentationState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContextImpl, currentQuery: ChatPresentationInputQuery?) -> (ChatPresentationInputQuery?, Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError>)? { var inputQuery: ChatPresentationInputQuery? if let search = chatPresentationInterfaceState.search { switch search.domain { @@ -363,7 +364,7 @@ func searchQuerySuggestionResultStateForChatInterfacePresentationState(_ chatPre private let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType([.link]).rawValue) -func urlPreviewStateForInputText(_ inputText: NSAttributedString?, context: AccountContext, currentQuery: String?) -> (String?, Signal<(TelegramMediaWebpage?) -> TelegramMediaWebpage?, NoError>)? { +func urlPreviewStateForInputText(_ inputText: NSAttributedString?, context: AccountContextImpl, currentQuery: String?) -> (String?, Signal<(TelegramMediaWebpage?) -> TelegramMediaWebpage?, NoError>)? { guard let text = inputText else { if currentQuery != nil { return (nil, .single({ _ in return nil })) diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift index 7466f47a4c..386a5c0086 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift @@ -3,7 +3,7 @@ import UIKit import AsyncDisplayKit import TelegramCore -func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatInputPanelNode?, textInputPanelNode: ChatTextInputPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> ChatInputPanelNode? { +func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContextImpl, currentPanel: ChatInputPanelNode?, textInputPanelNode: ChatTextInputPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> ChatInputPanelNode? { if let renderedPeer = chatPresentationInterfaceState.renderedPeer, renderedPeer.peer?.restrictionText != nil { return nil } diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceTitlePanelNodes.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceTitlePanelNodes.swift index 6531f718e3..59b1d885b4 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceTitlePanelNodes.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceTitlePanelNodes.swift @@ -2,7 +2,7 @@ import Foundation import UIKit import TelegramCore -func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatTitleAccessoryPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> ChatTitleAccessoryPanelNode? { +func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContextImpl, currentPanel: ChatTitleAccessoryPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> ChatTitleAccessoryPanelNode? { if case .overlay = chatPresentationInterfaceState.mode { return nil } diff --git a/submodules/TelegramUI/TelegramUI/ChatItemGalleryFooterContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatItemGalleryFooterContentNode.swift index c09b73d672..c3c70429eb 100644 --- a/submodules/TelegramUI/TelegramUI/ChatItemGalleryFooterContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatItemGalleryFooterContentNode.swift @@ -7,6 +7,7 @@ import TelegramCore import SwiftSignalKit import Photos import TelegramPresentationData +import TextFormat private let deleteImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionThrash"), color: .white) private let actionImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionAction"), color: .white) @@ -136,7 +137,7 @@ class CaptionScrollWrapperNode: ASDisplayNode { } final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScrollViewDelegate { - private let context: AccountContext + private let context: AccountContextImpl private var theme: PresentationTheme private var strings: PresentationStrings private var dateTimeFormat: PresentationDateTimeFormat @@ -253,7 +254,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll } } - init(context: AccountContext, presentationData: PresentationData) { + init(context: AccountContextImpl, presentationData: PresentationData) { self.context = context self.theme = presentationData.theme self.strings = presentationData.strings @@ -312,8 +313,8 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll TelegramTextAttributes.Timecode] for attribute in highlightedAttributes { - if let _ = attributes[NSAttributedStringKey(rawValue: attribute)] { - return NSAttributedStringKey(rawValue: attribute) + if let _ = attributes[NSAttributedString.Key(rawValue: attribute)] { + return NSAttributedString.Key(rawValue: attribute) } } return nil @@ -376,18 +377,18 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll self.scrollNode.view.showsVerticalScrollIndicator = false } - private func actionForAttributes(_ attributes: [NSAttributedStringKey: Any]) -> GalleryControllerInteractionTapAction? { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + private func actionForAttributes(_ attributes: [NSAttributedString.Key: Any]) -> GalleryControllerInteractionTapAction? { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { return .url(url: url, concealed: false) - } else if let peerMention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { + } else if let peerMention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { return .peerMention(peerMention.peerId, peerMention.mention) - } else if let peerName = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let peerName = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { return .textMention(peerName) - } else if let botCommand = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.BotCommand)] as? String { + } else if let botCommand = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.BotCommand)] as? String { return .botCommand(botCommand) - } else if let hashtag = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { + } else if let hashtag = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { return .hashtag(hashtag.peerName, hashtag.hashtag) - } else if let timecode = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Timecode)] as? TelegramTimecode { + } else if let timecode = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Timecode)] as? TelegramTimecode { return .timecode(timecode.time, timecode.text) } else { return nil diff --git a/submodules/TelegramUI/TelegramUI/ChatListBadgeNode.swift b/submodules/TelegramUI/TelegramUI/ChatListBadgeNode.swift index 5b68306427..92d837b2d9 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListBadgeNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListBadgeNode.swift @@ -154,7 +154,7 @@ final class ChatListBadgeNode: ASDisplayNode { snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak snapshotView] _ in snapshotView?.removeFromSuperview() }) - snapshotView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: (badgeWidth - previousBadgeWidth) / 2.0, y: -8.0), duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, additive: true) + snapshotView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: (badgeWidth - previousBadgeWidth) / 2.0, y: -8.0), duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true) } animateTextNode = true } else if !currentIsEmpty && nextIsEmpty && !strongSelf.isHiddenInternal { @@ -189,14 +189,14 @@ final class ChatListBadgeNode: ASDisplayNode { strongSelf.textNode.frame = badgeTextFrame if animateTextNode { strongSelf.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15) - strongSelf.textNode.layer.animatePosition(from: CGPoint(x: (previousBadgeWidth - badgeWidth) / 2.0, y: 8.0), to: CGPoint(), duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, additive: true) + strongSelf.textNode.layer.animatePosition(from: CGPoint(x: (previousBadgeWidth - badgeWidth) / 2.0, y: 8.0), to: CGPoint(), duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true) } } strongSelf.backgroundNode.frame = backgroundFrame if animated && badgeWidth != previousBadgeWidth { let previousBackgroundFrame = CGRect(x: 0.0, y: 0.0, width: previousBadgeWidth, height: backgroundFrame.height) - strongSelf.backgroundNode.layer.animateFrame(from: previousBackgroundFrame, to: backgroundFrame, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseInEaseOut) + strongSelf.backgroundNode.layer.animateFrame(from: previousBackgroundFrame, to: backgroundFrame, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue) } } }) diff --git a/submodules/TelegramUI/TelegramUI/ChatListController.swift b/submodules/TelegramUI/TelegramUI/ChatListController.swift index d8fc00a1a5..4bc5782c43 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListController.swift @@ -58,7 +58,7 @@ private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBa public class ChatListController: TelegramController, UIViewControllerPreviewingDelegate { private var validLayout: ContainerViewLayout? - let context: AccountContext + let context: AccountContextImpl private let controlsHistoryPreload: Bool private let hideNetworkActivityStatus: Bool @@ -102,7 +102,7 @@ public class ChatListController: TelegramController, UIViewControllerPreviewingD } } - public init(context: AccountContext, groupId: PeerGroupId, controlsHistoryPreload: Bool, hideNetworkActivityStatus: Bool = false) { + public init(context: AccountContextImpl, groupId: PeerGroupId, controlsHistoryPreload: Bool, hideNetworkActivityStatus: Bool = false) { self.context = context self.controlsHistoryPreload = controlsHistoryPreload self.hideNetworkActivityStatus = hideNetworkActivityStatus @@ -1290,22 +1290,22 @@ public class ChatListController: TelegramController, UIViewControllerPreviewingD } let inputShortcuts: [KeyShortcut] = [ - KeyShortcut(title: strings.KeyCommand_JumpToPreviousChat, input: UIKeyInputUpArrow, modifiers: [.alternate], action: { [weak self] in + KeyShortcut(title: strings.KeyCommand_JumpToPreviousChat, input: UIKeyCommand.inputUpArrow, modifiers: [.alternate], action: { [weak self] in if let strongSelf = self { strongSelf.chatListDisplayNode.chatListNode.selectChat(.previous(unread: false)) } }), - KeyShortcut(title: strings.KeyCommand_JumpToNextChat, input: UIKeyInputDownArrow, modifiers: [.alternate], action: { [weak self] in + KeyShortcut(title: strings.KeyCommand_JumpToNextChat, input: UIKeyCommand.inputDownArrow, modifiers: [.alternate], action: { [weak self] in if let strongSelf = self { strongSelf.chatListDisplayNode.chatListNode.selectChat(.next(unread: false)) } }), - KeyShortcut(title: strings.KeyCommand_JumpToPreviousUnreadChat, input: UIKeyInputUpArrow, modifiers: [.alternate, .shift], action: { [weak self] in + KeyShortcut(title: strings.KeyCommand_JumpToPreviousUnreadChat, input: UIKeyCommand.inputUpArrow, modifiers: [.alternate, .shift], action: { [weak self] in if let strongSelf = self { strongSelf.chatListDisplayNode.chatListNode.selectChat(.previous(unread: true)) } }), - KeyShortcut(title: strings.KeyCommand_JumpToNextUnreadChat, input: UIKeyInputDownArrow, modifiers: [.alternate, .shift], action: { [weak self] in + KeyShortcut(title: strings.KeyCommand_JumpToNextUnreadChat, input: UIKeyCommand.inputDownArrow, modifiers: [.alternate, .shift], action: { [weak self] in if let strongSelf = self { strongSelf.chatListDisplayNode.chatListNode.selectChat(.next(unread: true)) } @@ -1316,7 +1316,7 @@ public class ChatListController: TelegramController, UIViewControllerPreviewingD } }), KeyShortcut(title: strings.KeyCommand_Find, input: "\t", modifiers: [], action: toggleSearch), - KeyShortcut(input: UIKeyInputEscape, modifiers: [], action: toggleSearch) + KeyShortcut(input: UIKeyCommand.inputEscape, modifiers: [], action: toggleSearch) ] let openChat: (Int) -> Void = { [weak self] index in diff --git a/submodules/TelegramUI/TelegramUI/ChatListControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatListControllerNode.swift index 711fab8cce..47486b6457 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListControllerNode.swift @@ -6,6 +6,8 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import MergeLists +import ActivityIndicator private final class ChatListControllerNodeView: UITracingLayerView, PreviewingHostView { var previewingDelegate: PreviewingHostViewDelegate? { @@ -36,7 +38,7 @@ private struct TestItem: Comparable, Identifiable { } final class ChatListControllerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private let groupId: PeerGroupId private var presentationData: PresentationData @@ -63,7 +65,7 @@ final class ChatListControllerNode: ASDisplayNode { let debugListView = ListView() - init(context: AccountContext, groupId: PeerGroupId, controlsHistoryPreload: Bool, presentationData: PresentationData, controller: ChatListController) { + init(context: AccountContextImpl, groupId: PeerGroupId, controlsHistoryPreload: Bool, presentationData: PresentationData, controller: ChatListController) { self.context = context self.groupId = groupId self.presentationData = presentationData diff --git a/submodules/TelegramUI/TelegramUI/ChatListItem.swift b/submodules/TelegramUI/TelegramUI/ChatListItem.swift index 1edd6a7c38..35fff79297 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListItem.swift @@ -6,6 +6,7 @@ import Display import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ItemListUI enum ChatListItemContent { case peer(message: Message?, peer: RenderedPeer, combinedReadState: CombinedPeerReadState?, notificationSettings: PeerNotificationSettings?, presence: PeerPresence?, summaryInfo: ChatListMessageTagSummaryInfo, embeddedState: PeerChatListEmbeddedInterfaceState?, inputActivities: [(Peer, PeerInputActivity)]?, isAd: Bool, ignoreUnreadBadge: Bool) @@ -23,7 +24,7 @@ enum ChatListItemContent { class ChatListItem: ListViewItem { let presentationData: ChatListPresentationData - let context: AccountContext + let context: AccountContextImpl let peerGroupId: PeerGroupId let index: ChatListIndex let content: ChatListItemContent @@ -42,7 +43,7 @@ class ChatListItem: ListViewItem { let header: ListViewItemHeader? - init(presentationData: ChatListPresentationData, context: AccountContext, peerGroupId: PeerGroupId, index: ChatListIndex, content: ChatListItemContent, editing: Bool, hasActiveRevealControls: Bool, selected: Bool, header: ListViewItemHeader?, enableContextActions: Bool, hiddenOffset: Bool, interaction: ChatListNodeInteraction) { + init(presentationData: ChatListPresentationData, context: AccountContextImpl, peerGroupId: PeerGroupId, index: ChatListIndex, content: ChatListItemContent, editing: Bool, hasActiveRevealControls: Bool, selected: Bool, header: ListViewItemHeader?, enableContextActions: Bool, hiddenOffset: Bool, interaction: ChatListNodeInteraction) { self.presentationData = presentationData self.peerGroupId = peerGroupId self.context = context @@ -1679,7 +1680,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { self.highlightedBackgroundNode.alpha = 0.0 } self.highlightedBackgroundNode.layer.removeAllAnimations() - self.highlightedBackgroundNode.layer.animate(from: 1.0 as NSNumber, to: 0.0 as NSNumber, keyPath: "opacity", timingFunction: kCAMediaTimingFunctionEaseOut, duration: 0.3, delay: 0.7, completion: { [weak self] _ in + self.highlightedBackgroundNode.layer.animate(from: 1.0 as NSNumber, to: 0.0 as NSNumber, keyPath: "opacity", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, duration: 0.3, delay: 0.7, completion: { [weak self] _ in self?.updateIsHighlighted(transition: .immediate) }) } diff --git a/submodules/TelegramUI/TelegramUI/ChatListNode.swift b/submodules/TelegramUI/TelegramUI/ChatListNode.swift index a97065055d..d1388ee0df 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListNode.swift @@ -142,7 +142,7 @@ struct ChatListNodeState: Equatable { } } -private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, mode: ChatListNodeMode, entries: [ChatListNodeViewTransitionInsertEntry]) -> [ListViewInsertItem] { +private func mappedInsertEntries(context: AccountContextImpl, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, mode: ChatListNodeMode, entries: [ChatListNodeViewTransitionInsertEntry]) -> [ListViewInsertItem] { return entries.map { entry -> ListViewInsertItem in switch entry.entry { case let .PeerEntry(index, presentationData, message, combinedReadState, notificationSettings, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, isAd): @@ -223,7 +223,7 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL } } -private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, mode: ChatListNodeMode, entries: [ChatListNodeViewTransitionUpdateEntry]) -> [ListViewUpdateItem] { +private func mappedUpdateEntries(context: AccountContextImpl, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, mode: ChatListNodeMode, entries: [ChatListNodeViewTransitionUpdateEntry]) -> [ListViewUpdateItem] { return entries.map { entry -> ListViewUpdateItem in switch entry.entry { case let .PeerEntry(index, presentationData, message, combinedReadState, notificationSettings, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, isAd): @@ -262,7 +262,7 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL } } -private func mappedChatListNodeViewListTransition(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, mode: ChatListNodeMode, transition: ChatListNodeViewTransition) -> ChatListNodeListViewTransition { +private func mappedChatListNodeViewListTransition(context: AccountContextImpl, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, mode: ChatListNodeMode, transition: ChatListNodeViewTransition) -> ChatListNodeListViewTransition { return ChatListNodeListViewTransition(chatListView: transition.chatListView, deleteItems: transition.deleteItems, insertItems: mappedInsertEntries(context: context, nodeInteraction: nodeInteraction, peerGroupId: peerGroupId, mode: mode, entries: transition.insertEntries), updateItems: mappedUpdateEntries(context: context, nodeInteraction: nodeInteraction, peerGroupId: peerGroupId, mode: mode, entries: transition.updateEntries), options: transition.options, scrollToItem: transition.scrollToItem, stationaryItemRange: transition.stationaryItemRange) } @@ -305,7 +305,7 @@ enum ChatListNodeEmptyState: Equatable { final class ChatListNode: ListView { private let controlsHistoryPreload: Bool - private let context: AccountContext + private let context: AccountContextImpl private let groupId: PeerGroupId private let mode: ChatListNodeMode @@ -382,7 +382,7 @@ final class ChatListNode: ListView { private var hapticFeedback: HapticFeedback? - init(context: AccountContext, groupId: PeerGroupId, controlsHistoryPreload: Bool, mode: ChatListNodeMode, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, disableAnimations: Bool) { + init(context: AccountContextImpl, groupId: PeerGroupId, controlsHistoryPreload: Bool, mode: ChatListNodeMode, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, disableAnimations: Bool) { self.context = context self.groupId = groupId self.controlsHistoryPreload = controlsHistoryPreload diff --git a/submodules/TelegramUI/TelegramUI/ChatListNodeEntries.swift b/submodules/TelegramUI/TelegramUI/ChatListNodeEntries.swift index d206a38633..fca1a1480d 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListNodeEntries.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListNodeEntries.swift @@ -2,6 +2,7 @@ import Foundation import Postbox import TelegramCore import TelegramPresentationData +import MergeLists enum ChatListNodeEntryId: Hashable { case Hole(Int64) diff --git a/submodules/TelegramUI/TelegramUI/ChatListSearchContainerNode.swift b/submodules/TelegramUI/TelegramUI/ChatListSearchContainerNode.swift index 546a05ce87..58e4263687 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListSearchContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListSearchContainerNode.swift @@ -7,6 +7,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import MergeLists private enum ChatListRecentEntryStableId: Hashable { case topPeers @@ -71,7 +72,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable { } } - func item(context: AccountContext, filter: ChatListNodePeersFilter, peerSelected: @escaping (Peer) -> Void, peerLongTapped: @escaping (Peer) -> Void, clearRecentlySearchedPeers: @escaping () -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, deletePeer: @escaping (PeerId) -> Void) -> ListViewItem { + func item(context: AccountContextImpl, filter: ChatListNodePeersFilter, peerSelected: @escaping (Peer) -> Void, peerLongTapped: @escaping (Peer) -> Void, clearRecentlySearchedPeers: @escaping () -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, deletePeer: @escaping (PeerId) -> Void) -> ListViewItem { switch self { case let .topPeers(peers, theme, strings): return ChatListRecentPeersListItem(theme: theme, strings: strings, account: context.account, peers: peers, peerSelected: { peer in @@ -324,7 +325,7 @@ enum ChatListSearchEntry: Comparable, Identifiable { } } - func item(context: AccountContext, enableHeaders: Bool, filter: ChatListNodePeersFilter, interaction: ChatListNodeInteraction) -> ListViewItem { + func item(context: AccountContextImpl, enableHeaders: Bool, filter: ChatListNodePeersFilter, interaction: ChatListNodeInteraction) -> ListViewItem { switch self { case let .localPeer(peer, associatedPeer, unreadBadge, _, theme, strings, nameSortOrder, nameDisplayOrder): let primaryPeer: Peer @@ -448,7 +449,7 @@ struct ChatListSearchContainerTransition { let displayingResults: Bool } -private func chatListSearchContainerPreparedRecentTransition(from fromEntries: [ChatListRecentEntry], to toEntries: [ChatListRecentEntry], context: AccountContext, filter: ChatListNodePeersFilter, peerSelected: @escaping (Peer) -> Void, peerLongTapped: @escaping (Peer) -> Void, clearRecentlySearchedPeers: @escaping () -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, deletePeer: @escaping (PeerId) -> Void) -> ChatListSearchContainerRecentTransition { +private func chatListSearchContainerPreparedRecentTransition(from fromEntries: [ChatListRecentEntry], to toEntries: [ChatListRecentEntry], context: AccountContextImpl, filter: ChatListNodePeersFilter, peerSelected: @escaping (Peer) -> Void, peerLongTapped: @escaping (Peer) -> Void, clearRecentlySearchedPeers: @escaping () -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, deletePeer: @escaping (PeerId) -> Void) -> ChatListSearchContainerRecentTransition { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } @@ -458,7 +459,7 @@ private func chatListSearchContainerPreparedRecentTransition(from fromEntries: [ return ChatListSearchContainerRecentTransition(deletions: deletions, insertions: insertions, updates: updates) } -func chatListSearchContainerPreparedTransition(from fromEntries: [ChatListSearchEntry], to toEntries: [ChatListSearchEntry], displayingResults: Bool, context: AccountContext, enableHeaders: Bool, filter: ChatListNodePeersFilter, interaction: ChatListNodeInteraction) -> ChatListSearchContainerTransition { +func chatListSearchContainerPreparedTransition(from fromEntries: [ChatListSearchEntry], to toEntries: [ChatListSearchEntry], displayingResults: Bool, context: AccountContextImpl, enableHeaders: Bool, filter: ChatListNodePeersFilter, interaction: ChatListNodeInteraction) -> ChatListSearchContainerTransition { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } @@ -519,7 +520,7 @@ private struct ChatListSearchMessagesContext { } final class ChatListSearchContainerNode: SearchDisplayControllerContentNode { - private let context: AccountContext + private let context: AccountContextImpl private let recentListNode: ListView private let listNode: ListView @@ -548,7 +549,7 @@ final class ChatListSearchContainerNode: SearchDisplayControllerContentNode { private let filter: ChatListNodePeersFilter - init(context: AccountContext, filter: ChatListNodePeersFilter, groupId: PeerGroupId, openPeer: @escaping (Peer, Bool) -> Void, openRecentPeerOptions: @escaping (Peer) -> Void, openMessage: @escaping (Peer, MessageId) -> Void, addContact: ((String) -> Void)?) { + init(context: AccountContextImpl, filter: ChatListNodePeersFilter, groupId: PeerGroupId, openPeer: @escaping (Peer, Bool) -> Void, openRecentPeerOptions: @escaping (Peer) -> Void, openMessage: @escaping (Peer, MessageId) -> Void, addContact: ((String) -> Void)?) { self.context = context self.filter = filter self.dimNode = ASDisplayNode() diff --git a/submodules/TelegramUI/TelegramUI/ChatListSearchRecentPeersNode.swift b/submodules/TelegramUI/TelegramUI/ChatListSearchRecentPeersNode.swift index ef5079393a..fcb6a951ec 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListSearchRecentPeersNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListSearchRecentPeersNode.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import MergeLists private func calculateItemCustomWidth(width: CGFloat) -> CGFloat { let itemInsets = UIEdgeInsets(top: 0.0, left: 6.0, bottom: 0.0, right: 6.0) diff --git a/submodules/TelegramUI/TelegramUI/ChatListStatusNode.swift b/submodules/TelegramUI/TelegramUI/ChatListStatusNode.swift index 4c67678f4c..841e985785 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListStatusNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListStatusNode.swift @@ -176,12 +176,12 @@ private func maybeAddRotationAnimation(_ layer: CALayer, duration: Double) { } let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = duration basicAnimation.fromValue = NSNumber(value: Float(0.0)) basicAnimation.toValue = NSNumber(value: Float(Double.pi * 2.0)) basicAnimation.repeatCount = Float.infinity - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) basicAnimation.beginTime = 1.0 layer.add(basicAnimation, forKey: "clockFrameAnimation") } @@ -234,7 +234,7 @@ private class ChatListStatusChecksNode: ChatListStatusContentNode { }) as! POPAnimatableProperty) animation.fromValue = from as NSNumber animation.toValue = to as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 0.2 self.pop_add(animation, forKey: "progress") } diff --git a/submodules/TelegramUI/TelegramUI/ChatListTitleProxyNode.swift b/submodules/TelegramUI/TelegramUI/ChatListTitleProxyNode.swift index 453685717c..88c0342d2c 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListTitleProxyNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListTitleProxyNode.swift @@ -3,6 +3,7 @@ import UIKit import Display import AsyncDisplayKit import TelegramPresentationData +import ActivityIndicator enum ChatTitleProxyStatus { case connecting diff --git a/submodules/TelegramUI/TelegramUI/ChatListTitleView.swift b/submodules/TelegramUI/TelegramUI/ChatListTitleView.swift index 534fa5a7d2..0afb09502b 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListTitleView.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListTitleView.swift @@ -3,6 +3,7 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import ActivityIndicator struct NetworkStatusTitle: Equatable { let text: String @@ -90,13 +91,13 @@ final class ChatListTitleView: UIView, NavigationBarTitleView, NavigationBarTitl self.buttonView = HighlightTrackingButton() self.buttonView.isAccessibilityElement = true - self.buttonView.accessibilityTraits = UIAccessibilityTraitHeader + self.buttonView.accessibilityTraits = .header self.proxyButton = HighlightTrackingButton() self.proxyButton.isHidden = true self.proxyButton.isAccessibilityElement = true self.proxyButton.accessibilityLabel = "Proxy Settings" - self.proxyButton.accessibilityTraits = UIAccessibilityTraitButton + self.proxyButton.accessibilityTraits = .button super.init(frame: CGRect()) diff --git a/submodules/TelegramUI/TelegramUI/ChatListViewTransition.swift b/submodules/TelegramUI/TelegramUI/ChatListViewTransition.swift index 4ca77ec528..f4c3474d74 100644 --- a/submodules/TelegramUI/TelegramUI/ChatListViewTransition.swift +++ b/submodules/TelegramUI/TelegramUI/ChatListViewTransition.swift @@ -3,6 +3,7 @@ import Postbox import TelegramCore import SwiftSignalKit import Display +import MergeLists struct ChatListNodeView { let originalView: ChatListView diff --git a/submodules/TelegramUI/TelegramUI/ChatLoadingNode.swift b/submodules/TelegramUI/TelegramUI/ChatLoadingNode.swift index 4b7dd4fc48..87c93ef9c4 100644 --- a/submodules/TelegramUI/TelegramUI/ChatLoadingNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatLoadingNode.swift @@ -4,6 +4,7 @@ import AsyncDisplayKit import Display import TelegramCore import TelegramPresentationData +import ActivityIndicator final class ChatLoadingNode: ASDisplayNode { private let backgroundNode: ASImageNode diff --git a/submodules/TelegramUI/TelegramUI/ChatMediaInputGridEntries.swift b/submodules/TelegramUI/TelegramUI/ChatMediaInputGridEntries.swift index cf2927978b..b65b496c43 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMediaInputGridEntries.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMediaInputGridEntries.swift @@ -4,6 +4,7 @@ import TelegramCore import SwiftSignalKit import Display import TelegramPresentationData +import MergeLists enum ChatMediaInputGridEntryStableId: Equatable, Hashable { case search diff --git a/submodules/TelegramUI/TelegramUI/ChatMediaInputNode.swift b/submodules/TelegramUI/TelegramUI/ChatMediaInputNode.swift index fe4f3f6bd6..8d0c5653e4 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMediaInputNode.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import MergeLists private struct PeerSpecificPackData { let peer: Peer @@ -389,7 +390,7 @@ private final class CollectionListContainerNode: ASDisplayNode { } final class ChatMediaInputNode: ChatInputNode { - private let context: AccountContext + private let context: AccountContextImpl private let peerId: PeerId? private let controllerInteraction: ChatControllerInteraction private let gifPaneIsActiveUpdated: (Bool) -> Void @@ -434,7 +435,7 @@ final class ChatMediaInputNode: ChatInputNode { return self._ready.get() } - init(context: AccountContext, peerId: PeerId?, controllerInteraction: ChatControllerInteraction, theme: PresentationTheme, strings: PresentationStrings, gifPaneIsActiveUpdated: @escaping (Bool) -> Void) { + init(context: AccountContextImpl, peerId: PeerId?, controllerInteraction: ChatControllerInteraction, theme: PresentationTheme, strings: PresentationStrings, gifPaneIsActiveUpdated: @escaping (Bool) -> Void) { self.context = context self.peerId = peerId self.controllerInteraction = controllerInteraction diff --git a/submodules/TelegramUI/TelegramUI/ChatMediaInputPanelEntries.swift b/submodules/TelegramUI/TelegramUI/ChatMediaInputPanelEntries.swift index c2bd951dad..7b240c8657 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMediaInputPanelEntries.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMediaInputPanelEntries.swift @@ -4,6 +4,7 @@ import TelegramCore import SwiftSignalKit import Display import TelegramPresentationData +import MergeLists enum ChatMediaInputPanelAuxiliaryNamespace: Int32 { case savedStickers = 2 diff --git a/submodules/TelegramUI/TelegramUI/ChatMediaInputTrendingPane.swift b/submodules/TelegramUI/TelegramUI/ChatMediaInputTrendingPane.swift index 8c4ef0b1ae..4aac1bd2cf 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMediaInputTrendingPane.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMediaInputTrendingPane.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import MergeLists final class TrendingPaneInteraction { let installPack: (ItemCollectionInfo) -> Void @@ -106,7 +107,7 @@ private func trendingPaneEntries(trendingEntries: [FeaturedStickerPackItem], ins } final class ChatMediaInputTrendingPane: ChatMediaInputPane { - private let context: AccountContext + private let context: AccountContextImpl private let controllerInteraction: ChatControllerInteraction private let getItemIsPreviewed: (StickerPackItem) -> Bool @@ -126,7 +127,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane { var scrollingInitiated: (() -> Void)? - init(context: AccountContext, controllerInteraction: ChatControllerInteraction, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool) { + init(context: AccountContextImpl, controllerInteraction: ChatControllerInteraction, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool) { self.context = context self.controllerInteraction = controllerInteraction self.getItemIsPreviewed = getItemIsPreviewed diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageActionButtonsNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageActionButtonsNode.swift index a1343e4f38..9b6bdc0658 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageActionButtonsNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageActionButtonsNode.swift @@ -70,7 +70,7 @@ private final class ChatMessageActionButtonNode: ASDisplayNode { } } - class func asyncLayout(_ maybeNode: ChatMessageActionButtonNode?) -> (_ context: AccountContext, _ theme: ChatPresentationThemeData, _ strings: PresentationStrings, _ message: Message, _ button: ReplyMarkupButton, _ constrainedWidth: CGFloat, _ position: MessageBubbleActionButtonPosition) -> (minimumWidth: CGFloat, layout: ((CGFloat) -> (CGSize, () -> ChatMessageActionButtonNode))) { + class func asyncLayout(_ maybeNode: ChatMessageActionButtonNode?) -> (_ context: AccountContextImpl, _ theme: ChatPresentationThemeData, _ strings: PresentationStrings, _ message: Message, _ button: ReplyMarkupButton, _ constrainedWidth: CGFloat, _ position: MessageBubbleActionButtonPosition) -> (minimumWidth: CGFloat, layout: ((CGFloat) -> (CGSize, () -> ChatMessageActionButtonNode))) { let titleLayout = TextNode.asyncLayout(maybeNode?.titleNode) return { context, theme, strings, message, button, constrainedWidth, position in @@ -199,7 +199,7 @@ final class ChatMessageActionButtonsNode: ASDisplayNode { } } - class func asyncLayout(_ maybeNode: ChatMessageActionButtonsNode?) -> (_ context: AccountContext, _ theme: ChatPresentationThemeData, _ strings: PresentationStrings, _ replyMarkup: ReplyMarkupMessageAttribute, _ message: Message, _ constrainedWidth: CGFloat) -> (minWidth: CGFloat, layout: (CGFloat) -> (CGSize, (_ animated: Bool) -> ChatMessageActionButtonsNode)) { + class func asyncLayout(_ maybeNode: ChatMessageActionButtonsNode?) -> (_ context: AccountContextImpl, _ theme: ChatPresentationThemeData, _ strings: PresentationStrings, _ replyMarkup: ReplyMarkupMessageAttribute, _ message: Message, _ constrainedWidth: CGFloat) -> (minWidth: CGFloat, layout: (CGFloat) -> (CGSize, (_ animated: Bool) -> ChatMessageActionButtonsNode)) { let currentButtonLayouts = maybeNode?.buttonNodes.map { ChatMessageActionButtonNode.asyncLayout($0) } ?? [] return { context, theme, strings, replyMarkup, message, constrainedWidth in diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageActionItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageActionItemNode.swift index e07c4c5351..27168747ad 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageActionItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageActionItemNode.swift @@ -7,6 +7,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import TextFormat private let titleFont = Font.regular(13.0) private let titleBoldFont = Font.bold(13.0) @@ -628,7 +629,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { TelegramTextAttributes.Hashtag ] for name in possibleNames { - if let _ = attributes[NSAttributedStringKey(rawValue: name)] { + if let _ = attributes[NSAttributedString.Key(rawValue: name)] { rects = self.labelNode.lineAndAttributeRects(name: name, at: index) break } @@ -669,19 +670,19 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { override func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture) -> ChatMessageBubbleContentTapAction { let textNodeFrame = self.labelNode.frame if let (index, attributes) = self.labelNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY - 10.0)), gesture == .tap { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { var concealed = true if let attributeText = self.labelNode.attributeSubstring(name: TelegramTextAttributes.URL, index: index) { concealed = !doesUrlMatchText(url: url, text: attributeText) } return .url(url: url, concealed: concealed) - } else if let peerMention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { + } else if let peerMention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { return .peerMention(peerMention.peerId, peerMention.mention) - } else if let peerName = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let peerName = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { return .textMention(peerName) - } else if let botCommand = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.BotCommand)] as? String { + } else if let botCommand = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.BotCommand)] as? String { return .botCommand(botCommand) - } else if let hashtag = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { + } else if let hashtag = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { return .hashtag(hashtag.peerName, hashtag.hashtag) } } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageActionUrlAuthController.swift b/submodules/TelegramUI/TelegramUI/ChatMessageActionUrlAuthController.swift index bd0be2c6d5..06a390302e 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageActionUrlAuthController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageActionUrlAuthController.swift @@ -6,6 +6,8 @@ import Display import Postbox import TelegramCore import TelegramPresentationData +import CheckNode +import TextFormat private let textFont = Font.regular(13.0) private let boldTextFont = Font.semibold(13.0) @@ -294,7 +296,7 @@ private final class ChatMessageActionUrlAuthAlertContentNode: AlertContentNode { } } -func chatMessageActionUrlAuthController(context: AccountContext, defaultUrl: String, domain: String, bot: Peer, requestWriteAccess: Bool, displayName: String, open: @escaping (Bool, Bool) -> Void) -> AlertController { +func chatMessageActionUrlAuthController(context: AccountContextImpl, defaultUrl: String, domain: String, bot: Peer, requestWriteAccess: Bool, displayName: String, open: @escaping (Bool, Bool) -> Void) -> AlertController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index 910a2e6738..58383f8a50 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -8,6 +8,7 @@ import TelegramCore import CoreImage import TelegramPresentationData import Compression +import TextFormat private let nameFont = Font.medium(14.0) private let inlineBotPrefixFont = Font.regular(14.0) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift index a418e9b723..478d2a7af8 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAttachedContentNode.swift @@ -8,6 +8,7 @@ import TelegramCore import Postbox import TelegramPresentationData import TelegramUIPreferences +import TextFormat private let titleFont = Font.semibold(15.0) private let textFont = Font.regular(15.0) @@ -228,7 +229,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { private var additionalImageBadgeNode: ChatMessageInteractiveMediaBadge? private var linkHighlightingNode: LinkHighlightingNode? - private var context: AccountContext? + private var context: AccountContextImpl? private var message: Message? private var media: Media? private var theme: ChatPresentationThemeData? @@ -270,7 +271,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { self.addSubnode(self.statusNode) } - func asyncLayout() -> (_ presentationData: ChatPresentationData, _ automaticDownloadSettings: MediaAutoDownloadSettings, _ associatedData: ChatMessageItemAssociatedData, _ context: AccountContext, _ controllerInteraction: ChatControllerInteraction, _ message: Message, _ messageRead: Bool, _ title: String?, _ subtitle: NSAttributedString?, _ text: String?, _ entities: [MessageTextEntity]?, _ media: (Media, ChatMessageAttachedContentNodeMediaFlags)?, _ mediaBadge: String?, _ actionIcon: ChatMessageAttachedContentActionIcon?, _ actionTitle: String?, _ displayLine: Bool, _ layoutConstants: ChatMessageItemLayoutConstants, _ constrainedSize: CGSize) -> (CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool) -> Void))) { + func asyncLayout() -> (_ presentationData: ChatPresentationData, _ automaticDownloadSettings: MediaAutoDownloadSettings, _ associatedData: ChatMessageItemAssociatedData, _ context: AccountContextImpl, _ controllerInteraction: ChatControllerInteraction, _ message: Message, _ messageRead: Bool, _ title: String?, _ subtitle: NSAttributedString?, _ text: String?, _ entities: [MessageTextEntity]?, _ media: (Media, ChatMessageAttachedContentNodeMediaFlags)?, _ mediaBadge: String?, _ actionIcon: ChatMessageAttachedContentActionIcon?, _ actionTitle: String?, _ displayLine: Bool, _ layoutConstants: ChatMessageItemLayoutConstants, _ constrainedSize: CGSize) -> (CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool) -> Void))) { let textAsyncLayout = TextNode.asyncLayout(self.textNode) let currentImage = self.media as? TelegramMediaImage let imageLayout = self.inlineImageNode.asyncLayout() @@ -958,19 +959,19 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture) -> ChatMessageBubbleContentTapAction { let textNodeFrame = self.textNode.frame if let (index, attributes) = self.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { var concealed = true if let attributeText = self.textNode.attributeSubstring(name: TelegramTextAttributes.URL, index: index) { concealed = !doesUrlMatchText(url: url, text: attributeText) } return .url(url: url, concealed: concealed) - } else if let peerMention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { + } else if let peerMention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { return .peerMention(peerMention.peerId, peerMention.mention) - } else if let peerName = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let peerName = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { return .textMention(peerName) - } else if let botCommand = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.BotCommand)] as? String { + } else if let botCommand = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.BotCommand)] as? String { return .botCommand(botCommand) - } else if let hashtag = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { + } else if let hashtag = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { return .hashtag(hashtag.peerName, hashtag.hashtag) } else { return .none @@ -994,7 +995,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { TelegramTextAttributes.Hashtag ] for name in possibleNames { - if let _ = attributes[NSAttributedStringKey(rawValue: name)] { + if let _ = attributes[NSAttributedString.Key(rawValue: name)] { rects = self.textNode.attributeRects(name: name, at: index) break } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAvatarAccessoryItem.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAvatarAccessoryItem.swift index b5c777c419..ba500c8f21 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAvatarAccessoryItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAvatarAccessoryItem.swift @@ -8,7 +8,7 @@ import TelegramPresentationData private let avatarFont = UIFont(name: ".SFCompactRounded-Semibold", size: 16.0)! final class ChatMessageAvatarAccessoryItem: ListViewAccessoryItem { - private let context: AccountContext + private let context: AccountContextImpl private let peerId: PeerId private let peer: Peer? private let messageReference: MessageReference? @@ -17,7 +17,7 @@ final class ChatMessageAvatarAccessoryItem: ListViewAccessoryItem { private let day: Int32 - init(context: AccountContext, peerId: PeerId, peer: Peer?, messageReference: MessageReference?, messageTimestamp: Int32, emptyColor: UIColor) { + init(context: AccountContextImpl, peerId: PeerId, peer: Peer?, messageReference: MessageReference?, messageTimestamp: Int32, emptyColor: UIColor) { self.context = context self.peerId = peerId self.peer = peer diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageBackground.swift b/submodules/TelegramUI/TelegramUI/ChatMessageBackground.swift index ac60654fe9..c7060d854f 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageBackground.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageBackground.swift @@ -2,6 +2,7 @@ import Foundation import UIKit import AsyncDisplayKit import Display +import TelegramPresentationData enum ChatMessageBackgroundMergeType: Equatable { case None, Side, Top(side: Bool), Bottom, Both diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleContentNode.swift index cafc20c6b4..605abf112c 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleContentNode.swift @@ -81,14 +81,14 @@ enum ChatMessageBubbleContentTapAction { } final class ChatMessageBubbleContentItem { - let context: AccountContext + let context: AccountContextImpl let controllerInteraction: ChatControllerInteraction let message: Message let read: Bool let presentationData: ChatPresentationData let associatedData: ChatMessageItemAssociatedData - init(context: AccountContext, controllerInteraction: ChatControllerInteraction, message: Message, read: Bool, presentationData: ChatPresentationData, associatedData: ChatMessageItemAssociatedData) { + init(context: AccountContextImpl, controllerInteraction: ChatControllerInteraction, message: Message, read: Bool, presentationData: ChatPresentationData, associatedData: ChatMessageItemAssociatedData) { self.context = context self.controllerInteraction = controllerInteraction self.message = message diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift index babf94bba4..1af8dbe32c 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageBubbleItemNode.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import TextFormat private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> [(Message, AnyClass)] { var result: [(Message, AnyClass)] = [] @@ -365,8 +366,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { authorNameLayout: (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode), adminBadgeLayout: (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode), forwardInfoLayout: (ChatPresentationData, PresentationStrings, ChatMessageForwardInfoType, Peer?, String?, CGSize) -> (CGSize, () -> ChatMessageForwardInfoNode), - replyInfoLayout: (ChatPresentationData, PresentationStrings, AccountContext, ChatMessageReplyInfoType, Message, CGSize) -> (CGSize, () -> ChatMessageReplyInfoNode), - actionButtonsLayout: (AccountContext, ChatPresentationThemeData, PresentationStrings, ReplyMarkupMessageAttribute, Message, CGFloat) -> (minWidth: CGFloat, layout: (CGFloat) -> (CGSize, (Bool) -> ChatMessageActionButtonsNode)), + replyInfoLayout: (ChatPresentationData, PresentationStrings, AccountContextImpl, ChatMessageReplyInfoType, Message, CGSize) -> (CGSize, () -> ChatMessageReplyInfoNode), + actionButtonsLayout: (AccountContextImpl, ChatPresentationThemeData, PresentationStrings, ReplyMarkupMessageAttribute, Message, CGFloat) -> (minWidth: CGFloat, layout: (CGFloat) -> (CGSize, (Bool) -> ChatMessageActionButtonsNode)), mosaicStatusLayout: (ChatPresentationData, Bool, Int?, String, ChatMessageDateAndStatusType, CGSize) -> (CGSize, (Bool) -> ChatMessageDateAndStatusNode), currentShareButtonNode: HighlightableButtonNode?, layoutConstants: ChatMessageItemLayoutConstants, @@ -876,7 +877,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { adminBadgeString = NSAttributedString(string: " \(item.presentationData.strings.Channel_Status)", font: inlineBotPrefixFont, textColor: messageTheme.secondaryTextColor) } if let authorNameString = authorNameString, let authorNameColor = authorNameColor, let inlineBotNameString = inlineBotNameString { - let mutableString = NSMutableAttributedString(string: "\(authorNameString) ", attributes: [NSAttributedStringKey.font: nameFont, NSAttributedStringKey.foregroundColor: authorNameColor]) + let mutableString = NSMutableAttributedString(string: "\(authorNameString) ", attributes: [NSAttributedString.Key.font: nameFont, NSAttributedString.Key.foregroundColor: authorNameColor]) let bodyAttributes = MarkdownAttributeSet(font: nameFont, textColor: inlineBotNameColor) let boldAttributes = MarkdownAttributeSet(font: inlineBotPrefixFont, textColor: inlineBotNameColor) let botString = addAttributesToStringWithRanges(item.presentationData.strings.Conversation_MessageViaUser("@\(inlineBotNameString)"), body: bodyAttributes, argumentAttributes: [0: boldAttributes]) @@ -2350,7 +2351,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { self.backgroundNode.setType(type: backgroundType, highlighted: false, graphics: graphics, transition: .immediate) if let updatedContents = self.backgroundNode.layer.contents { - self.backgroundNode.layer.animate(from: previousContents as AnyObject, to: updatedContents as AnyObject, keyPath: "contents", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.42) + self.backgroundNode.layer.animate(from: previousContents as AnyObject, to: updatedContents as AnyObject, keyPath: "contents", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.42) } } else { self.backgroundNode.setType(type: backgroundType, highlighted: false, graphics: graphics, transition: .immediate) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageDateAndStatusNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageDateAndStatusNode.swift index f407cc4fdc..1a812564b3 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageDateAndStatusNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageDateAndStatusNode.swift @@ -14,12 +14,12 @@ private func maybeAddRotationAnimation(_ layer: CALayer, duration: Double) { } let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = duration basicAnimation.fromValue = NSNumber(value: Float(0.0)) basicAnimation.toValue = NSNumber(value: Float(Double.pi * 2.0)) basicAnimation.repeatCount = Float.infinity - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) basicAnimation.beginTime = 1.0 layer.add(basicAnimation, forKey: "clockFrameAnimation") } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageForwardInfoNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageForwardInfoNode.swift index ef2422f254..5477304e76 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageForwardInfoNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageForwardInfoNode.swift @@ -77,9 +77,9 @@ class ChatMessageForwardInfoNode: ASDisplayNode { } let completeString: NSString = completeSourceString.0 as NSString - let string = NSMutableAttributedString(string: completeString as String, attributes: [NSAttributedStringKey.foregroundColor: titleColor, NSAttributedStringKey.font: prefixFont]) + let string = NSMutableAttributedString(string: completeString as String, attributes: [NSAttributedString.Key.foregroundColor: titleColor, NSAttributedString.Key.font: prefixFont]) if highlight, let range = completeSourceString.1.first?.1 { - string.addAttributes([NSAttributedStringKey.font: peerFont], range: range) + string.addAttributes([NSAttributedString.Key.font: peerFont], range: range) } var credibilityIconWidth: CGFloat = 0.0 diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageInstantVideoItemNode.swift index 9b696f95cb..1c6b12f95f 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageInstantVideoItemNode.swift @@ -7,6 +7,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import TextFormat private let nameFont = Font.medium(14.0) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveFileNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveFileNode.swift index 1c66d9ceb9..e84c21dc02 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveFileNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveFileNode.swift @@ -60,7 +60,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode { var activateLocalContent: () -> Void = { } var requestUpdateLayout: (Bool) -> Void = { _ in } - private var context: AccountContext? + private var context: AccountContextImpl? private var message: Message? private var themeAndStrings: (ChatPresentationThemeData, PresentationStrings, String)? private var file: TelegramMediaFile? @@ -184,7 +184,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode { } } - func asyncLayout() -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ message: Message, _ file: TelegramMediaFile, _ automaticDownload: Bool, _ incoming: Bool, _ isRecentActions: Bool, _ forcedResourceStatus: FileMediaResourceStatus?, _ dateAndStatusType: ChatMessageDateAndStatusType?, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, (Bool) -> Void))) { + func asyncLayout() -> (_ context: AccountContextImpl, _ presentationData: ChatPresentationData, _ message: Message, _ file: TelegramMediaFile, _ automaticDownload: Bool, _ incoming: Bool, _ isRecentActions: Bool, _ forcedResourceStatus: FileMediaResourceStatus?, _ dateAndStatusType: ChatMessageDateAndStatusType?, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, (Bool) -> Void))) { let currentFile = self.file let titleAsyncLayout = TextNode.asyncLayout(self.titleNode) @@ -540,7 +540,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode { if isVoice { if strongSelf.waveformScrubbingNode == nil { let waveformScrubbingNode = MediaPlayerScrubbingNode(content: .custom(backgroundNode: strongSelf.waveformNode, foregroundContentNode: strongSelf.waveformForegroundNode)) - waveformScrubbingNode.hitTestSlop = UIEdgeInsetsMake(-10.0, 0.0, -10.0, 0.0) + waveformScrubbingNode.hitTestSlop = UIEdgeInsets(top: -10.0, left: 0.0, bottom: -10.0, right: 0.0) waveformScrubbingNode.seek = { timestamp in if let strongSelf = self, let context = strongSelf.context, let message = strongSelf.message, let type = peerMessageMediaPlayerType(message) { context.sharedContext.mediaManager.playlistControl(.seek(timestamp), type: type) @@ -859,12 +859,12 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode { self.fetchingCompactTextNode.frame = CGRect(origin: self.descriptionNode.frame.origin, size: fetchingCompactSize) } - static func asyncLayout(_ node: ChatMessageInteractiveFileNode?) -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ message: Message, _ file: TelegramMediaFile, _ automaticDownload: Bool, _ incoming: Bool, _ isRecentActions: Bool, _ forcedResourceStatus: FileMediaResourceStatus?, _ dateAndStatusType: ChatMessageDateAndStatusType?, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, (Bool) -> ChatMessageInteractiveFileNode))) { + static func asyncLayout(_ node: ChatMessageInteractiveFileNode?) -> (_ context: AccountContextImpl, _ presentationData: ChatPresentationData, _ message: Message, _ file: TelegramMediaFile, _ automaticDownload: Bool, _ incoming: Bool, _ isRecentActions: Bool, _ forcedResourceStatus: FileMediaResourceStatus?, _ dateAndStatusType: ChatMessageDateAndStatusType?, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, (Bool) -> ChatMessageInteractiveFileNode))) { let currentAsyncLayout = node?.asyncLayout() return { context, presentationData, message, file, automaticDownload, incoming, isRecentActions, forcedResourceStatus, dateAndStatusType, constrainedSize in var fileNode: ChatMessageInteractiveFileNode - var fileLayout: (_ context: AccountContext, _ presentationData: ChatPresentationData, _ message: Message, _ file: TelegramMediaFile, _ automaticDownload: Bool, _ incoming: Bool, _ isRecentActions: Bool, _ forcedResourceStatus: FileMediaResourceStatus?, _ dateAndStatusType: ChatMessageDateAndStatusType?, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, (Bool) -> Void))) + var fileLayout: (_ context: AccountContextImpl, _ presentationData: ChatPresentationData, _ message: Message, _ file: TelegramMediaFile, _ automaticDownload: Bool, _ incoming: Bool, _ isRecentActions: Bool, _ forcedResourceStatus: FileMediaResourceStatus?, _ dateAndStatusType: ChatMessageDateAndStatusType?, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, (Bool) -> Void))) if let node = node, let currentAsyncLayout = currentAsyncLayout { fileNode = node diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaBadge.swift b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaBadge.swift index dcf1a72890..97dd146bdf 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaBadge.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaBadge.swift @@ -3,6 +3,7 @@ import UIKit import Display import AsyncDisplayKit import TelegramPresentationData +import TextFormat enum ChatMessageInteractiveMediaDownloadState: Equatable { case remote diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaNode.swift index fa6096a608..626a095eb4 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageInteractiveMediaNode.swift @@ -8,6 +8,7 @@ import TelegramCore import TelegramPresentationData import TelegramUIPreferences import UniversalMediaPlayer +import TextFormat private struct FetchControls { let fetch: (Bool) -> Void @@ -52,7 +53,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode { private var badgeNode: ChatMessageInteractiveMediaBadge? private var tapRecognizer: UITapGestureRecognizer? - private var context: AccountContext? + private var context: AccountContextImpl? private var message: Message? private var media: Media? private var themeAndStrings: (PresentationTheme, PresentationStrings, String)? @@ -199,7 +200,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode { } } - func asyncLayout() -> (_ context: AccountContext, _ theme: PresentationTheme, _ strings: PresentationStrings, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ media: Media, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ContainedViewLayoutTransition, Bool) -> Void))) { + func asyncLayout() -> (_ context: AccountContextImpl, _ theme: PresentationTheme, _ strings: PresentationStrings, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ media: Media, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ContainedViewLayoutTransition, Bool) -> Void))) { let currentMessage = self.message let currentMedia = self.media let imageLayout = self.imageNode.asyncLayout() @@ -1200,12 +1201,12 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode { } } - static func asyncLayout(_ node: ChatMessageInteractiveMediaNode?) -> (_ context: AccountContext, _ theme: PresentationTheme, _ strings: PresentationStrings, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ media: Media, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ContainedViewLayoutTransition, Bool) -> ChatMessageInteractiveMediaNode))) { + static func asyncLayout(_ node: ChatMessageInteractiveMediaNode?) -> (_ context: AccountContextImpl, _ theme: PresentationTheme, _ strings: PresentationStrings, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ media: Media, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ContainedViewLayoutTransition, Bool) -> ChatMessageInteractiveMediaNode))) { let currentAsyncLayout = node?.asyncLayout() return { context, theme, strings, dateTimeFormat, message, media, automaticDownload, peerType, sizeCalculation, layoutConstants, contentMode in var imageNode: ChatMessageInteractiveMediaNode - var imageLayout: (_ context: AccountContext, _ theme: PresentationTheme, _ strings: PresentationStrings, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ media: Media, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ContainedViewLayoutTransition, Bool) -> Void))) + var imageLayout: (_ context: AccountContextImpl, _ theme: PresentationTheme, _ strings: PresentationStrings, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ media: Media, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ContainedViewLayoutTransition, Bool) -> Void))) if let node = node, let currentAsyncLayout = currentAsyncLayout { imageNode = node diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift index c18041ac90..9c30a04bf9 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift @@ -246,7 +246,7 @@ public final class ChatMessageItemAssociatedData: Equatable { public final class ChatMessageItem: ListViewItem, CustomStringConvertible { let presentationData: ChatPresentationData - let context: AccountContext + let context: AccountContextImpl let chatLocation: ChatLocation let associatedData: ChatMessageItemAssociatedData let controllerInteraction: ChatControllerInteraction @@ -276,7 +276,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { } } - public init(presentationData: ChatPresentationData, context: AccountContext, chatLocation: ChatLocation, associatedData: ChatMessageItemAssociatedData, controllerInteraction: ChatControllerInteraction, content: ChatMessageItemContent, disableDate: Bool = false, additionalContent: ChatMessageItemAdditionalContent? = nil) { + public init(presentationData: ChatPresentationData, context: AccountContextImpl, chatLocation: ChatLocation, associatedData: ChatMessageItemAssociatedData, controllerInteraction: ChatControllerInteraction, content: ChatMessageItemContent, disableDate: Bool = false, additionalContent: ChatMessageItemAdditionalContent? = nil) { self.presentationData = presentationData self.context = context self.chatLocation = chatLocation diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageItemView.swift b/submodules/TelegramUI/TelegramUI/ChatMessageItemView.swift index a4f1d3fd33..7273bab3d8 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageItemView.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageItemView.swift @@ -148,7 +148,7 @@ final class ChatMessageAccessibilityData { var label: String = "" let value: String var hint: String? - var traits: UIAccessibilityTraits = 0 + var traits: UIAccessibilityTraits = [] var singleUrl: String? var customActions: [ChatMessageAccessibilityCustomAction] = [] @@ -194,7 +194,7 @@ final class ChatMessageAccessibilityData { if isSelected == nil { hint = "Double tap to play" } - traits |= UIAccessibilityTraitStartsMediaSession + traits.insert(.startsMediaSession) if audio.isVoice { let durationString = voiceMessageDurationFormatter.string(from: Double(audio.duration)) ?? "" if isIncoming { @@ -227,7 +227,7 @@ final class ChatMessageAccessibilityData { if isSelected == nil { hint = "Double tap to play" } - traits |= UIAccessibilityTraitStartsMediaSession + traits.insert(.startsMediaSession) let durationString = voiceMessageDurationFormatter.string(from: Double(video.duration)) ?? "" if video.flags.contains(.instantRoundVideo) { if isIncoming { @@ -458,7 +458,7 @@ final class ChatMessageAccessibilityData { if isSelected { result += "Selected.\n" } - traits |= UIAccessibilityTraitStartsMediaSession + traits.insert(.startsMediaSession) } result += "\(text)" diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationPositionNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationPositionNode.swift index 0a275de1d7..e492a7ce61 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationPositionNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationPositionNode.swift @@ -15,7 +15,7 @@ private func addPulseAnimations(layer: CALayer) { scaleAnimation.keyTimes = [0.0 as NSNumber, 0.49 as NSNumber, 0.88 as NSNumber, 1.0 as NSNumber] scaleAnimation.duration = 3.0 scaleAnimation.repeatCount = Float.infinity - scaleAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) + scaleAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut) scaleAnimation.beginTime = 1.0 layer.add(scaleAnimation, forKey: "pulse-scale") diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationTextNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationTextNode.swift index 4601f2b0ab..f4a5872358 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationTextNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationTextNode.swift @@ -55,7 +55,7 @@ final class ChatMessageLiveLocationTextNode: ASDisplayNode { self?.setNeedsDisplay() }), selector: #selector(RadialTimeoutNodeTimer.event), userInfo: nil, repeats: true) self.updateTimer = updateTimer - RunLoop.main.add(updateTimer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(updateTimer, forMode: .common) } } @@ -81,7 +81,7 @@ final class ChatMessageLiveLocationTextNode: ASDisplayNode { } if let parameters = parameters as? ChatMessageLiveLocationTextNodeParams { - let attributes: [NSAttributedStringKey: Any] = [.font: textFont, .foregroundColor: parameters.color] + let attributes: [NSAttributedString.Key: Any] = [.font: textFont, .foregroundColor: parameters.color] let nsString = parameters.string as NSString nsString.draw(at: CGPoint(x: 0.0, y: 0.0), withAttributes: attributes) } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationTimerNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationTimerNode.swift index e061f23841..f710ba497a 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationTimerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageLiveLocationTimerNode.swift @@ -60,7 +60,7 @@ final class ChatMessageLiveLocationTimerNode: ASDisplayNode { self?.setNeedsDisplay() }), selector: #selector(RadialTimeoutNodeTimer.event), userInfo: nil, repeats: true) self.animationTimer = animationTimer - RunLoop.main.add(animationTimer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(animationTimer, forMode: .common) } } @@ -119,7 +119,7 @@ final class ChatMessageLiveLocationTimerNode: ASDisplayNode { path.lineCapStyle = .round path.stroke() - let attributes: [NSAttributedStringKey: Any] = [.font: textFont, .foregroundColor: parameters.foregroundColor] + let attributes: [NSAttributedString.Key: Any] = [.font: textFont, .foregroundColor: parameters.foregroundColor] let nsString = parameters.string as NSString let size = nsString.size(withAttributes: attributes) nsString.draw(at: CGPoint(x: floor((bounds.size.width - size.width) / 2.0), y: floor((bounds.size.height - size.height) / 2.0)), withAttributes: attributes) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageNotificationItem.swift b/submodules/TelegramUI/TelegramUI/ChatMessageNotificationItem.swift index 18d338bfa9..5f820f907a 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageNotificationItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageNotificationItem.swift @@ -9,7 +9,7 @@ import TelegramPresentationData import TelegramUIPreferences public final class ChatMessageNotificationItem: NotificationItem { - let context: AccountContext + let context: AccountContextImpl let strings: PresentationStrings let nameDisplayOrder: PresentationPersonNameOrder let messages: [Message] @@ -20,7 +20,7 @@ public final class ChatMessageNotificationItem: NotificationItem { return messages.first?.id.peerId } - public init(context: AccountContext, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, messages: [Message], tapAction: @escaping () -> Bool, expandAction: @escaping (() -> (ASDisplayNode?, () -> Void)) -> Void) { + public init(context: AccountContextImpl, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, messages: [Message], tapAction: @escaping () -> Bool, expandAction: @escaping (() -> (ASDisplayNode?, () -> Void)) -> Void) { self.context = context self.strings = strings self.nameDisplayOrder = nameDisplayOrder diff --git a/submodules/TelegramUI/TelegramUI/ChatMessagePollBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessagePollBubbleContentNode.swift index acd97cd28c..90d8c6c6f1 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessagePollBubbleContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessagePollBubbleContentNode.swift @@ -4,6 +4,7 @@ import AsyncDisplayKit import Display import TelegramCore import Postbox +import TextFormat struct PercentCounterItem: Comparable { var index: Int = 0 @@ -176,7 +177,7 @@ private final class ChatMessagePollOptionRadioNode: ASDisplayNode { let displayLink = CADisplayLink(target: DisplayLinkProxy({ [weak self] in self?.setNeedsDisplay() }), selector: #selector(DisplayLinkProxy.displayLinkEvent)) - displayLink.add(to: .main, forMode: .commonModes) + displayLink.add(to: .main, forMode: .common) self.displayLink = displayLink } self.setNeedsDisplay() @@ -459,7 +460,7 @@ private final class ChatMessagePollOptionNode: ASDisplayNode { let animation = CAKeyframeAnimation(keyPath: "contents") animation.values = images.map { $0.cgImage! } animation.duration = percentageDuration * UIView.animationDurationFactor() - animation.calculationMode = kCAAnimationDiscrete + animation.calculationMode = .discrete node.percentageNode.layer.add(animation, forKey: "image") } } @@ -908,19 +909,19 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode { override func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture) -> ChatMessageBubbleContentTapAction { let textNodeFrame = self.textNode.frame if let (index, attributes) = self.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { var concealed = true if let attributeText = self.textNode.attributeSubstring(name: TelegramTextAttributes.URL, index: index) { concealed = !doesUrlMatchText(url: url, text: attributeText) } return .url(url: url, concealed: concealed) - } else if let peerMention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { + } else if let peerMention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { return .peerMention(peerMention.peerId, peerMention.mention) - } else if let peerName = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let peerName = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { return .textMention(peerName) - } else if let botCommand = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.BotCommand)] as? String { + } else if let botCommand = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.BotCommand)] as? String { return .botCommand(botCommand) - } else if let hashtag = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { + } else if let hashtag = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { return .hashtag(hashtag.peerName, hashtag.hashtag) } else { return .none diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageReplyInfoNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageReplyInfoNode.swift index ca2b9fa1cd..bd17d3fe45 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageReplyInfoNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageReplyInfoNode.swift @@ -41,7 +41,7 @@ class ChatMessageReplyInfoNode: ASDisplayNode { self.contentNode.addSubnode(self.lineNode) } - class func asyncLayout(_ maybeNode: ChatMessageReplyInfoNode?) -> (_ theme: ChatPresentationData, _ strings: PresentationStrings, _ context: AccountContext, _ type: ChatMessageReplyInfoType, _ message: Message, _ constrainedSize: CGSize) -> (CGSize, () -> ChatMessageReplyInfoNode) { + class func asyncLayout(_ maybeNode: ChatMessageReplyInfoNode?) -> (_ theme: ChatPresentationData, _ strings: PresentationStrings, _ context: AccountContextImpl, _ type: ChatMessageReplyInfoType, _ message: Message, _ constrainedSize: CGSize) -> (CGSize, () -> ChatMessageReplyInfoNode) { let titleNodeLayout = TextNode.asyncLayout(maybeNode?.titleNode) let textNodeLayout = TextNode.asyncLayout(maybeNode?.textNode) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageSelectionNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageSelectionNode.swift index 5dccab0809..facf67d2dc 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageSelectionNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageSelectionNode.swift @@ -2,6 +2,7 @@ import Foundation import UIKit import AsyncDisplayKit import TelegramPresentationData +import CheckNode final class ChatMessageSelectionNode: ASDisplayNode { private let toggle: (Bool) -> Void diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift index f21455166f..7d44bf00cb 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import TextFormat private let nameFont = Font.medium(14.0) private let inlineBotPrefixFont = Font.regular(14.0) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift index e33571fb75..ffdbcde6fe 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageTextBubbleContentNode.swift @@ -4,6 +4,7 @@ import AsyncDisplayKit import Display import TelegramCore import Postbox +import TextFormat private final class CachedChatMessageText { let text: String @@ -377,21 +378,21 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { override func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture) -> ChatMessageBubbleContentTapAction { let textNodeFrame = self.textNode.frame if let (index, attributes) = self.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { var concealed = true if let attributeText = self.textNode.attributeSubstring(name: TelegramTextAttributes.URL, index: index) { concealed = !doesUrlMatchText(url: url, text: attributeText) } return .url(url: url, concealed: concealed) - } else if let peerMention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { + } else if let peerMention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { return .peerMention(peerMention.peerId, peerMention.mention) - } else if let peerName = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let peerName = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { return .textMention(peerName) - } else if let botCommand = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.BotCommand)] as? String { + } else if let botCommand = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.BotCommand)] as? String { return .botCommand(botCommand) - } else if let hashtag = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { + } else if let hashtag = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag)] as? TelegramHashtag { return .hashtag(hashtag.peerName, hashtag.hashtag) - } else if let timecode = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.Timecode)] as? TelegramTimecode { + } else if let timecode = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Timecode)] as? TelegramTimecode { return .timecode(timecode.time, timecode.text) } else { return .none @@ -416,7 +417,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { TelegramTextAttributes.Timecode ] for name in possibleNames { - if let _ = attributes[NSAttributedStringKey(rawValue: name)] { + if let _ = attributes[NSAttributedString.Key(rawValue: name)] { rects = self.textNode.attributeRects(name: name, at: index) break } @@ -448,7 +449,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { if let item = self.item { let textNodeFrame = self.textNode.frame if let (index, attributes) = self.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) { - if let value = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let value = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { if let rects = self.textNode.attributeRects(name: TelegramTextAttributes.URL, at: index), !rects.isEmpty { var rect = rects[0] for i in 1 ..< rects.count { diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageWebpageBubbleContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageWebpageBubbleContentNode.swift index 399b9d423f..1241971ba7 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageWebpageBubbleContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageWebpageBubbleContentNode.swift @@ -6,6 +6,7 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramCore import TelegramUIPreferences +import TextFormat enum WebsiteType { case generic diff --git a/submodules/TelegramUI/TelegramUI/ChatOverlayNavigationBar.swift b/submodules/TelegramUI/TelegramUI/ChatOverlayNavigationBar.swift index f2aeb99cb5..929cfa6772 100644 --- a/submodules/TelegramUI/TelegramUI/ChatOverlayNavigationBar.swift +++ b/submodules/TelegramUI/TelegramUI/ChatOverlayNavigationBar.swift @@ -49,7 +49,7 @@ final class ChatOverlayNavigationBar: ASDisplayNode { self.titleNode.isUserInteractionEnabled = false self.closeButton = HighlightableButtonNode() - self.closeButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0) + self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0) self.closeButton.displaysAsynchronously = false let closeImage = generateImage(CGSize(width: 12.0, height: 12.0), contextGenerator: { size, context in diff --git a/submodules/TelegramUI/TelegramUI/ChatPinnedMessageTitlePanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatPinnedMessageTitlePanelNode.swift index d620db3a8e..0abcf97a3b 100644 --- a/submodules/TelegramUI/TelegramUI/ChatPinnedMessageTitlePanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatPinnedMessageTitlePanelNode.swift @@ -9,7 +9,7 @@ import TelegramPresentationData import TelegramUIPreferences final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { - private let context: AccountContext + private let context: AccountContextImpl private let tapButton: HighlightTrackingButtonNode private let closeButton: HighlightableButtonNode private let lineNode: ASImageNode @@ -27,13 +27,13 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { private let queue = Queue() - init(context: AccountContext) { + init(context: AccountContextImpl) { self.context = context self.tapButton = HighlightTrackingButtonNode() self.closeButton = HighlightableButtonNode() - self.closeButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0) + self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0) self.closeButton.displaysAsynchronously = false self.separatorNode = ASDisplayNode() diff --git a/submodules/TelegramUI/TelegramUI/ChatPresentationData.swift b/submodules/TelegramUI/TelegramUI/ChatPresentationData.swift index 1fd121b7fc..5a0d87496f 100644 --- a/submodules/TelegramUI/TelegramUI/ChatPresentationData.swift +++ b/submodules/TelegramUI/TelegramUI/ChatPresentationData.swift @@ -26,33 +26,6 @@ extension PresentationFontSize { } } -extension TelegramWallpaper { - var isEmpty: Bool { - switch self { - case .image: - return false - case let .file(file): - if file.isPattern, file.settings.color == 0xffffff { - return true - } else { - return false - } - case let .color(color): - return color == 0xffffff - default: - return false - } - } - var isBuiltin: Bool { - switch self { - case .builtin: - return true - default: - return false - } - } -} - public final class ChatPresentationThemeData: Equatable { public let theme: PresentationTheme public let wallpaper: TelegramWallpaper diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsController.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsController.swift index b2854d262b..1f3748bec1 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsController.swift @@ -11,7 +11,7 @@ final class ChatRecentActionsController: TelegramController { return self.displayNode as! ChatRecentActionsControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let peer: Peer private var presentationData: PresentationData private var presentationDataDisposable: Disposable? @@ -21,7 +21,7 @@ final class ChatRecentActionsController: TelegramController { private let titleView: ChatRecentActionsTitleView - init(context: AccountContext, peer: Peer) { + init(context: AccountContextImpl, peer: Peer) { self.context = context self.peer = peer diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift index 5d58516804..7beadbaf53 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift @@ -20,7 +20,7 @@ private final class ChatRecentActionsListOpaqueState { } final class ChatRecentActionsControllerNode: ViewControllerTracingNode { - private let context: AccountContext + private let context: AccountContextImpl private let peer: Peer private var presentationData: PresentationData @@ -71,7 +71,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { private var adminsState: ChannelMemberListState? private let banDisposables = DisposableDict() - init(context: AccountContext, peer: Peer, presentationData: PresentationData, interaction: ChatRecentActionsInteraction, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, Any?) -> Void, getNavigationController: @escaping () -> NavigationController?) { + init(context: AccountContextImpl, peer: Peer, presentationData: PresentationData, interaction: ChatRecentActionsInteraction, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, Any?) -> Void, getNavigationController: @escaping () -> NavigationController?) { self.context = context self.peer = peer self.presentationData = presentationData diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsEmptyNode.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsEmptyNode.swift index 9d6921f857..29809d97fe 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsEmptyNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsEmptyNode.swift @@ -47,7 +47,7 @@ final class ChatRecentActionsEmptyNode: ASDisplayNode { func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) { self.layoutParams = size - let insets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0) + let insets = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0) let maxTextWidth = size.width - insets.left - insets.right - 18.0 * 2.0 diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsFilterController.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsFilterController.swift index 7f39107943..0b6499df5f 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsFilterController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsFilterController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class ChatRecentActionsFilterControllerArguments { let account: Account @@ -359,7 +360,7 @@ private func channelRecentActionsFilterControllerEntries(presentationData: Prese return entries } -public func channelRecentActionsFilterController(context: AccountContext, peer: Peer, events: AdminLogEventsFlags, adminPeerIds: [PeerId]?, apply: @escaping (_ events: AdminLogEventsFlags, _ adminPeerIds: [PeerId]?) -> Void) -> ViewController { +public func channelRecentActionsFilterController(context: AccountContextImpl, 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 diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift index 85c0d4b7cc..b3eca557c5 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift @@ -4,6 +4,7 @@ import Display import TelegramCore import Postbox import TelegramPresentationData +import MergeLists enum ChatRecentActionsEntryContentIndex: Int32 { case header = 0 @@ -103,7 +104,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { return self.id } - func item(context: AccountContext, peer: Peer, controllerInteraction: ChatControllerInteraction) -> ListViewItem { + func item(context: AccountContextImpl, peer: Peer, controllerInteraction: ChatControllerInteraction) -> ListViewItem { switch self.entry.event.action { case let .changeTitle(_, new): var peers = SimpleDictionary() @@ -1058,7 +1059,7 @@ struct ChatRecentActionsHistoryTransition { let isEmpty: Bool } -func chatRecentActionsHistoryPreparedTransition(from fromEntries: [ChatRecentActionsEntry], to toEntries: [ChatRecentActionsEntry], type: ChannelAdminEventLogUpdateType, canLoadEarlier: Bool, displayingResults: Bool, context: AccountContext, peer: Peer, controllerInteraction: ChatControllerInteraction) -> ChatRecentActionsHistoryTransition { +func chatRecentActionsHistoryPreparedTransition(from fromEntries: [ChatRecentActionsEntry], to toEntries: [ChatRecentActionsEntry], type: ChannelAdminEventLogUpdateType, canLoadEarlier: Bool, displayingResults: Bool, context: AccountContextImpl, peer: Peer, controllerInteraction: ChatControllerInteraction) -> ChatRecentActionsHistoryTransition { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } diff --git a/submodules/TelegramUI/TelegramUI/ChatRecordingPreviewInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatRecordingPreviewInputPanelNode.swift index a782fc2bc9..0ffdb8ddd9 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecordingPreviewInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecordingPreviewInputPanelNode.swift @@ -62,7 +62,7 @@ final class ChatRecordingPreviewInputPanelNode: ChatInputPanelNode { self.pauseButton.isUserInteractionEnabled = false self.waveformButton = ASButtonNode() - self.waveformButton.accessibilityTraits |= UIAccessibilityTraitStartsMediaSession + self.waveformButton.accessibilityTraits.insert(.startsMediaSession) self.waveformNode = AudioWaveformNode() self.waveformNode.isLayerBacked = true diff --git a/submodules/TelegramUI/TelegramUI/ChatRecordingVideoActivityContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatRecordingVideoActivityContentNode.swift index 0097bfb03c..6fc499972a 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecordingVideoActivityContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecordingVideoActivityContentNode.swift @@ -20,7 +20,7 @@ private class ChatRecordingVideoActivityIndicatorNode: ChatTitleActivityIndicato } override var timingFunction: CAMediaTimingFunction { - return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + return CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) } override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? { diff --git a/submodules/TelegramUI/TelegramUI/ChatReportPeerTitlePanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatReportPeerTitlePanelNode.swift index a54f4e9ff5..63ff68c6bc 100644 --- a/submodules/TelegramUI/TelegramUI/ChatReportPeerTitlePanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatReportPeerTitlePanelNode.swift @@ -76,7 +76,7 @@ final class ChatReportPeerTitlePanelNode: ChatTitleAccessoryPanelNode { self.separatorNode.isLayerBacked = true self.closeButton = HighlightableButtonNode() - self.closeButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0) + self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0) self.closeButton.displaysAsynchronously = false super.init() diff --git a/submodules/TelegramUI/TelegramUI/ChatSearchInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatSearchInputPanelNode.swift index b336426a9f..ef1a4309ec 100644 --- a/submodules/TelegramUI/TelegramUI/ChatSearchInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatSearchInputPanelNode.swift @@ -6,6 +6,7 @@ import TelegramCore import Postbox import SwiftSignalKit import TelegramPresentationData +import ActivityIndicator private let labelFont = Font.regular(15.0) diff --git a/submodules/TelegramUI/TelegramUI/ChatSecretAutoremoveTimerActionSheet.swift b/submodules/TelegramUI/TelegramUI/ChatSecretAutoremoveTimerActionSheet.swift index d02e822920..9b386f7f79 100644 --- a/submodules/TelegramUI/TelegramUI/ChatSecretAutoremoveTimerActionSheet.swift +++ b/submodules/TelegramUI/TelegramUI/ChatSecretAutoremoveTimerActionSheet.swift @@ -16,7 +16,7 @@ final class ChatSecretAutoremoveTimerActionSheetController: ActionSheetControlle return self._ready } - init(context: AccountContext, currentValue: Int32, applyValue: @escaping (Int32) -> Void) { + init(context: AccountContextImpl, currentValue: Int32, applyValue: @escaping (Int32) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetController.swift b/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetController.swift index fe8c69a922..9c035db637 100644 --- a/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetController.swift @@ -10,7 +10,7 @@ final class ChatSendMessageActionSheetController: ViewController { return self.displayNode as! ChatSendMessageActionSheetControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let controllerInteraction: ChatControllerInteraction? private let interfaceState: ChatPresentationInterfaceState private let sendButtonFrame: CGRect @@ -25,7 +25,7 @@ final class ChatSendMessageActionSheetController: ViewController { private let hapticFeedback = HapticFeedback() - init(context: AccountContext, controllerInteraction: ChatControllerInteraction?, interfaceState: ChatPresentationInterfaceState, sendButtonFrame: CGRect, textInputNode: EditableTextNode, completion: @escaping () -> Void) { + init(context: AccountContextImpl, controllerInteraction: ChatControllerInteraction?, interfaceState: ChatPresentationInterfaceState, sendButtonFrame: CGRect, textInputNode: EditableTextNode, completion: @escaping () -> Void) { self.context = context self.controllerInteraction = controllerInteraction self.interfaceState = interfaceState diff --git a/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift index 66452f17b2..780fb1dd4f 100644 --- a/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatSendMessageActionSheetControllerNode.swift @@ -128,7 +128,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, private var validLayout: ContainerViewLayout? - init(context: AccountContext, sendButtonFrame: CGRect, textInputNode: EditableTextNode, forwardedCount: Int?, send: (() -> Void)?, sendSilently: (() -> Void)?, cancel: (() -> Void)?) { + init(context: AccountContextImpl, sendButtonFrame: CGRect, textInputNode: EditableTextNode, forwardedCount: Int?, send: (() -> Void)?, sendSilently: (() -> Void)?, cancel: (() -> Void)?) { self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.sendButtonFrame = sendButtonFrame self.textFieldFrame = textInputNode.convert(textInputNode.bounds, to: nil) @@ -205,13 +205,13 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, self.fromMessageTextNode.attributedText = attributedText if let toAttributedText = self.fromMessageTextNode.attributedText?.mutableCopy() as? NSMutableAttributedString { - toAttributedText.addAttribute(NSAttributedStringKey.foregroundColor, value: self.presentationData.theme.chat.message.outgoing.primaryTextColor, range: NSMakeRange(0, (toAttributedText.string as NSString).length)) + toAttributedText.addAttribute(NSAttributedString.Key.foregroundColor, value: self.presentationData.theme.chat.message.outgoing.primaryTextColor, range: NSMakeRange(0, (toAttributedText.string as NSString).length)) self.toMessageTextNode.attributedText = toAttributedText } } else { - self.fromMessageTextNode.attributedText = NSAttributedString(string: self.presentationData.strings.Conversation_InputTextPlaceholder, attributes: [NSAttributedStringKey.foregroundColor: self.presentationData.theme.chat.inputPanel.inputPlaceholderColor, NSAttributedStringKey.font: Font.regular(self.presentationData.fontSize.baseDisplaySize)]) + self.fromMessageTextNode.attributedText = NSAttributedString(string: self.presentationData.strings.Conversation_InputTextPlaceholder, attributes: [NSAttributedString.Key.foregroundColor: self.presentationData.theme.chat.inputPanel.inputPlaceholderColor, NSAttributedString.Key.font: Font.regular(self.presentationData.fontSize.baseDisplaySize)]) - self.toMessageTextNode.attributedText = NSAttributedString(string: self.presentationData.strings.ForwardedMessages(Int32(forwardedCount ?? 0)), attributes: [NSAttributedStringKey.foregroundColor: self.presentationData.theme.chat.message.outgoing.primaryTextColor, NSAttributedStringKey.font: Font.regular(self.presentationData.fontSize.baseDisplaySize)]) + self.toMessageTextNode.attributedText = NSAttributedString(string: self.presentationData.strings.ForwardedMessages(Int32(forwardedCount ?? 0)), attributes: [NSAttributedString.Key.foregroundColor: self.presentationData.theme.chat.message.outgoing.primaryTextColor, NSAttributedString.Key.font: Font.regular(self.presentationData.fontSize.baseDisplaySize)]) } self.messageBackgroundNode.contentMode = .scaleToFill @@ -281,7 +281,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: []) if let toAttributedText = self.textInputNode.attributedText?.mutableCopy() as? NSMutableAttributedString { - toAttributedText.addAttribute(NSAttributedStringKey.foregroundColor, value: self.presentationData.theme.chat.message.outgoing.primaryTextColor, range: NSMakeRange(0, (toAttributedText.string as NSString).length)) + toAttributedText.addAttribute(NSAttributedString.Key.foregroundColor, value: self.presentationData.theme.chat.message.outgoing.primaryTextColor, range: NSMakeRange(0, (toAttributedText.string as NSString).length)) self.toMessageTextNode.attributedText = toAttributedText } @@ -338,7 +338,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, if let layout = self.validLayout { let duration = 0.4 - self.sendButtonNode.layer.animateScale(from: 0.75, to: 1.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear) + self.sendButtonNode.layer.animateScale(from: 0.75, to: 1.0, duration: 0.2, timingFunction: CAMediaTimingFunctionName.linear.rawValue) self.sendButtonNode.layer.animatePosition(from: self.sendButtonFrame.center, to: self.sendButtonNode.position, duration: duration, timingFunction: kCAMediaTimingFunctionSpring) var initialWidth = self.textFieldFrame.width + 32.0 @@ -431,8 +431,8 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, if !cancel { self.buttonCoverNode.isHidden = true - self.sendButtonNode.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false) - self.sendButtonNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false) + self.sendButtonNode.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false) + self.sendButtonNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false) } var initialWidth = self.textFieldFrame.width + 32.0 diff --git a/submodules/TelegramUI/TelegramUI/ChatSlowmodeItem.swift b/submodules/TelegramUI/TelegramUI/ChatSlowmodeItem.swift index 6cc629952f..f0f93b0312 100644 --- a/submodules/TelegramUI/TelegramUI/ChatSlowmodeItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatSlowmodeItem.swift @@ -7,6 +7,7 @@ import TelegramCore import TelegramUIPreferences import TelegramPresentationData import LegacyComponents +import ItemListUI class ChatSlowmodeItem: ListViewItem, ItemListItem { let theme: PresentationTheme @@ -157,7 +158,7 @@ class ChatSlowmodeItemNode: ListViewItemNode { sliderView.knobImage = generateKnobImage() sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + 15.0, y: 37.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - 15.0 * 2.0, height: 44.0)) - sliderView.hitTestEdgeInsets = UIEdgeInsetsMake(-sliderView.frame.minX, 0.0, 0.0, -sliderView.frame.minX) + sliderView.hitTestEdgeInsets = UIEdgeInsets(top: -sliderView.frame.minX, left: 0.0, bottom: 0.0, right: -sliderView.frame.minX) } self.view.addSubview(sliderView) sliderView.addTarget(self, action: #selector(self.sliderValueChanged), for: .valueChanged) @@ -271,7 +272,7 @@ class ChatSlowmodeItemNode: ListViewItemNode { } sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + 15.0, y: 37.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - 15.0 * 2.0, height: 44.0)) - sliderView.hitTestEdgeInsets = UIEdgeInsetsMake(-sliderView.frame.minX, 0.0, 0.0, -sliderView.frame.minX) + sliderView.hitTestEdgeInsets = UIEdgeInsets(top: -sliderView.frame.minX, left: 0.0, bottom: 0.0, right: -sliderView.frame.minX) strongSelf.updateSliderView() } diff --git a/submodules/TelegramUI/TelegramUI/ChatTextFormat.swift b/submodules/TelegramUI/TelegramUI/ChatTextFormat.swift new file mode 100644 index 0000000000..f832b5aedc --- /dev/null +++ b/submodules/TelegramUI/TelegramUI/ChatTextFormat.swift @@ -0,0 +1,76 @@ +import Foundation +import TextFormat + +func chatTextInputAddFormattingAttribute(_ state: ChatTextInputState, attribute: NSAttributedString.Key) -> ChatTextInputState { + if !state.selectionRange.isEmpty { + let nsRange = NSRange(location: state.selectionRange.lowerBound, length: state.selectionRange.count) + var addAttribute = true + var attributesToRemove: [NSAttributedString.Key] = [] + state.inputText.enumerateAttributes(in: nsRange, options: .longestEffectiveRangeNotRequired) { attributes, range, stop in + for (key, _) in attributes { + if key == attribute && range == nsRange { + addAttribute = false + attributesToRemove.append(key) + } + } + } + + let result = NSMutableAttributedString(attributedString: state.inputText) + for attribute in attributesToRemove { + result.removeAttribute(attribute, range: nsRange) + } + if addAttribute { + result.addAttribute(attribute, value: true as Bool, range: nsRange) + } + return ChatTextInputState(inputText: result, selectionRange: state.selectionRange) + } else { + return state + } +} + +func chatTextInputClearFormattingAttributes(_ state: ChatTextInputState) -> ChatTextInputState { + if !state.selectionRange.isEmpty { + let nsRange = NSRange(location: state.selectionRange.lowerBound, length: state.selectionRange.count) + var attributesToRemove: [NSAttributedString.Key] = [] + state.inputText.enumerateAttributes(in: nsRange, options: .longestEffectiveRangeNotRequired) { attributes, range, stop in + for (key, _) in attributes { + attributesToRemove.append(key) + } + } + + let result = NSMutableAttributedString(attributedString: state.inputText) + for attribute in attributesToRemove { + result.removeAttribute(attribute, range: nsRange) + } + return ChatTextInputState(inputText: result, selectionRange: state.selectionRange) + } else { + return state + } +} + +func chatTextInputAddLinkAttribute(_ state: ChatTextInputState, url: String) -> ChatTextInputState { + if !state.selectionRange.isEmpty { + let nsRange = NSRange(location: state.selectionRange.lowerBound, length: state.selectionRange.count) + var linkRange = nsRange + var attributesToRemove: [(NSAttributedString.Key, NSRange)] = [] + state.inputText.enumerateAttributes(in: nsRange, options: .longestEffectiveRangeNotRequired) { attributes, range, stop in + for (key, _) in attributes { + if key == ChatTextInputAttributes.textUrl { + attributesToRemove.append((key, range)) + linkRange = linkRange.union(range) + } else { + attributesToRemove.append((key, nsRange)) + } + } + } + + let result = NSMutableAttributedString(attributedString: state.inputText) + for (attribute, range) in attributesToRemove { + result.removeAttribute(attribute, range: range) + } + result.addAttribute(ChatTextInputAttributes.textUrl, value: ChatTextInputTextUrlAttribute(url: url), range: nsRange) + return ChatTextInputState(inputText: result, selectionRange: state.selectionRange) + } else { + return state + } +} diff --git a/submodules/TelegramUI/TelegramUI/ChatTextInputActionButtonsNode.swift b/submodules/TelegramUI/TelegramUI/ChatTextInputActionButtonsNode.swift index ac8302d487..f55288cd82 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTextInputActionButtonsNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTextInputActionButtonsNode.swift @@ -32,7 +32,7 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode { super.init() self.isAccessibilityElement = true - self.accessibilityTraits = UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled + self.accessibilityTraits = [.button, .notEnabled] self.sendButton.highligthedChanged = { [weak self] highlighted in if let strongSelf = self { @@ -123,7 +123,7 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode { func updateAccessibility() { if !self.micButton.alpha.isZero { - self.accessibilityTraits = UIAccessibilityTraitButton + self.accessibilityTraits = .button switch self.micButton.mode { case .audio: self.accessibilityLabel = "Voice Message" @@ -133,7 +133,7 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode { self.accessibilityHint = "Double tap and hold to record voice message. Slide up to pin recording, slide left to cancel. Double tap to switch to audio." } } else { - self.accessibilityTraits = UIAccessibilityTraitButton + self.accessibilityTraits = .button self.accessibilityLabel = "Send" self.accessibilityHint = nil } diff --git a/submodules/TelegramUI/TelegramUI/ChatTextInputAudioRecordingOverlayButton.swift b/submodules/TelegramUI/TelegramUI/ChatTextInputAudioRecordingOverlayButton.swift index 58561906f6..6b56c873e0 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTextInputAudioRecordingOverlayButton.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTextInputAudioRecordingOverlayButton.swift @@ -108,7 +108,7 @@ final class ChatTextInputAudioRecordingOverlay { self.animatedIn = true self.animationStartTime = CACurrentMediaTime() - self.displayLink?.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink?.add(to: RunLoop.main, forMode: .common) self.displayLink?.isPaused = false } } diff --git a/submodules/TelegramUI/TelegramUI/ChatTextInputMenu.swift b/submodules/TelegramUI/TelegramUI/ChatTextInputMenu.swift index ba6db9b6e9..3dfb32530c 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTextInputMenu.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTextInputMenu.swift @@ -44,7 +44,7 @@ final class ChatTextInputMenu { private var observer: NSObjectProtocol? init() { - self.observer = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIMenuControllerDidHideMenu, object: nil, queue: nil, using: { [weak self] _ in + self.observer = NotificationCenter.default.addObserver(forName: UIMenuController.didHideMenuNotification, object: nil, queue: nil, using: { [weak self] _ in self?.back() }) } diff --git a/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift index 2532044104..a930be79c3 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import MobileCoreServices import TelegramPresentationData +import TextFormat private let searchLayoutProgressImage = generateImage(CGSize(width: 22.0, height: 22.0), contextGenerator: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) @@ -260,7 +261,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { } } - override var context: AccountContext? { + override var context: AccountContextImpl? { didSet { self.actionButtons.micButton.account = self.context?.account } @@ -469,7 +470,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { paragraphStyle.maximumLineHeight = 20.0 paragraphStyle.minimumLineHeight = 20.0 - textInputNode.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(max(17.0, baseFontSize)), NSAttributedStringKey.foregroundColor.rawValue: textColor, NSAttributedStringKey.paragraphStyle.rawValue: paragraphStyle] + textInputNode.typingAttributes = [NSAttributedString.Key.font.rawValue: Font.regular(max(17.0, baseFontSize)), NSAttributedString.Key.foregroundColor.rawValue: textColor, NSAttributedString.Key.paragraphStyle.rawValue: paragraphStyle] textInputNode.clipsToBounds = false textInputNode.textView.clipsToBounds = false textInputNode.delegate = self @@ -643,7 +644,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { textInputNode.attributedText = NSAttributedString(string: text, font: Font.regular(baseFontSize), textColor: textColor) textInputNode.selectedRange = range } - textInputNode.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(baseFontSize), NSAttributedStringKey.foregroundColor.rawValue: textColor] + textInputNode.typingAttributes = [NSAttributedString.Key.font.rawValue: Font.regular(baseFontSize), NSAttributedString.Key.foregroundColor.rawValue: textColor] } } @@ -1006,7 +1007,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { added = true mediaRecordingAccessibilityArea = AccessibilityAreaNode() mediaRecordingAccessibilityArea.accessibilityLabel = text - mediaRecordingAccessibilityArea.accessibilityTraits = UIAccessibilityTraitButton | UIAccessibilityTraitStartsMediaSession + mediaRecordingAccessibilityArea.accessibilityTraits = [.button, .startsMediaSession] self.mediaRecordingAccessibilityArea = mediaRecordingAccessibilityArea mediaRecordingAccessibilityArea.activate = { [weak self] in self?.interfaceInteraction?.finishMediaRecording(.send) @@ -1020,7 +1021,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { if added { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.4, execute: { [weak mediaRecordingAccessibilityArea] in - UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, mediaRecordingAccessibilityArea?.view) + UIAccessibility.post(notification: UIAccessibility.Notification.layoutChanged, argument: mediaRecordingAccessibilityArea?.view) }) } } else { diff --git a/submodules/TelegramUI/TelegramUI/ChatTextInputSlowmodePlaceholderNode.swift b/submodules/TelegramUI/TelegramUI/ChatTextInputSlowmodePlaceholderNode.swift index 9564b95c88..116aae2055 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTextInputSlowmodePlaceholderNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTextInputSlowmodePlaceholderNode.swift @@ -74,12 +74,12 @@ final class ChatTextInputSlowmodePlaceholderNode: ASDisplayNode { if timeout <= 30 { if self.iconArrowNode.layer.animation(forKey: "rotation") == nil { let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = 1.0 basicAnimation.fromValue = NSNumber(value: Float(0.0)) basicAnimation.toValue = NSNumber(value: Float(Double.pi * 2.0)) basicAnimation.repeatCount = Float.infinity - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) self.iconArrowNode.layer.add(basicAnimation, forKey: "rotation") } } else { diff --git a/submodules/TelegramUI/TelegramUI/ChatTextLinkEditController.swift b/submodules/TelegramUI/TelegramUI/ChatTextLinkEditController.swift index 9ac41cfba8..3a48fe08e3 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTextLinkEditController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTextLinkEditController.swift @@ -46,7 +46,7 @@ private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTex self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 33.0, color: theme.actionSheet.inputHollowBackgroundColor, strokeColor: theme.actionSheet.inputBorderColor, strokeWidth: 1.0) self.textInputNode = EditableTextNode() - self.textInputNode.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(17.0), NSAttributedStringKey.foregroundColor.rawValue: theme.actionSheet.inputTextColor] + self.textInputNode.typingAttributes = [NSAttributedString.Key.font.rawValue: Font.regular(17.0), NSAttributedString.Key.foregroundColor.rawValue: theme.actionSheet.inputTextColor] self.textInputNode.clipsToBounds = true self.textInputNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0) self.textInputNode.textContainerInset = UIEdgeInsets(top: self.inputInsets.top, left: 0.0, bottom: self.inputInsets.bottom, right: 0.0) @@ -380,7 +380,7 @@ private final class ChatTextLinkEditAlertContentNode: AlertContentNode { } } -func chatTextLinkEditController(sharedContext: SharedAccountContext, account: Account, text: String, link: String?, apply: @escaping (String?) -> Void) -> AlertController { +func chatTextLinkEditController(sharedContext: SharedAccountContextImpl, account: Account, text: String, link: String?, apply: @escaping (String?) -> Void) -> AlertController { let presentationData = sharedContext.currentPresentationData.with { $0 } var dismissImpl: ((Bool) -> Void)? diff --git a/submodules/TelegramUI/TelegramUI/ChatTitleActivityContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatTitleActivityContentNode.swift index acb9f05960..dd4a4b4275 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTitleActivityContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTitleActivityContentNode.swift @@ -13,7 +13,7 @@ class ChatTitleActivityIndicatorNode: ASDisplayNode { } var timingFunction: CAMediaTimingFunction { - return CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + return CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) } var color: UIColor? { diff --git a/submodules/TelegramUI/TelegramUI/ChatTitleView.swift b/submodules/TelegramUI/TelegramUI/ChatTitleView.swift index 8b4522bea0..217286e4c9 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTitleView.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTitleView.swift @@ -8,6 +8,7 @@ import SwiftSignalKit import LegacyComponents import TelegramPresentationData import TelegramUIPreferences +import ActivityIndicator enum ChatTitleContent { case peer(peerView: PeerView, onlineMemberCount: Int32?) @@ -466,7 +467,7 @@ final class ChatTitleView: UIView, NavigationBarTitleView { super.init(frame: CGRect()) self.isAccessibilityElement = true - self.accessibilityTraits = UIAccessibilityTraitHeader + self.accessibilityTraits = .header self.addSubnode(self.contentContainer) self.contentContainer.addSubnode(self.titleNode) diff --git a/submodules/TelegramUI/TelegramUI/ChatUnblockInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatUnblockInputPanelNode.swift index 4561f5b873..7bcc64806e 100644 --- a/submodules/TelegramUI/TelegramUI/ChatUnblockInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatUnblockInputPanelNode.swift @@ -45,7 +45,7 @@ final class ChatUnblockInputPanelNode: ChatInputPanelNode { self.strings = strings self.button = HighlightableButtonNode() - self.activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray) + self.activityIndicator = UIActivityIndicatorView(style: .gray) self.activityIndicator.isHidden = true super.init() diff --git a/submodules/TelegramUI/TelegramUI/ChatUnreadItem.swift b/submodules/TelegramUI/TelegramUI/ChatUnreadItem.swift index 25fd8fe719..b5006dd3d2 100644 --- a/submodules/TelegramUI/TelegramUI/ChatUnreadItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatUnreadItem.swift @@ -4,6 +4,7 @@ import Postbox import AsyncDisplayKit import Display import SwiftSignalKit +import TelegramPresentationData private let titleFont = UIFont.systemFont(ofSize: 13.0) diff --git a/submodules/TelegramUI/TelegramUI/ChatUploadingActivityContentNode.swift b/submodules/TelegramUI/TelegramUI/ChatUploadingActivityContentNode.swift index d35df14004..a5cebb8109 100644 --- a/submodules/TelegramUI/TelegramUI/ChatUploadingActivityContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatUploadingActivityContentNode.swift @@ -24,7 +24,7 @@ private class ChatUploadingActivityIndicatorNode: ChatTitleActivityIndicatorNode } override var timingFunction: CAMediaTimingFunction { - return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + return CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) } override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? { diff --git a/submodules/TelegramUI/TelegramUI/CheckDiskSpace.swift b/submodules/TelegramUI/TelegramUI/CheckDiskSpace.swift index a23663b3b4..3be22a3d3f 100644 --- a/submodules/TelegramUI/TelegramUI/CheckDiskSpace.swift +++ b/submodules/TelegramUI/TelegramUI/CheckDiskSpace.swift @@ -20,7 +20,7 @@ func freeDiskSpace() -> Int64 { } } -func checkAvailableDiskSpace(context: AccountContext, threshold: Int64 = 100 * 1024 * 1024, present: @escaping (ViewController, Any?) -> Void) -> Bool { +func checkAvailableDiskSpace(context: AccountContextImpl, threshold: Int64 = 100 * 1024 * 1024, present: @escaping (ViewController, Any?) -> Void) -> Bool { guard freeDiskSpace() < threshold else { return true } diff --git a/submodules/TelegramUI/TelegramUI/CommandChatInputContextPanelNode.swift b/submodules/TelegramUI/TelegramUI/CommandChatInputContextPanelNode.swift index 0509ef89ae..eae103c380 100644 --- a/submodules/TelegramUI/TelegramUI/CommandChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/CommandChatInputContextPanelNode.swift @@ -5,17 +5,10 @@ import Postbox import TelegramCore import Display import TelegramPresentationData +import MergeLists private struct CommandChatInputContextPanelEntryStableId: Hashable { let command: PeerCommand - - var hashValue: Int { - return command.command.text.hashValue ^ command.peer.id.hashValue - } - - static func ==(lhs: CommandChatInputContextPanelEntryStableId, rhs: CommandChatInputContextPanelEntryStableId) -> Bool { - return lhs.command == rhs.command - } } private struct CommandChatInputContextPanelEntry: Comparable, Identifiable { @@ -67,7 +60,7 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode { private var enqueuedTransitions: [(CommandChatInputContextPanelTransition, Bool)] = [] private var validLayout: (CGSize, CGFloat, CGFloat)? - override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + override init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.listView = ListView() self.listView.isOpaque = false self.listView.stackFromBottom = true diff --git a/submodules/TelegramUI/TelegramUI/ComposeController.swift b/submodules/TelegramUI/TelegramUI/ComposeController.swift index 2cde9da221..225bdf2a56 100644 --- a/submodules/TelegramUI/TelegramUI/ComposeController.swift +++ b/submodules/TelegramUI/TelegramUI/ComposeController.swift @@ -8,7 +8,7 @@ import TelegramCore import TelegramPresentationData public class ComposeController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private var contactsNode: ComposeControllerNode { return self.displayNode as! ComposeControllerNode @@ -28,7 +28,7 @@ public class ComposeController: ViewController { private var searchContentNode: NavigationBarSearchContentNode? - public init(context: AccountContext) { + public init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/ComposeControllerNode.swift b/submodules/TelegramUI/TelegramUI/ComposeControllerNode.swift index 8b2410f596..5a4473cb37 100644 --- a/submodules/TelegramUI/TelegramUI/ComposeControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ComposeControllerNode.swift @@ -9,7 +9,7 @@ import TelegramPresentationData final class ComposeControllerNode: ASDisplayNode { let contactListNode: ContactListNode - private let context: AccountContext + private let context: AccountContextImpl private var searchDisplayController: SearchDisplayController? private var containerLayout: (ContainerViewLayout, CGFloat)? @@ -26,7 +26,7 @@ final class ComposeControllerNode: ASDisplayNode { private var presentationData: PresentationData private var presentationDataDisposable: Disposable? - init(context: AccountContext) { + init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/ConfirmPhoneNumberController.swift b/submodules/TelegramUI/TelegramUI/ConfirmPhoneNumberController.swift index d77a774870..8a701e0dfd 100644 --- a/submodules/TelegramUI/TelegramUI/ConfirmPhoneNumberController.swift +++ b/submodules/TelegramUI/TelegramUI/ConfirmPhoneNumberController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private final class ConfirmPhoneNumberCodeControllerArguments { let updateEntryText: (String) -> Void @@ -156,7 +157,7 @@ protocol ConfirmPhoneNumberCodeController: class { private final class ConfirmPhoneNumberCodeControllerImpl: ItemListController, ConfirmPhoneNumberCodeController { private let applyCodeImpl: (Int) -> Void - init(context: AccountContext, state: Signal<(ItemListControllerState, (ItemListNodeState, ConfirmPhoneNumberCodeEntry.ItemGenerationArguments)), NoError>, applyCodeImpl: @escaping (Int) -> Void) { + init(context: AccountContextImpl, state: Signal<(ItemListControllerState, (ItemListNodeState, ConfirmPhoneNumberCodeEntry.ItemGenerationArguments)), NoError>, applyCodeImpl: @escaping (Int) -> Void) { self.applyCodeImpl = applyCodeImpl let presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -172,7 +173,7 @@ private final class ConfirmPhoneNumberCodeControllerImpl: ItemListController ViewController { +func confirmPhoneNumberCodeController(context: AccountContextImpl, phoneNumber: String, codeData: CancelAccountResetData) -> ViewController { let initialState = ConfirmPhoneNumberCodeControllerState(codeText: "", checking: false) let statePromise = ValuePromise(initialState, ignoreRepeated: true) diff --git a/submodules/TelegramUI/TelegramUI/ContactListNode.swift b/submodules/TelegramUI/TelegramUI/ContactListNode.swift index c485ad7dd6..35d0bf6e31 100644 --- a/submodules/TelegramUI/TelegramUI/ContactListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ContactListNode.swift @@ -8,6 +8,8 @@ import TelegramCore import TelegramPresentationData import TelegramUIPreferences import DeviceAccess +import MergeLists +import ItemListUI private let dropDownIcon = { () -> UIImage in UIGraphicsBeginImageContextWithOptions(CGSize(width: 12.0, height: 12.0), false, 0.0) @@ -762,7 +764,7 @@ enum ContactListFilter { } final class ContactListNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentation: ContactListPresentation? private let filters: [ContactListFilter] @@ -829,7 +831,7 @@ final class ContactListNode: ASDisplayNode { private var authorizationNode: PermissionContentNode private let displayPermissionPlaceholder: Bool - init(context: AccountContext, presentation: Signal, filters: [ContactListFilter] = [.excludeSelf], selectionState: ContactListNodeGroupSelectionState? = nil, displayPermissionPlaceholder: Bool = true, displaySortOptions: Bool = false) { + init(context: AccountContextImpl, presentation: Signal, filters: [ContactListFilter] = [.excludeSelf], selectionState: ContactListNodeGroupSelectionState? = nil, displayPermissionPlaceholder: Bool = true, displaySortOptions: Bool = false) { self.context = context self.filters = filters self.displayPermissionPlaceholder = displayPermissionPlaceholder diff --git a/submodules/TelegramUI/TelegramUI/ContactMultiselectionController.swift b/submodules/TelegramUI/TelegramUI/ContactMultiselectionController.swift index ef5c56a026..e375f6478c 100644 --- a/submodules/TelegramUI/TelegramUI/ContactMultiselectionController.swift +++ b/submodules/TelegramUI/TelegramUI/ContactMultiselectionController.swift @@ -6,6 +6,7 @@ import Postbox import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ProgressNavigationButtonNode enum ContactMultiselectionControllerMode { case groupCreation @@ -14,7 +15,7 @@ enum ContactMultiselectionControllerMode { } class ContactMultiselectionController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private let mode: ContactMultiselectionControllerMode private let titleView: CounterContollerTitleView @@ -64,7 +65,7 @@ class ContactMultiselectionController: ViewController { private let options: [ContactListAdditionalOption] private let filters: [ContactListFilter] - init(context: AccountContext, mode: ContactMultiselectionControllerMode, options: [ContactListAdditionalOption], filters: [ContactListFilter] = [.excludeSelf]) { + init(context: AccountContextImpl, mode: ContactMultiselectionControllerMode, options: [ContactListAdditionalOption], filters: [ContactListFilter] = [.excludeSelf]) { self.context = context self.mode = mode self.options = options diff --git a/submodules/TelegramUI/TelegramUI/ContactMultiselectionControllerNode.swift b/submodules/TelegramUI/TelegramUI/ContactMultiselectionControllerNode.swift index 29a4d1f781..f142a9c164 100644 --- a/submodules/TelegramUI/TelegramUI/ContactMultiselectionControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ContactMultiselectionControllerNode.swift @@ -5,6 +5,7 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import MergeLists private struct SearchResultEntry: Identifiable { let index: Int @@ -28,7 +29,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { let tokenListNode: EditableTokenListNode var searchResultsNode: ContactListNode? - private let context: AccountContext + private let context: AccountContextImpl private var containerLayout: (ContainerViewLayout, CGFloat, CGFloat)? @@ -45,7 +46,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { private var presentationData: PresentationData private var presentationDataDisposable: Disposable? - init(context: AccountContext, mode: ContactMultiselectionControllerMode, options: [ContactListAdditionalOption], filters: [ContactListFilter]) { + init(context: AccountContextImpl, mode: ContactMultiselectionControllerMode, options: [ContactListAdditionalOption], filters: [ContactListFilter]) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -191,7 +192,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { } func animateOut(completion: (() -> Void)?) { - self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, additive: true, completion: { [weak self] _ in + self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, completion: { [weak self] _ in if let strongSelf = self { strongSelf.dismiss?() completion?() diff --git a/submodules/TelegramUI/TelegramUI/ContactSelectionController.swift b/submodules/TelegramUI/TelegramUI/ContactSelectionController.swift index 5442e87ed6..9997e097c8 100644 --- a/submodules/TelegramUI/TelegramUI/ContactSelectionController.swift +++ b/submodules/TelegramUI/TelegramUI/ContactSelectionController.swift @@ -6,9 +6,10 @@ import Postbox import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ProgressNavigationButtonNode class ContactSelectionController: ViewController, PresentableController { - private let context: AccountContext + private let context: AccountContextImpl private let autoDismiss: Bool private var contactsNode: ContactSelectionControllerNode { @@ -63,7 +64,7 @@ class ContactSelectionController: ViewController, PresentableController { } } - init(context: AccountContext, autoDismiss: Bool = true, title: @escaping (PresentationStrings) -> String, options: [ContactListAdditionalOption] = [], displayDeviceContacts: Bool = false, confirmation: @escaping (ContactListPeer) -> Signal = { _ in .single(true) }) { + init(context: AccountContextImpl, autoDismiss: Bool = true, title: @escaping (PresentationStrings) -> String, options: [ContactListAdditionalOption] = [], displayDeviceContacts: Bool = false, confirmation: @escaping (ContactListPeer) -> Signal = { _ in .single(true) }) { self.context = context self.autoDismiss = autoDismiss self.titleProducer = title diff --git a/submodules/TelegramUI/TelegramUI/ContactSelectionControllerNode.swift b/submodules/TelegramUI/TelegramUI/ContactSelectionControllerNode.swift index 5729187d40..3e02fd1f02 100644 --- a/submodules/TelegramUI/TelegramUI/ContactSelectionControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ContactSelectionControllerNode.swift @@ -21,7 +21,7 @@ final class ContactSelectionControllerNode: ASDisplayNode { let contactListNode: ContactListNode private let dimNode: ASDisplayNode - private let context: AccountContext + private let context: AccountContextImpl private var searchDisplayController: SearchDisplayController? private var containerLayout: (ContainerViewLayout, CGFloat)? @@ -35,7 +35,7 @@ final class ContactSelectionControllerNode: ASDisplayNode { var presentationData: PresentationData var presentationDataDisposable: Disposable? - init(context: AccountContext, options: [ContactListAdditionalOption], displayDeviceContacts: Bool) { + init(context: AccountContextImpl, options: [ContactListAdditionalOption], displayDeviceContacts: Bool) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.displayDeviceContacts = displayDeviceContacts @@ -154,7 +154,7 @@ final class ContactSelectionControllerNode: ASDisplayNode { } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { [weak self] _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in if let strongSelf = self { strongSelf.dismiss?() } diff --git a/submodules/TelegramUI/TelegramUI/ContactsController.swift b/submodules/TelegramUI/TelegramUI/ContactsController.swift index a1c73398bd..b642a2e916 100644 --- a/submodules/TelegramUI/TelegramUI/ContactsController.swift +++ b/submodules/TelegramUI/TelegramUI/ContactsController.swift @@ -54,7 +54,7 @@ private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBa } public class ContactsController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private var contactsNode: ContactsControllerNode { return self.displayNode as! ContactsControllerNode @@ -83,7 +83,7 @@ public class ContactsController: ViewController { } } - public init(context: AccountContext) { + public init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/ContactsControllerNode.swift b/submodules/TelegramUI/TelegramUI/ContactsControllerNode.swift index 6dc6fdabac..44006d914f 100644 --- a/submodules/TelegramUI/TelegramUI/ContactsControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ContactsControllerNode.swift @@ -24,7 +24,7 @@ private final class ContactsControllerNodeView: UITracingLayerView, PreviewingHo final class ContactsControllerNode: ASDisplayNode { let contactListNode: ContactListNode - private let context: AccountContext + private let context: AccountContextImpl private(set) var searchDisplayController: SearchDisplayController? private var containerLayout: (ContainerViewLayout, CGFloat)? @@ -41,7 +41,7 @@ final class ContactsControllerNode: ASDisplayNode { weak var controller: ContactsController? - init(context: AccountContext, sortOrder: Signal, present: @escaping (ViewController, Any?) -> Void, controller: ContactsController) { + init(context: AccountContextImpl, sortOrder: Signal, present: @escaping (ViewController, Any?) -> Void, controller: ContactsController) { self.context = context self.controller = controller diff --git a/submodules/TelegramUI/TelegramUI/ContactsPeerItem.swift b/submodules/TelegramUI/TelegramUI/ContactsPeerItem.swift index 1ad45a7b7f..2935e9f173 100644 --- a/submodules/TelegramUI/TelegramUI/ContactsPeerItem.swift +++ b/submodules/TelegramUI/TelegramUI/ContactsPeerItem.swift @@ -7,6 +7,8 @@ import SwiftSignalKit import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI +import CheckNode private let titleFont = Font.regular(17.0) private let titleBoldFont = Font.medium(17.0) diff --git a/submodules/TelegramUI/TelegramUI/ContactsSearchContainerNode.swift b/submodules/TelegramUI/TelegramUI/ContactsSearchContainerNode.swift index 4845605b3c..ba54a53c16 100644 --- a/submodules/TelegramUI/TelegramUI/ContactsSearchContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ContactsSearchContainerNode.swift @@ -7,6 +7,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import MergeLists private enum ContactListSearchGroup { case contacts @@ -126,7 +127,7 @@ struct ContactsSearchCategories: OptionSet { } final class ContactsSearchContainerNode: SearchDisplayControllerContentNode { - private let context: AccountContext + private let context: AccountContextImpl private let openPeer: (ContactListPeer) -> Void private let dimNode: ASDisplayNode @@ -141,7 +142,7 @@ final class ContactsSearchContainerNode: SearchDisplayControllerContentNode { private var containerViewLayout: (ContainerViewLayout, CGFloat)? private var enqueuedTransitions: [ContactListSearchContainerTransition] = [] - init(context: AccountContext, onlyWriteable: Bool, categories: ContactsSearchCategories, filters: [ContactListFilter] = [.excludeSelf], openPeer: @escaping (ContactListPeer) -> Void) { + init(context: AccountContextImpl, onlyWriteable: Bool, categories: ContactsSearchCategories, filters: [ContactListFilter] = [.excludeSelf], openPeer: @escaping (ContactListPeer) -> Void) { self.context = context self.openPeer = openPeer diff --git a/submodules/TelegramUI/TelegramUI/ConvertToSupergroupController.swift b/submodules/TelegramUI/TelegramUI/ConvertToSupergroupController.swift index 4abeca8742..498beb2401 100644 --- a/submodules/TelegramUI/TelegramUI/ConvertToSupergroupController.swift +++ b/submodules/TelegramUI/TelegramUI/ConvertToSupergroupController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private final class ConvertToSupergroupArguments { let convert: () -> Void @@ -114,7 +115,7 @@ private func convertToSupergroupEntries(presentationData: PresentationData) -> [ return entries } -public func convertToSupergroupController(context: AccountContext, peerId: PeerId) -> ViewController { +public func convertToSupergroupController(context: AccountContextImpl, peerId: PeerId) -> ViewController { var replaceControllerImpl: ((ViewController) -> Void)? var presentControllerImpl: ((ViewController, Any?) -> Void)? diff --git a/submodules/TelegramUI/TelegramUI/CounterContollerTitleView.swift b/submodules/TelegramUI/TelegramUI/CounterContollerTitleView.swift index c87181729a..916d2066f6 100644 --- a/submodules/TelegramUI/TelegramUI/CounterContollerTitleView.swift +++ b/submodules/TelegramUI/TelegramUI/CounterContollerTitleView.swift @@ -46,7 +46,7 @@ final class CounterContollerTitleView: UIView { super.init(frame: CGRect()) self.isAccessibilityElement = true - self.accessibilityTraits = UIAccessibilityTraitHeader + self.accessibilityTraits = .header self.addSubnode(self.titleNode) self.addSubnode(self.subtitleNode) diff --git a/submodules/TelegramUI/TelegramUI/CreateChannelController.swift b/submodules/TelegramUI/TelegramUI/CreateChannelController.swift index 3d79003f1f..b9d30c7d19 100644 --- a/submodules/TelegramUI/TelegramUI/CreateChannelController.swift +++ b/submodules/TelegramUI/TelegramUI/CreateChannelController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import LegacyComponents +import ItemListUI private struct CreateChannelArguments { let account: Account @@ -186,7 +187,7 @@ private func CreateChannelEntries(presentationData: PresentationData, state: Cre return entries } -public func createChannelController(context: AccountContext) -> ViewController { +public func createChannelController(context: AccountContextImpl) -> ViewController { let initialState = CreateChannelState(creating: false, editingName: ItemListAvatarAndNameInfoItemName.title(title: "", type: .channel), editingDescriptionText: "", avatar: nil) let statePromise = ValuePromise(initialState, ignoreRepeated: true) let stateValue = Atomic(value: initialState) @@ -300,7 +301,7 @@ public func createChannelController(context: AccountContext) -> ViewController { presentControllerImpl?(legacyController, nil) let completedImpl: (UIImage) -> Void = { image in - if let data = UIImageJPEGRepresentation(image, 0.6) { + if let data = image.jpegData(compressionQuality: 0.6) { let resource = LocalFileMediaResource(fileId: arc4random64()) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) let representation = TelegramMediaImageRepresentation(dimensions: CGSize(width: 640.0, height: 640.0), resource: resource) diff --git a/submodules/TelegramUI/TelegramUI/CreateGroupController.swift b/submodules/TelegramUI/TelegramUI/CreateGroupController.swift index 0076fd36cd..04db31d318 100644 --- a/submodules/TelegramUI/TelegramUI/CreateGroupController.swift +++ b/submodules/TelegramUI/TelegramUI/CreateGroupController.swift @@ -7,6 +7,7 @@ import TelegramCore import TelegramPresentationData import TelegramUIPreferences import LegacyComponents +import ItemListUI public enum CreateGroupMode { case generic @@ -287,7 +288,7 @@ private func createGroupEntries(presentationData: PresentationData, state: Creat return entries } -public func createGroupController(context: AccountContext, peerIds: [PeerId], initialTitle: String? = nil, mode: CreateGroupMode = .generic, completion: ((PeerId, @escaping () -> Void) -> Void)? = nil) -> ViewController { +public func createGroupController(context: AccountContextImpl, peerIds: [PeerId], initialTitle: String? = nil, mode: CreateGroupMode = .generic, completion: ((PeerId, @escaping () -> Void) -> Void)? = nil) -> ViewController { var location: PeerGeoLocation? if case let .locatedGroup(latitude, longitude, address) = mode { location = PeerGeoLocation(latitude: latitude, longitude: longitude, address: address ?? "") @@ -492,7 +493,7 @@ public func createGroupController(context: AccountContext, peerIds: [PeerId], in presentControllerImpl?(legacyController, nil) let completedImpl: (UIImage) -> Void = { image in - if let data = UIImageJPEGRepresentation(image, 0.6) { + if let data = image.jpegData(compressionQuality: 0.6) { let resource = LocalFileMediaResource(fileId: arc4random64()) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) let representation = TelegramMediaImageRepresentation(dimensions: CGSize(width: 640.0, height: 640.0), resource: resource) diff --git a/submodules/TelegramUI/TelegramUI/CreatePasswordController.swift b/submodules/TelegramUI/TelegramUI/CreatePasswordController.swift index 7c79181c65..6f8a72aa97 100644 --- a/submodules/TelegramUI/TelegramUI/CreatePasswordController.swift +++ b/submodules/TelegramUI/TelegramUI/CreatePasswordController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private enum CreatePasswordField { case password @@ -220,7 +221,7 @@ enum CreatePasswordState: Equatable { case pendingVerification(emailPattern: String) } -func createPasswordController(context: AccountContext, createPasswordContext: CreatePasswordContext, state: CreatePasswordState, completion: @escaping (String, String, Bool) -> Void, updatePasswordEmailConfirmation: @escaping ((String, String)?) -> Void, processPasswordEmailConfirmation: Bool = true) -> ViewController { +func createPasswordController(context: AccountContextImpl, createPasswordContext: CreatePasswordContext, state: CreatePasswordState, completion: @escaping (String, String, Bool) -> Void, updatePasswordEmailConfirmation: @escaping ((String, String)?) -> Void, processPasswordEmailConfirmation: Bool = true) -> ViewController { let statePromise = ValuePromise(CreatePasswordControllerState(state: state), ignoreRepeated: true) let stateValue = Atomic(value: CreatePasswordControllerState(state: state)) let updateState: ((CreatePasswordControllerState) -> CreatePasswordControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/CreatePollController.swift b/submodules/TelegramUI/TelegramUI/CreatePollController.swift index 40ee40e5ea..cdc64c9034 100644 --- a/submodules/TelegramUI/TelegramUI/CreatePollController.swift +++ b/submodules/TelegramUI/TelegramUI/CreatePollController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private let maxTextLength = 255 private let maxOptionLength = 100 @@ -194,7 +195,7 @@ private func createPollControllerEntries(presentationData: PresentationData, sta return entries } -public func createPollController(context: AccountContext, peerId: PeerId, completion: @escaping (EnqueueMessage) -> Void) -> ViewController { +public func createPollController(context: AccountContextImpl, peerId: PeerId, completion: @escaping (EnqueueMessage) -> Void) -> ViewController { let statePromise = ValuePromise(CreatePollControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: CreatePollControllerState()) let updateState: ((CreatePollControllerState) -> CreatePollControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/CreatePollOptionActionItem.swift b/submodules/TelegramUI/TelegramUI/CreatePollOptionActionItem.swift index 81b582ce08..2d007dba66 100644 --- a/submodules/TelegramUI/TelegramUI/CreatePollOptionActionItem.swift +++ b/submodules/TelegramUI/TelegramUI/CreatePollOptionActionItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI class CreatePollOptionActionItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/CreatePollOptionItem.swift b/submodules/TelegramUI/TelegramUI/CreatePollOptionItem.swift index 72711de6e5..c9ebc5f006 100644 --- a/submodules/TelegramUI/TelegramUI/CreatePollOptionItem.swift +++ b/submodules/TelegramUI/TelegramUI/CreatePollOptionItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI struct CreatePollOptionItemEditing { let editable: Bool @@ -150,7 +151,7 @@ class CreatePollOptionItemNode: ItemListRevealOptionsItemNode, ItemListItemNode, if let item = self.item { textColor = item.theme.list.itemPrimaryTextColor } - self.textNode.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(17.0), NSAttributedStringKey.foregroundColor.rawValue: textColor] + self.textNode.typingAttributes = [NSAttributedString.Key.font.rawValue: Font.regular(17.0), NSAttributedString.Key.foregroundColor.rawValue: textColor] self.textNode.clipsToBounds = true self.textNode.delegate = self self.textNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0) @@ -273,7 +274,7 @@ class CreatePollOptionItemNode: ItemListRevealOptionsItemNode, ItemListItemNode, strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor if strongSelf.isNodeLoaded { - strongSelf.textNode.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(17.0), NSAttributedStringKey.foregroundColor.rawValue: item.theme.list.itemPrimaryTextColor] + strongSelf.textNode.typingAttributes = [NSAttributedString.Key.font.rawValue: Font.regular(17.0), NSAttributedString.Key.foregroundColor.rawValue: item.theme.list.itemPrimaryTextColor] } } diff --git a/submodules/TelegramUI/TelegramUI/CustomWallpaperPicker.swift b/submodules/TelegramUI/TelegramUI/CustomWallpaperPicker.swift index f4ae858259..51893e342e 100644 --- a/submodules/TelegramUI/TelegramUI/CustomWallpaperPicker.swift +++ b/submodules/TelegramUI/TelegramUI/CustomWallpaperPicker.swift @@ -7,7 +7,7 @@ import TelegramCore import LegacyComponents import TelegramUIPreferences -func presentCustomWallpaperPicker(context: AccountContext, present: @escaping (ViewController) -> Void) { +func presentCustomWallpaperPicker(context: AccountContextImpl, present: @escaping (ViewController) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let _ = legacyWallpaperPicker(context: context, presentationData: presentationData).start(next: { generator in let legacyController = LegacyController(presentation: .modal(animateIn: true), theme: presentationData.theme) @@ -41,7 +41,7 @@ func presentCustomWallpaperPicker(context: AccountContext, present: @escaping (V }) } -func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryEntry, mode: WallpaperPresentationOptions, cropRect: CGRect?, completion: @escaping () -> Void) { +func uploadCustomWallpaper(context: AccountContextImpl, wallpaper: WallpaperGalleryEntry, mode: WallpaperPresentationOptions, cropRect: CGRect?, completion: @escaping () -> Void) { let imageSignal: Signal switch wallpaper { case let .wallpaper(wallpaper, _): @@ -123,7 +123,7 @@ func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryE let thumbnailDimensions = finalCropRect.size.fitted(CGSize(width: 320.0, height: 320.0)) let thumbnailImage = generateScaledImage(image: croppedImage, size: thumbnailDimensions, scale: 1.0) - if let data = UIImageJPEGRepresentation(croppedImage, 0.8), let thumbnailImage = thumbnailImage, let thumbnailData = UIImageJPEGRepresentation(thumbnailImage, 0.4) { + if let data = croppedImage.jpegData(compressionQuality: 0.8), let thumbnailImage = thumbnailImage, let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { let thumbnailResource = LocalFileMediaResource(fileId: arc4random64()) context.sharedContext.accountManager.mediaBox.storeResourceData(thumbnailResource.id, data: thumbnailData) context.account.postbox.mediaBox.storeResourceData(thumbnailResource.id, data: thumbnailData) diff --git a/submodules/TelegramUI/TelegramUI/DataAndStorageSettingsController.swift b/submodules/TelegramUI/TelegramUI/DataAndStorageSettingsController.swift index e671154668..3b83bb0b67 100644 --- a/submodules/TelegramUI/TelegramUI/DataAndStorageSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/DataAndStorageSettingsController.swift @@ -7,6 +7,7 @@ import TelegramCore import LegacyComponents import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class DataAndStorageControllerArguments { let openStorageUsage: () -> Void @@ -454,7 +455,7 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat return entries } -func dataAndStorageController(context: AccountContext, focusOnItemTag: DataAndStorageEntryTag? = nil) -> ViewController { +func dataAndStorageController(context: AccountContextImpl, focusOnItemTag: DataAndStorageEntryTag? = nil) -> ViewController { let initialState = DataAndStorageControllerState() let statePromise = ValuePromise(initialState, ignoreRepeated: true) diff --git a/submodules/TelegramUI/TelegramUI/DataPrivacySettingsController.swift b/submodules/TelegramUI/TelegramUI/DataPrivacySettingsController.swift index 262f84e013..bce29af8f5 100644 --- a/submodules/TelegramUI/TelegramUI/DataPrivacySettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/DataPrivacySettingsController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class DataPrivacyControllerArguments { let account: Account @@ -278,7 +279,7 @@ private func dataPrivacyControllerEntries(presentationData: PresentationData, st return entries } -public func dataPrivacyController(context: AccountContext) -> ViewController { +public func dataPrivacyController(context: AccountContextImpl) -> ViewController { let statePromise = ValuePromise(DataPrivacyControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: DataPrivacyControllerState()) let updateState: ((DataPrivacyControllerState) -> DataPrivacyControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/DateSelectionActionSheetController.swift b/submodules/TelegramUI/TelegramUI/DateSelectionActionSheetController.swift index bf3ac5818a..5315435abb 100644 --- a/submodules/TelegramUI/TelegramUI/DateSelectionActionSheetController.swift +++ b/submodules/TelegramUI/TelegramUI/DateSelectionActionSheetController.swift @@ -16,7 +16,7 @@ final class DateSelectionActionSheetController: ActionSheetController { return self._ready } - init(context: AccountContext, title: String?, currentValue: Int32, minimumDate: Date? = nil, maximumDate: Date? = nil, emptyTitle: String? = nil, applyValue: @escaping (Int32?) -> Void) { + init(context: AccountContextImpl, title: String?, currentValue: Int32, minimumDate: Date? = nil, maximumDate: Date? = nil, emptyTitle: String? = nil, applyValue: @escaping (Int32?) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/DebugAccountsController.swift b/submodules/TelegramUI/TelegramUI/DebugAccountsController.swift index 47627f2b23..3ed886ce2f 100644 --- a/submodules/TelegramUI/TelegramUI/DebugAccountsController.swift +++ b/submodules/TelegramUI/TelegramUI/DebugAccountsController.swift @@ -5,15 +5,16 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private final class DebugAccountsControllerArguments { - let context: AccountContext + let context: AccountContextImpl let presentController: (ViewController, ViewControllerPresentationArguments) -> Void let switchAccount: (AccountRecordId) -> Void let loginNewAccount: () -> Void - init(context: AccountContext, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, switchAccount: @escaping (AccountRecordId) -> Void, loginNewAccount: @escaping () -> Void) { + init(context: AccountContextImpl, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, switchAccount: @escaping (AccountRecordId) -> Void, loginNewAccount: @escaping () -> Void) { self.context = context self.presentController = presentController self.switchAccount = switchAccount @@ -97,7 +98,7 @@ private func debugAccountsControllerEntries(view: AccountRecordsView, presentati return entries } -public func debugAccountsController(context: AccountContext, accountManager: AccountManager) -> ViewController { +public func debugAccountsController(context: AccountContextImpl, accountManager: AccountManager) -> ViewController { var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)? let arguments = DebugAccountsControllerArguments(context: context, presentController: { controller, arguments in diff --git a/submodules/TelegramUI/TelegramUI/DebugController.swift b/submodules/TelegramUI/TelegramUI/DebugController.swift index 11bed23910..f8e70606df 100644 --- a/submodules/TelegramUI/TelegramUI/DebugController.swift +++ b/submodules/TelegramUI/TelegramUI/DebugController.swift @@ -12,15 +12,16 @@ import MtProtoKitDynamic import MessageUI import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class DebugControllerArguments { - let sharedContext: SharedAccountContext - let context: AccountContext? + let sharedContext: SharedAccountContextImpl + let context: AccountContextImpl? let presentController: (ViewController, ViewControllerPresentationArguments?) -> Void let pushController: (ViewController) -> Void let getRootController: () -> UIViewController? - init(sharedContext: SharedAccountContext, context: AccountContext?, presentController: @escaping (ViewController, ViewControllerPresentationArguments?) -> Void, pushController: @escaping (ViewController) -> Void, getRootController: @escaping () -> UIViewController?) { + init(sharedContext: SharedAccountContextImpl, context: AccountContextImpl?, presentController: @escaping (ViewController, ViewControllerPresentationArguments?) -> Void, pushController: @escaping (ViewController) -> Void, getRootController: @escaping () -> UIViewController?) { self.sharedContext = sharedContext self.context = context self.presentController = presentController @@ -542,7 +543,7 @@ private func debugControllerEntries(presentationData: PresentationData, loggingS return entries } -public func debugController(sharedContext: SharedAccountContext, context: AccountContext?, modal: Bool = false) -> ViewController { +public func debugController(sharedContext: SharedAccountContextImpl, context: AccountContextImpl?, modal: Bool = false) -> ViewController { var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)? var pushControllerImpl: ((ViewController) -> Void)? var dismissImpl: (() -> Void)? diff --git a/submodules/TelegramUI/TelegramUI/DeleteChatPeerActionSheetItem.swift b/submodules/TelegramUI/TelegramUI/DeleteChatPeerActionSheetItem.swift index 7b5c5b03c7..0058c223d2 100644 --- a/submodules/TelegramUI/TelegramUI/DeleteChatPeerActionSheetItem.swift +++ b/submodules/TelegramUI/TelegramUI/DeleteChatPeerActionSheetItem.swift @@ -11,13 +11,13 @@ enum DeleteChatPeerAction { } final class DeleteChatPeerActionSheetItem: ActionSheetItem { - let context: AccountContext + let context: AccountContextImpl let peer: Peer let chatPeer: Peer let action: DeleteChatPeerAction let strings: PresentationStrings - init(context: AccountContext, peer: Peer, chatPeer: Peer, action: DeleteChatPeerAction, strings: PresentationStrings) { + init(context: AccountContextImpl, peer: Peer, chatPeer: Peer, action: DeleteChatPeerAction, strings: PresentationStrings) { self.context = context self.peer = peer self.chatPeer = chatPeer @@ -42,7 +42,7 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode { private let avatarNode: AvatarNode private let textNode: ImmediateTextNode - init(theme: ActionSheetControllerTheme, strings: PresentationStrings, context: AccountContext, peer: Peer, chatPeer: Peer, action: DeleteChatPeerAction) { + init(theme: ActionSheetControllerTheme, strings: PresentationStrings, context: AccountContextImpl, peer: Peer, chatPeer: Peer, action: DeleteChatPeerAction) { self.theme = theme self.strings = strings diff --git a/submodules/TelegramUI/TelegramUI/DeviceContactInfoController.swift b/submodules/TelegramUI/TelegramUI/DeviceContactInfoController.swift index 6c536c036d..26e7b5c0fb 100644 --- a/submodules/TelegramUI/TelegramUI/DeviceContactInfoController.swift +++ b/submodules/TelegramUI/TelegramUI/DeviceContactInfoController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import MessageUI import TelegramPresentationData +import ItemListUI private enum DeviceContactInfoAction { case sendMessage @@ -797,7 +798,7 @@ private final class DeviceContactInfoController: ItemListController Void)? = nil, cancelled: (() -> Void)? = nil) -> ViewController { +public func deviceContactInfoController(context: AccountContextImpl, subject: DeviceContactInfoSubject, completed: (() -> Void)? = nil, cancelled: (() -> Void)? = nil) -> ViewController { var initialState = DeviceContactInfoState() if case let .create(peer, contactData, _, _, _) = subject { var peerPhoneNumber: String? @@ -1310,7 +1311,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device return controller } -private func addContactToExisting(context: AccountContext, parentController: ViewController, contactData: DeviceContactExtendedData, completion: @escaping (Peer?, DeviceContactStableId, DeviceContactExtendedData) -> Void) { +private func addContactToExisting(context: AccountContextImpl, parentController: ViewController, contactData: DeviceContactExtendedData, completion: @escaping (Peer?, DeviceContactStableId, DeviceContactExtendedData) -> Void) { let contactsController = ContactSelectionController(context: context, title: { $0.Contacts_Title }, displayDeviceContacts: true) parentController.present(contactsController, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) let _ = (contactsController.result @@ -1379,7 +1380,7 @@ private func addContactToExisting(context: AccountContext, parentController: Vie }) } -func addContactOptionsController(context: AccountContext, peer: Peer?, contactData: DeviceContactExtendedData) -> ActionSheetController { +func addContactOptionsController(context: AccountContextImpl, peer: Peer?, contactData: DeviceContactExtendedData) -> ActionSheetController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let controller = ActionSheetController(presentationTheme: presentationData.theme) let dismissAction: () -> Void = { [weak controller] in diff --git a/submodules/TelegramUI/TelegramUI/DisabledContextResultsChatInputContextPanelNode.swift b/submodules/TelegramUI/TelegramUI/DisabledContextResultsChatInputContextPanelNode.swift index e17ad63bf8..98b232b193 100644 --- a/submodules/TelegramUI/TelegramUI/DisabledContextResultsChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/DisabledContextResultsChatInputContextPanelNode.swift @@ -12,7 +12,7 @@ final class DisabledContextResultsChatInputContextPanelNode: ChatInputContextPan private var validLayout: (CGSize, CGFloat, CGFloat)? - override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + override init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.containerNode = ASDisplayNode() self.separatorNode = ASDisplayNode() self.textNode = ImmediateTextNode() diff --git a/submodules/TelegramUI/TelegramUI/DocumentPreviewController.swift b/submodules/TelegramUI/TelegramUI/DocumentPreviewController.swift index 3d811c105a..b35497d69f 100644 --- a/submodules/TelegramUI/TelegramUI/DocumentPreviewController.swift +++ b/submodules/TelegramUI/TelegramUI/DocumentPreviewController.swift @@ -47,7 +47,7 @@ final class DocumentPreviewController: UINavigationController, QLPreviewControll context.fill(CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: UIScreenPixel))) }) self.navigationBar.isTranslucent = false - self.navigationBar.titleTextAttributes = [NSAttributedStringKey.font: Font.semibold(17.0), NSAttributedStringKey.foregroundColor: theme.rootController.navigationBar.primaryTextColor] + self.navigationBar.titleTextAttributes = [NSAttributedString.Key.font: Font.semibold(17.0), NSAttributedString.Key.foregroundColor: theme.rootController.navigationBar.primaryTextColor] let controller = QLPreviewController(nibName: nil, bundle: nil) controller.navigation_setDismiss({ [weak self] in @@ -134,7 +134,7 @@ final class CompactDocumentPreviewController: QLPreviewController, QLPreviewCont context.fill(CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: UIScreenPixel))) }) self.navigationBar.isTranslucent = false - self.navigationBar.titleTextAttributes = [NSAttributedStringKey.font: Font.semibold(17.0), NSAttributedStringKey.foregroundColor: theme.rootController.navigationBar.primaryTextColor] + self.navigationBar.titleTextAttributes = [NSAttributedString.Key.font: Font.semibold(17.0), NSAttributedString.Key.foregroundColor: theme.rootController.navigationBar.primaryTextColor] controller.navigationItem.setLeftBarButton(UIBarButtonItem(title: strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false) self.setViewControllers([controller], animated: false)*/ @@ -212,7 +212,7 @@ func presentDocumentPreviewController(rootController: UIViewController, theme: P context.setFillColor(theme.rootController.navigationBar.separatorColor.cgColor) context.fill(CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: UIScreenPixel))) }) - navigationBar.titleTextAttributes = [NSAttributedStringKey.font: Font.semibold(17.0), NSAttributedStringKey.foregroundColor: theme.rootController.navigationBar.primaryTextColor] + navigationBar.titleTextAttributes = [NSAttributedString.Key.font: Font.semibold(17.0), NSAttributedString.Key.foregroundColor: theme.rootController.navigationBar.primaryTextColor] } rootController.present(CompactDocumentPreviewController(theme: theme, strings: strings, postbox: postbox, file: file), animated: true, completion: nil) diff --git a/submodules/TelegramUI/TelegramUI/EditAccessoryPanelNode.swift b/submodules/TelegramUI/TelegramUI/EditAccessoryPanelNode.swift index 3efe488a5f..cb4a8c913a 100644 --- a/submodules/TelegramUI/TelegramUI/EditAccessoryPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/EditAccessoryPanelNode.swift @@ -7,6 +7,7 @@ import SwiftSignalKit import Display import TelegramPresentationData import TelegramUIPreferences +import ActivityIndicator final class EditAccessoryPanelNode: AccessoryPanelNode { let messageId: MessageId @@ -53,12 +54,12 @@ final class EditAccessoryPanelNode: AccessoryPanelNode { } } - private let context: AccountContext + private let context: AccountContextImpl var theme: PresentationTheme var strings: PresentationStrings var nameDisplayOrder: PresentationPersonNameOrder - init(context: AccountContext, messageId: MessageId, theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder) { + init(context: AccountContextImpl, messageId: MessageId, theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder) { self.context = context self.messageId = messageId self.theme = theme @@ -68,7 +69,7 @@ final class EditAccessoryPanelNode: AccessoryPanelNode { self.closeButton = ASButtonNode() self.closeButton.accessibilityLabel = "Discard" self.closeButton.setImage(PresentationResourcesChat.chatInputPanelCloseIconImage(theme), for: []) - self.closeButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0) + self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0) self.closeButton.displaysAsynchronously = false self.lineNode = ASImageNode() diff --git a/submodules/TelegramUI/TelegramUI/EditSettingsController.swift b/submodules/TelegramUI/TelegramUI/EditSettingsController.swift index a2da800fce..5e3c4f3e08 100644 --- a/submodules/TelegramUI/TelegramUI/EditSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/EditSettingsController.swift @@ -7,9 +7,10 @@ import Postbox import TelegramCore import LegacyComponents import TelegramPresentationData +import ItemListUI private struct EditSettingsItemArguments { - let context: AccountContext + let context: AccountContextImpl let accountManager: AccountManager let avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext @@ -35,7 +36,7 @@ private enum SettingsSection: Int32 { public enum EditSettingsEntryTag: ItemListItemTag { case bio - func isEqual(to other: ItemListItemTag) -> Bool { + public func isEqual(to other: ItemListItemTag) -> Bool { if let other = other as? EditSettingsEntryTag, self == other { return true } else { @@ -297,7 +298,7 @@ private func editSettingsEntries(presentationData: PresentationData, state: Edit return entries } -func editSettingsController(context: AccountContext, currentName: ItemListAvatarAndNameInfoItemName, currentBioText: String, accountManager: AccountManager, canAddAccounts: Bool, focusOnItemTag: EditSettingsEntryTag? = nil) -> ViewController { +func editSettingsController(context: AccountContextImpl, currentName: ItemListAvatarAndNameInfoItemName, currentBioText: String, accountManager: AccountManager, canAddAccounts: Bool, focusOnItemTag: EditSettingsEntryTag? = nil) -> ViewController { let initialState = EditSettingsState(editingName: currentName, editingBioText: currentBioText) let statePromise = ValuePromise(initialState, ignoreRepeated: true) let stateValue = Atomic(value: initialState) @@ -495,7 +496,7 @@ func editSettingsController(context: AccountContext, currentName: ItemListAvatar } let completedImpl: (UIImage) -> Void = { image in - if let data = UIImageJPEGRepresentation(image, 0.6) { + if let data = image.jpegData(compressionQuality: 0.6) { let resource = LocalFileMediaResource(fileId: arc4random64()) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) let representation = TelegramMediaImageRepresentation(dimensions: CGSize(width: 640.0, height: 640.0), resource: resource) diff --git a/submodules/TelegramUI/TelegramUI/EditableTokenListNode.swift b/submodules/TelegramUI/TelegramUI/EditableTokenListNode.swift index 9d0317019e..7fbd691ab8 100644 --- a/submodules/TelegramUI/TelegramUI/EditableTokenListNode.swift +++ b/submodules/TelegramUI/TelegramUI/EditableTokenListNode.swift @@ -241,7 +241,7 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { let targetEndPosition = CGPoint(x: tokenFrame.midX, y: tokenFrame.midY) tokenNode.frame = tokenFrame - let initialAnimation = tokenNode.layer.makeAnimation(from: NSValue(cgPoint: initialStartPosition), to: NSValue(cgPoint: initialEndPosition), keyPath: "position", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.12, mediaTimingFunction: nil, removeOnCompletion: true, additive: false, completion: nil) + let initialAnimation = tokenNode.layer.makeAnimation(from: NSValue(cgPoint: initialStartPosition), to: NSValue(cgPoint: initialEndPosition), keyPath: "position", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.12, mediaTimingFunction: nil, removeOnCompletion: true, additive: false, completion: nil) let targetAnimation = tokenNode.layer.makeAnimation(from: NSValue(cgPoint: targetStartPosition), to: NSValue(cgPoint: targetEndPosition), keyPath: "position", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.2 + animationDelay, mediaTimingFunction: nil, removeOnCompletion: true, additive: false, completion: nil) tokenNode.layer.animateGroup([initialAnimation, targetAnimation], key: "slide") animationDelay += 0.025 diff --git a/submodules/TelegramUI/TelegramUI/EmojiResources.swift b/submodules/TelegramUI/TelegramUI/EmojiResources.swift index fe625d7d09..6983e6aa7a 100644 --- a/submodules/TelegramUI/TelegramUI/EmojiResources.swift +++ b/submodules/TelegramUI/TelegramUI/EmojiResources.swift @@ -350,7 +350,7 @@ func fetchEmojiSpriteResource(postbox: Postbox, network: Network, resource: Emoj let image = buffer.with { buffer -> UIImage? in return WebP.convert(fromWebP: buffer.data) } - if let image = image, let data = UIImagePNGRepresentation(image) { + if let image = image, let data = image.pngData() { subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< data.count, complete: true)) subscriber.putCompletion() } diff --git a/submodules/TelegramUI/TelegramUI/EmojisChatInputContextPanelNode.swift b/submodules/TelegramUI/TelegramUI/EmojisChatInputContextPanelNode.swift index bb17fdeeb9..2d0a9eb872 100644 --- a/submodules/TelegramUI/TelegramUI/EmojisChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/EmojisChatInputContextPanelNode.swift @@ -5,6 +5,7 @@ import Postbox import TelegramCore import Display import TelegramPresentationData +import MergeLists private struct EmojisChatInputContextPanelEntryStableId: Hashable, Equatable { let symbol: String @@ -100,7 +101,7 @@ final class EmojisChatInputContextPanelNode: ChatInputContextPanelNode { private var enqueuedTransitions: [(EmojisChatInputContextPanelTransition, Bool)] = [] private var validLayout: (CGSize, CGFloat, CGFloat)? - override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + override init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.backgroundNode = ASImageNode() self.backgroundNode.displayWithoutProcessing = true self.backgroundNode.displaysAsynchronously = false diff --git a/submodules/TelegramUI/TelegramUI/FeaturedStickerPacksController.swift b/submodules/TelegramUI/TelegramUI/FeaturedStickerPacksController.swift index 207189c093..55ec3b8dde 100644 --- a/submodules/TelegramUI/TelegramUI/FeaturedStickerPacksController.swift +++ b/submodules/TelegramUI/TelegramUI/FeaturedStickerPacksController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class FeaturedStickerPacksControllerArguments { let account: Account @@ -158,7 +159,7 @@ private func featuredStickerPacksControllerEntries(presentationData: Presentatio return entries } -public func featuredStickerPacksController(context: AccountContext) -> ViewController { +public func featuredStickerPacksController(context: AccountContextImpl) -> ViewController { let statePromise = ValuePromise(FeaturedStickerPacksControllerState(), ignoreRepeated: true) var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)? diff --git a/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift b/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift index ffafc8e884..e7c29f278e 100644 --- a/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift +++ b/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift @@ -722,7 +722,7 @@ private func fetchEmojiThumbnailRepresentation(account: Account, resource: Media let nsString = (resource.emoji as NSString) let font = Font.regular(52.0) - let stringAttributes = [NSAttributedStringKey.font: font] + let stringAttributes = [NSAttributedString.Key.font: font] var textSize = nsString.size(withAttributes: stringAttributes) textSize = CGSize(width: ceil(textSize.width) + 1.0, height: ceil(textSize.height) + 1.0) diff --git a/submodules/TelegramUI/TelegramUI/FetchMediaUtils.swift b/submodules/TelegramUI/TelegramUI/FetchMediaUtils.swift index 25c0df6115..9da9890068 100644 --- a/submodules/TelegramUI/TelegramUI/FetchMediaUtils.swift +++ b/submodules/TelegramUI/TelegramUI/FetchMediaUtils.swift @@ -27,7 +27,7 @@ private func fetchCategoryForFile(_ file: TelegramMediaFile) -> FetchManagerCate } } -public func messageMediaFileInteractiveFetched(context: AccountContext, message: Message, file: TelegramMediaFile, userInitiated: Bool) -> Signal { +public func messageMediaFileInteractiveFetched(context: AccountContextImpl, message: Message, file: TelegramMediaFile, userInitiated: Bool) -> Signal { return messageMediaFileInteractiveFetched(fetchManager: context.fetchManager, messageId: message.id, messageReference: MessageReference(message), file: file, userInitiated: userInitiated, priority: .userInitiated) } @@ -36,11 +36,11 @@ func messageMediaFileInteractiveFetched(fetchManager: FetchManager, messageId: M return fetchManager.interactivelyFetched(category: fetchCategoryForFile(file), location: .chat(messageId.peerId), locationKey: .messageId(messageId), mediaReference: mediaReference, resourceReference: mediaReference.resourceReference(file.resource), ranges: ranges, statsCategory: statsCategoryForFileWithAttributes(file.attributes), elevatedPriority: false, userInitiated: userInitiated, priority: priority) } -func messageMediaFileCancelInteractiveFetch(context: AccountContext, messageId: MessageId, file: TelegramMediaFile) { +func messageMediaFileCancelInteractiveFetch(context: AccountContextImpl, messageId: MessageId, file: TelegramMediaFile) { context.fetchManager.cancelInteractiveFetches(category: fetchCategoryForFile(file), location: .chat(messageId.peerId), locationKey: .messageId(messageId), resource: file.resource) } -public func messageMediaImageInteractiveFetched(context: AccountContext, message: Message, image: TelegramMediaImage, resource: MediaResource, storeToDownloadsPeerType: MediaAutoDownloadPeerType?) -> Signal { +public func messageMediaImageInteractiveFetched(context: AccountContextImpl, message: Message, image: TelegramMediaImage, resource: MediaResource, storeToDownloadsPeerType: MediaAutoDownloadPeerType?) -> Signal { return messageMediaImageInteractiveFetched(fetchManager: context.fetchManager, messageId: message.id, messageReference: MessageReference(message), image: image, resource: resource, userInitiated: true, priority: .userInitiated, storeToDownloadsPeerType: storeToDownloadsPeerType) } @@ -49,10 +49,10 @@ func messageMediaImageInteractiveFetched(fetchManager: FetchManager, messageId: return fetchManager.interactivelyFetched(category: .image, location: .chat(messageId.peerId), locationKey: .messageId(messageId), mediaReference: mediaReference, resourceReference: mediaReference.resourceReference(resource), statsCategory: .image, elevatedPriority: false, userInitiated: userInitiated, priority: priority, storeToDownloadsPeerType: storeToDownloadsPeerType) } -func messageMediaImageCancelInteractiveFetch(context: AccountContext, messageId: MessageId, image: TelegramMediaImage, resource: MediaResource) { +func messageMediaImageCancelInteractiveFetch(context: AccountContextImpl, messageId: MessageId, image: TelegramMediaImage, resource: MediaResource) { context.fetchManager.cancelInteractiveFetches(category: .image, location: .chat(messageId.peerId), locationKey: .messageId(messageId), resource: resource) } -func messageMediaFileStatus(context: AccountContext, messageId: MessageId, file: TelegramMediaFile) -> Signal { +func messageMediaFileStatus(context: AccountContextImpl, messageId: MessageId, file: TelegramMediaFile) -> Signal { return context.fetchManager.fetchStatus(category: fetchCategoryForFile(file), location: .chat(messageId.peerId), locationKey: .messageId(messageId), resource: file.resource) } diff --git a/submodules/TelegramUI/TelegramUI/FetchPhotoLibraryImageResource.swift b/submodules/TelegramUI/TelegramUI/FetchPhotoLibraryImageResource.swift index 7874e5d834..62601bdc58 100644 --- a/submodules/TelegramUI/TelegramUI/FetchPhotoLibraryImageResource.swift +++ b/submodules/TelegramUI/TelegramUI/FetchPhotoLibraryImageResource.swift @@ -51,7 +51,7 @@ func fetchPhotoLibraryResource(localIdentifier: String) -> Signal Signal { +private func internalMessageFileMediaPlaybackStatus(context: AccountContextImpl, file: TelegramMediaFile, message: Message, isRecentActions: Bool) -> Signal { guard let playerType = peerMessageMediaPlayerType(message) else { return .single(nil) } @@ -35,7 +35,7 @@ private func internalMessageFileMediaPlaybackStatus(context: AccountContext, fil } } -func messageFileMediaPlaybackStatus(context: AccountContext, file: TelegramMediaFile, message: Message, isRecentActions: Bool) -> Signal { +func messageFileMediaPlaybackStatus(context: AccountContextImpl, file: TelegramMediaFile, message: Message, isRecentActions: Bool) -> Signal { var duration = 0.0 if let value = file.duration { duration = Double(value) @@ -46,7 +46,7 @@ func messageFileMediaPlaybackStatus(context: AccountContext, file: TelegramMedia } } -func messageFileMediaResourceStatus(context: AccountContext, file: TelegramMediaFile, message: Message, isRecentActions: Bool) -> Signal { +func messageFileMediaResourceStatus(context: AccountContextImpl, file: TelegramMediaFile, message: Message, isRecentActions: Bool) -> Signal { let playbackStatus = internalMessageFileMediaPlaybackStatus(context: context, file: file, message: message, isRecentActions: isRecentActions) |> map { status -> MediaPlayerPlaybackStatus? in return status?.status } diff --git a/submodules/TelegramUI/TelegramUI/FormControllerItem.swift b/submodules/TelegramUI/TelegramUI/FormControllerItem.swift index 38b9c7ca98..d7f51e9a75 100644 --- a/submodules/TelegramUI/TelegramUI/FormControllerItem.swift +++ b/submodules/TelegramUI/TelegramUI/FormControllerItem.swift @@ -3,6 +3,7 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import MergeLists protocol FormControllerEntry: Identifiable { associatedtype ItemParams diff --git a/submodules/TelegramUI/TelegramUI/FormControllerNode.swift b/submodules/TelegramUI/TelegramUI/FormControllerNode.swift index f920e29d47..c33f299c0f 100644 --- a/submodules/TelegramUI/TelegramUI/FormControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/FormControllerNode.swift @@ -387,7 +387,7 @@ class FormControllerNode: View } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/FormEditableBlockItemNode.swift b/submodules/TelegramUI/TelegramUI/FormEditableBlockItemNode.swift index ce8e3d65e3..46f5e652bf 100644 --- a/submodules/TelegramUI/TelegramUI/FormEditableBlockItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/FormEditableBlockItemNode.swift @@ -3,6 +3,7 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import ItemListUI class FormEditableBlockItemNode: ASDisplayNode, FormControllerItemNode, FormBlockItemNodeProto, UIGestureRecognizerDelegate { private let topSeparatorInset: FormBlockItemInset @@ -18,7 +19,7 @@ class FormEditableBlockItemNode: ASDisplayNode, FormCo private var revealOptions: (left: [ItemListRevealOption], right: [ItemListRevealOption]) = ([], []) private var initialRevealOffset: CGFloat = 0.0 - private(set) var revealOffset: CGFloat = 0.0 + public private(set) var revealOffset: CGFloat = 0.0 private var recognizer: ItemListRevealOptionsGestureRecognizer? private var hapticFeedback: HapticFeedback? diff --git a/submodules/TelegramUI/TelegramUI/ForwardAccessoryPanelNode.swift b/submodules/TelegramUI/TelegramUI/ForwardAccessoryPanelNode.swift index 0f8a329766..2729394d5e 100644 --- a/submodules/TelegramUI/TelegramUI/ForwardAccessoryPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ForwardAccessoryPanelNode.swift @@ -78,14 +78,14 @@ final class ForwardAccessoryPanelNode: AccessoryPanelNode { var theme: PresentationTheme - init(context: AccountContext, messageIds: [MessageId], theme: PresentationTheme, strings: PresentationStrings) { + init(context: AccountContextImpl, messageIds: [MessageId], theme: PresentationTheme, strings: PresentationStrings) { self.messageIds = messageIds self.theme = theme self.closeButton = ASButtonNode() self.closeButton.accessibilityLabel = "Discard" self.closeButton.setImage(PresentationResourcesChat.chatInputPanelCloseIconImage(theme), for: []) - self.closeButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0) + self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0) self.closeButton.displaysAsynchronously = false self.lineNode = ASImageNode() diff --git a/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift b/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift index 3b9f33015d..12a7eea243 100644 --- a/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift +++ b/submodules/TelegramUI/TelegramUI/ForwardPrivacyChatPreviewItem.swift @@ -7,9 +7,10 @@ import TelegramCore import Postbox import TelegramPresentationData import TelegramUIPreferences +import ItemListUI class ForwardPrivacyChatPreviewItem: ListViewItem, ItemListItem { - let context: AccountContext + let context: AccountContextImpl let theme: PresentationTheme let strings: PresentationStrings let sectionId: ItemListSectionId @@ -21,7 +22,7 @@ class ForwardPrivacyChatPreviewItem: ListViewItem, ItemListItem { let linkEnabled: Bool let tooltipText: String - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, fontSize: PresentationFontSize, wallpaper: TelegramWallpaper, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, peerName: String, linkEnabled: Bool, tooltipText: String) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, fontSize: PresentationFontSize, wallpaper: TelegramWallpaper, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, peerName: String, linkEnabled: Bool, tooltipText: String) { self.context = context self.theme = theme self.strings = strings diff --git a/submodules/TelegramUI/TelegramUI/GalleryController.swift b/submodules/TelegramUI/TelegramUI/GalleryController.swift index 6856c12d7a..2395f68746 100644 --- a/submodules/TelegramUI/TelegramUI/GalleryController.swift +++ b/submodules/TelegramUI/TelegramUI/GalleryController.swift @@ -8,6 +8,7 @@ import AsyncDisplayKit import TelegramCore import SafariServices import TelegramPresentationData +import TextFormat private func tagsForMessage(_ message: Message) -> MessageTags? { for media in message.media { @@ -134,7 +135,7 @@ private func galleryMessageCaptionText(_ message: Message) -> String { return message.text } -func galleryItemForEntry(context: AccountContext, presentationData: PresentationData, entry: MessageHistoryEntry, isCentral: Bool = false, streamVideos: Bool, loopVideos: Bool = false, hideControls: Bool = false, fromPlayingVideo: Bool = false, landscape: Bool = false, timecode: Double? = nil, tempFilePath: String? = nil, playbackCompleted: @escaping () -> Void = {}, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void = { _ in }, openActionOptions: @escaping (GalleryControllerInteractionTapAction) -> Void = { _ in }) -> GalleryItem? { +func galleryItemForEntry(context: AccountContextImpl, presentationData: PresentationData, entry: MessageHistoryEntry, isCentral: Bool = false, streamVideos: Bool, loopVideos: Bool = false, hideControls: Bool = false, fromPlayingVideo: Bool = false, landscape: Bool = false, timecode: Double? = nil, tempFilePath: String? = nil, playbackCompleted: @escaping () -> Void = {}, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void = { _ in }, openActionOptions: @escaping (GalleryControllerInteractionTapAction) -> Void = { _ in }) -> GalleryItem? { let message = entry.message let location = entry.location if let (media, mediaImage) = mediaForMessage(message: message) { @@ -295,7 +296,7 @@ class GalleryController: ViewController { return self.displayNode as! GalleryControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let source: GalleryControllerItemSource @@ -339,7 +340,7 @@ class GalleryController: ViewController { private var performAction: (GalleryControllerInteractionTapAction) -> Void private var openActionOptions: (GalleryControllerInteractionTapAction) -> Void - init(context: AccountContext, source: GalleryControllerItemSource, invertItemOrder: Bool = false, streamSingleVideo: Bool = false, fromPlayingVideo: Bool = false, landscape: Bool = false, timecode: Double? = nil, synchronousLoad: Bool = false, replaceRootController: @escaping (ViewController, ValuePromise?) -> Void, baseNavigationController: NavigationController?, actionInteraction: GalleryControllerActionInteraction? = nil) { + init(context: AccountContextImpl, source: GalleryControllerItemSource, invertItemOrder: Bool = false, streamSingleVideo: Bool = false, fromPlayingVideo: Bool = false, landscape: Bool = false, timecode: Double? = nil, synchronousLoad: Bool = false, replaceRootController: @escaping (ViewController, ValuePromise?) -> Void, baseNavigationController: NavigationController?, actionInteraction: GalleryControllerActionInteraction? = nil) { self.context = context self.source = source self.replaceRootController = replaceRootController diff --git a/submodules/TelegramUI/TelegramUI/GalleryControllerNode.swift b/submodules/TelegramUI/TelegramUI/GalleryControllerNode.swift index 82edee516a..fc1a68febe 100644 --- a/submodules/TelegramUI/TelegramUI/GalleryControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/GalleryControllerNode.swift @@ -327,7 +327,7 @@ class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGestureRecog if let backgroundColor = self.backgroundNode.backgroundColor { let updatedColor = backgroundColor.withAlphaComponent(0.0) self.backgroundNode.backgroundColor = updatedColor - self.backgroundNode.layer.animate(from: backgroundColor.cgColor, to: updatedColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionLinear, duration: 0.15) + self.backgroundNode.layer.animate(from: backgroundColor.cgColor, to: updatedColor.cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.15) } UIView.animate(withDuration: 0.25, animations: { self.statusBar?.alpha = 0.0 @@ -341,7 +341,7 @@ class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGestureRecog if animateContent { contentAnimationCompleted = false - self.scrollView.layer.animateBounds(from: self.scrollView.layer.bounds, to: self.scrollView.layer.bounds.offsetBy(dx: 0.0, dy: -self.scrollView.layer.bounds.size.height), duration: 0.25, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false, completion: { _ in + self.scrollView.layer.animateBounds(from: self.scrollView.layer.bounds, to: self.scrollView.layer.bounds.offsetBy(dx: 0.0, dy: -self.scrollView.layer.bounds.size.height), duration: 0.25, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { _ in contentAnimationCompleted = true intermediateCompletion() }) @@ -391,7 +391,7 @@ class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGestureRecog let minimalDismissDistance = scrollView.contentSize.height / 12.0 if abs(velocity.y) > 1.0 || abs(distanceFromEquilibrium) > minimalDismissDistance { if let backgroundColor = self.backgroundNode.backgroundColor { - self.backgroundNode.layer.animate(from: backgroundColor, to: UIColor(white: 0.0, alpha: 0.0).cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionLinear, duration: 0.2, removeOnCompletion: false) + self.backgroundNode.layer.animate(from: backgroundColor, to: UIColor(white: 0.0, alpha: 0.0).cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.2, removeOnCompletion: false) } var interfaceAnimationCompleted = false @@ -422,7 +422,7 @@ class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGestureRecog if contentAnimationCompleted { contentAnimationCompleted = false - self.scrollView.layer.animateBounds(from: self.scrollView.layer.bounds, to: self.scrollView.layer.bounds.offsetBy(dx: 0.0, dy: self.scrollView.layer.bounds.size.height * (velocity.y < 0.0 ? -1.0 : 1.0)), duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false, completion: { _ in + self.scrollView.layer.animateBounds(from: self.scrollView.layer.bounds, to: self.scrollView.layer.bounds.offsetBy(dx: 0.0, dy: self.scrollView.layer.bounds.size.height * (velocity.y < 0.0 ? -1.0 : 1.0)), duration: 0.2, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { _ in contentAnimationCompleted = true completion() }) diff --git a/submodules/TelegramUI/TelegramUI/GalleryNavigationCheckNode.swift b/submodules/TelegramUI/TelegramUI/GalleryNavigationCheckNode.swift index 183af1eac9..3a53d69013 100644 --- a/submodules/TelegramUI/TelegramUI/GalleryNavigationCheckNode.swift +++ b/submodules/TelegramUI/TelegramUI/GalleryNavigationCheckNode.swift @@ -3,6 +3,7 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import CheckNode final class GalleryNavigationCheckNode: ASDisplayNode, NavigationButtonCustomDisplayNode { private var checkNode: CheckNode diff --git a/submodules/TelegramUI/TelegramUI/GalleryThumbnailContainerNode.swift b/submodules/TelegramUI/TelegramUI/GalleryThumbnailContainerNode.swift index 9c28320230..88e1ccffbb 100644 --- a/submodules/TelegramUI/TelegramUI/GalleryThumbnailContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/GalleryThumbnailContainerNode.swift @@ -153,7 +153,7 @@ final class GalleryThumbnailContainerNode: ASDisplayNode, UIScrollViewDelegate { self.scrollNode.frame = CGRect(origin: CGPoint(), size: size) let centralSpacing: CGFloat = 8.0 - let contentInset = UIEdgeInsetsMake(0.0, size.width / 2.0, 0.0, 0.0) + let contentInset = UIEdgeInsets(top: 0.0, left: size.width / 2.0, bottom: 0.0, right: 0.0) let contentSize = CGSize(width: size.width - contentInset.left + (itemBaseSize.width + spacing) * CGFloat(self.itemNodes.count - 1), height : size.height) var updated = false diff --git a/submodules/TelegramUI/TelegramUI/GameController.swift b/submodules/TelegramUI/TelegramUI/GameController.swift index 8609b12b3f..5a8ff15ae0 100644 --- a/submodules/TelegramUI/TelegramUI/GameController.swift +++ b/submodules/TelegramUI/TelegramUI/GameController.swift @@ -12,13 +12,13 @@ final class GameController: ViewController { return self.displayNode as! GameControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let url: String private let message: Message private var presentationData: PresentationData - init(context: AccountContext, url: String, message: Message) { + init(context: AccountContextImpl, url: String, message: Message) { self.context = context self.url = url self.message = message diff --git a/submodules/TelegramUI/TelegramUI/GameControllerNode.swift b/submodules/TelegramUI/TelegramUI/GameControllerNode.swift index 8275332938..3b1914762e 100644 --- a/submodules/TelegramUI/TelegramUI/GameControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/GameControllerNode.swift @@ -25,12 +25,12 @@ private class WeakGameScriptMessageHandler: NSObject, WKScriptMessageHandler { final class GameControllerNode: ViewControllerTracingNode { private var webView: WKWebView? - private let context: AccountContext + private let context: AccountContextImpl var presentationData: PresentationData private let present: (ViewController, Any?) -> Void private let message: Message - init(context: AccountContext, presentationData: PresentationData, url: String, present: @escaping (ViewController, Any?) -> Void, message: Message) { + init(context: AccountContextImpl, presentationData: PresentationData, url: String, present: @escaping (ViewController, Any?) -> Void, message: Message) { self.context = context self.presentationData = presentationData self.present = present @@ -89,7 +89,7 @@ final class GameControllerNode: ViewControllerTracingNode { } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/GifPaneSearchContentNode.swift b/submodules/TelegramUI/TelegramUI/GifPaneSearchContentNode.swift index 427035d894..f23dc27815 100644 --- a/submodules/TelegramUI/TelegramUI/GifPaneSearchContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/GifPaneSearchContentNode.swift @@ -98,7 +98,7 @@ func paneGifSearchForQuery(account: Account, query: String, updateActivity: ((Bo } final class GifPaneSearchContentNode: ASDisplayNode & PaneSearchContentNode { - private let context: AccountContext + private let context: AccountContextImpl private let controllerInteraction: ChatControllerInteraction private let inputNodeInteraction: ChatMediaInputNodeInteraction @@ -122,7 +122,7 @@ final class GifPaneSearchContentNode: ASDisplayNode & PaneSearchContentNode { var deactivateSearchBar: (() -> Void)? var updateActivity: ((Bool) -> Void)? - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction, trendingPromise: Promise<[FileMediaReference]?>) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction, trendingPromise: Promise<[FileMediaReference]?>) { self.context = context self.controllerInteraction = controllerInteraction self.inputNodeInteraction = inputNodeInteraction diff --git a/submodules/TelegramUI/TelegramUI/GridHoleItem.swift b/submodules/TelegramUI/TelegramUI/GridHoleItem.swift index cd308bb976..b603f10cb1 100644 --- a/submodules/TelegramUI/TelegramUI/GridHoleItem.swift +++ b/submodules/TelegramUI/TelegramUI/GridHoleItem.swift @@ -18,7 +18,7 @@ class GridHoleItemNode: GridItemNode { private let activityIndicatorView: UIActivityIndicatorView override init() { - self.activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray) + self.activityIndicatorView = UIActivityIndicatorView(style: .gray) super.init() diff --git a/submodules/TelegramUI/TelegramUI/GridMessageItem.swift b/submodules/TelegramUI/TelegramUI/GridMessageItem.swift index 89f0e6f6f8..f6e8c8511c 100644 --- a/submodules/TelegramUI/TelegramUI/GridMessageItem.swift +++ b/submodules/TelegramUI/TelegramUI/GridMessageItem.swift @@ -105,12 +105,12 @@ final class GridMessageItemSectionNode: ASDisplayNode { final class GridMessageItem: GridItem { fileprivate let theme: PresentationTheme private let strings: PresentationStrings - private let context: AccountContext + private let context: AccountContextImpl fileprivate let message: Message private let controllerInteraction: ChatControllerInteraction let section: GridSection? - init(theme: PresentationTheme, strings: PresentationStrings, context: AccountContext, message: Message, controllerInteraction: ChatControllerInteraction) { + init(theme: PresentationTheme, strings: PresentationStrings, context: AccountContextImpl, message: Message, controllerInteraction: ChatControllerInteraction) { self.theme = theme self.strings = strings self.context = context @@ -139,7 +139,7 @@ final class GridMessageItem: GridItem { } final class GridMessageItemNode: GridItemNode { - private var currentState: (AccountContext, Media, CGSize)? + private var currentState: (AccountContextImpl, Media, CGSize)? private let imageNode: TransformImageNode private(set) var messageId: MessageId? private var item: GridMessageItem? @@ -188,7 +188,7 @@ final class GridMessageItemNode: GridItemNode { self.imageNode.view.addGestureRecognizer(recognizer) } - func setup(context: AccountContext, item: GridMessageItem, media: Media, messageId: MessageId, controllerInteraction: ChatControllerInteraction, synchronousLoad: Bool) { + func setup(context: AccountContextImpl, item: GridMessageItem, media: Media, messageId: MessageId, controllerInteraction: ChatControllerInteraction, synchronousLoad: Bool) { self.item = item if self.currentState == nil || self.currentState!.0 !== context || !self.currentState!.1.isEqual(to: media) { diff --git a/submodules/TelegramUI/TelegramUI/GridMessageSelectionNode.swift b/submodules/TelegramUI/TelegramUI/GridMessageSelectionNode.swift index 714696b7b5..274b0d01fc 100644 --- a/submodules/TelegramUI/TelegramUI/GridMessageSelectionNode.swift +++ b/submodules/TelegramUI/TelegramUI/GridMessageSelectionNode.swift @@ -3,6 +3,7 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import CheckNode final class GridMessageSelectionNode: ASDisplayNode { private let toggle: (Bool) -> Void diff --git a/submodules/TelegramUI/TelegramUI/GroupInfoController.swift b/submodules/TelegramUI/TelegramUI/GroupInfoController.swift index 364eb5f7bd..2145172fa4 100644 --- a/submodules/TelegramUI/TelegramUI/GroupInfoController.swift +++ b/submodules/TelegramUI/TelegramUI/GroupInfoController.swift @@ -9,9 +9,12 @@ import LegacyComponents import TelegramPresentationData import SafariServices import TelegramUIPreferences +import ItemListUI +import TextFormat +import AccountContext private final class GroupInfoArguments { - let context: AccountContext + let context: AccountContextImpl let avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext let tapAvatarAction: () -> Void @@ -42,7 +45,7 @@ private final class GroupInfoArguments { let changeLocation: () -> Void let displayLocationContextMenu: (String) -> Void - init(context: AccountContext, avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext, tapAvatarAction: @escaping () -> Void, changeProfilePhoto: @escaping () -> Void, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, changeNotificationMuteSettings: @escaping () -> Void, openPreHistory: @escaping () -> Void, openSharedMedia: @escaping () -> Void, openAdministrators: @escaping () -> Void, openPermissions: @escaping () -> Void, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updateEditingDescriptionText: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addMember: @escaping () -> Void, promotePeer: @escaping (RenderedChannelParticipant) -> Void, restrictPeer: @escaping (RenderedChannelParticipant) -> Void, removePeer: @escaping (PeerId) -> Void, leave: @escaping () -> Void, displayUsernameShareMenu: @escaping (String) -> Void, displayUsernameContextMenu: @escaping (String) -> Void, displayAboutContextMenu: @escaping (String) -> Void, aboutLinkAction: @escaping (TextLinkItemActionType, TextLinkItem) -> Void, openStickerPackSetup: @escaping () -> Void, openGroupTypeSetup: @escaping () -> Void, openLinkedChannelSetup: @escaping () -> Void, openLocation: @escaping (PeerGeoLocation) -> Void, changeLocation: @escaping () -> Void, displayLocationContextMenu: @escaping (String) -> Void) { + init(context: AccountContextImpl, avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext, tapAvatarAction: @escaping () -> Void, changeProfilePhoto: @escaping () -> Void, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, changeNotificationMuteSettings: @escaping () -> Void, openPreHistory: @escaping () -> Void, openSharedMedia: @escaping () -> Void, openAdministrators: @escaping () -> Void, openPermissions: @escaping () -> Void, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updateEditingDescriptionText: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addMember: @escaping () -> Void, promotePeer: @escaping (RenderedChannelParticipant) -> Void, restrictPeer: @escaping (RenderedChannelParticipant) -> Void, removePeer: @escaping (PeerId) -> Void, leave: @escaping () -> Void, displayUsernameShareMenu: @escaping (String) -> Void, displayUsernameContextMenu: @escaping (String) -> Void, displayAboutContextMenu: @escaping (String) -> Void, aboutLinkAction: @escaping (TextLinkItemActionType, TextLinkItem) -> Void, openStickerPackSetup: @escaping () -> Void, openGroupTypeSetup: @escaping () -> Void, openLinkedChannelSetup: @escaping () -> Void, openLocation: @escaping (PeerGeoLocation) -> Void, changeLocation: @escaping () -> Void, displayLocationContextMenu: @escaping (String) -> Void) { self.context = context self.avatarAndNameInfoContext = avatarAndNameInfoContext self.tapAvatarAction = tapAvatarAction @@ -1258,7 +1261,7 @@ private func valuesRequiringUpdate(state: GroupInfoState, view: PeerView) -> (ti } } -public func groupInfoController(context: AccountContext, peerId originalPeerId: PeerId, membersLoaded: @escaping () -> Void = {}) -> ViewController { +public func groupInfoController(context: AccountContextImpl, peerId originalPeerId: PeerId, membersLoaded: @escaping () -> Void = {}) -> ViewController { let statePromise = ValuePromise(GroupInfoState(updatingAvatar: nil, editingState: nil, updatingName: nil, peerIdWithRevealedOptions: nil, temporaryParticipants: [], successfullyAddedParticipantIds: Set(), removingParticipantIds: Set(), savingData: false, searchingMembers: false), ignoreRepeated: true) let stateValue = Atomic(value: GroupInfoState(updatingAvatar: nil, editingState: nil, updatingName: nil, peerIdWithRevealedOptions: nil, temporaryParticipants: [], successfullyAddedParticipantIds: Set(), removingParticipantIds: Set(), savingData: false, searchingMembers: false)) let updateState: ((GroupInfoState) -> GroupInfoState) -> Void = { f in @@ -1382,7 +1385,7 @@ public func groupInfoController(context: AccountContext, peerId originalPeerId: } let completedImpl: (UIImage) -> Void = { image in - if let data = UIImageJPEGRepresentation(image, 0.6) { + if let data = image.jpegData(compressionQuality: 0.6) { let resource = LocalFileMediaResource(fileId: arc4random64()) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) let representation = TelegramMediaImageRepresentation(dimensions: CGSize(width: 640.0, height: 640.0), resource: resource) @@ -2359,12 +2362,12 @@ public func groupInfoController(context: AccountContext, peerId originalPeerId: } } - aboutLinkActionImpl = { [weak controller] action, itemLink in + aboutLinkActionImpl = { [weak context, weak controller] action, itemLink in let _ = (peerView.get() |> take(1) |> deliverOnMainQueue).start(next: { peerView in - if let controller = controller { - handleTextLinkAction(context: context, peerId: peerView.peerId, navigateDisposable: navigateDisposable, controller: controller, action: action, itemLink: itemLink) + if let controller = controller, let context = context { + context.sharedContext.handleTextLinkAction(context: context, peerId: peerView.peerId, navigateDisposable: navigateDisposable, controller: controller, action: action, itemLink: itemLink) } }) } diff --git a/submodules/TelegramUI/TelegramUI/GroupInfoSearchItem.swift b/submodules/TelegramUI/TelegramUI/GroupInfoSearchItem.swift index 1b9071c53f..31c71ee009 100644 --- a/submodules/TelegramUI/TelegramUI/GroupInfoSearchItem.swift +++ b/submodules/TelegramUI/TelegramUI/GroupInfoSearchItem.swift @@ -5,9 +5,10 @@ import AsyncDisplayKit import Postbox import TelegramCore import SwiftSignalKit +import ItemListUI final class ChannelMembersSearchItem: ItemListControllerSearch { - let context: AccountContext + let context: AccountContextImpl let peerId: PeerId let searchContext: GroupMembersSearchContext? let cancel: () -> Void @@ -19,7 +20,7 @@ final class ChannelMembersSearchItem: ItemListControllerSearch { private var activity: ValuePromise = ValuePromise(ignoreRepeated: false) private let activityDisposable = MetaDisposable() - init(context: AccountContext, peerId: PeerId, searchContext: GroupMembersSearchContext?, searchMode: ChannelMembersSearchMode = .searchMembers, cancel: @escaping () -> Void, openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, present: @escaping (ViewController, Any?) -> Void) { + init(context: AccountContextImpl, peerId: PeerId, searchContext: GroupMembersSearchContext?, searchMode: ChannelMembersSearchMode = .searchMembers, cancel: @escaping () -> Void, openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, present: @escaping (ViewController, Any?) -> Void) { self.context = context self.peerId = peerId self.searchContext = searchContext @@ -80,7 +81,7 @@ final class ChannelMembersSearchItem: ItemListControllerSearch { private final class ChannelMembersSearchItemNode: ItemListControllerSearchNode { private let containerNode: ChannelMembersSearchContainerNode - init(context: AccountContext, peerId: PeerId, searchMode: ChannelMembersSearchMode, searchContext: GroupMembersSearchContext?, openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, cancel: @escaping () -> Void, updateActivity: @escaping(Bool) -> Void, present: @escaping (ViewController, Any?) -> Void) { + init(context: AccountContextImpl, peerId: PeerId, searchMode: ChannelMembersSearchMode, searchContext: GroupMembersSearchContext?, openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, cancel: @escaping () -> Void, updateActivity: @escaping(Bool) -> Void, present: @escaping (ViewController, Any?) -> Void) { self.containerNode = ChannelMembersSearchContainerNode(context: context, peerId: peerId, mode: searchMode, filters: [], searchContext: searchContext, openPeer: { peer, participant in openPeer(peer, participant) }, updateActivity: updateActivity, present: present) diff --git a/submodules/TelegramUI/TelegramUI/GroupInfoSearchNavigationContentNode.swift b/submodules/TelegramUI/TelegramUI/GroupInfoSearchNavigationContentNode.swift index b84661afa9..b9969d598e 100644 --- a/submodules/TelegramUI/TelegramUI/GroupInfoSearchNavigationContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/GroupInfoSearchNavigationContentNode.swift @@ -5,6 +5,7 @@ import Display import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private let searchBarFont = Font.regular(17.0) diff --git a/submodules/TelegramUI/TelegramUI/GroupPreHistorySetupController.swift b/submodules/TelegramUI/TelegramUI/GroupPreHistorySetupController.swift index 1d8856cc28..d4d14e9e9f 100644 --- a/submodules/TelegramUI/TelegramUI/GroupPreHistorySetupController.swift +++ b/submodules/TelegramUI/TelegramUI/GroupPreHistorySetupController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private final class GroupPreHistorySetupArguments { let toggle: (Bool) -> Void @@ -112,7 +113,7 @@ private func groupPreHistorySetupEntries(isSupergroup: Bool, presentationData: P return entries } -public func groupPreHistorySetupController(context: AccountContext, peerId: PeerId, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void) -> ViewController { +public func groupPreHistorySetupController(context: AccountContextImpl, peerId: PeerId, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void) -> ViewController { let statePromise = ValuePromise(GroupPreHistorySetupState(), ignoreRepeated: true) let stateValue = Atomic(value: GroupPreHistorySetupState()) let updateState: ((GroupPreHistorySetupState) -> GroupPreHistorySetupState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/GroupStickerPackCurrentItem.swift b/submodules/TelegramUI/TelegramUI/GroupStickerPackCurrentItem.swift index 6840993a82..a22d770210 100644 --- a/submodules/TelegramUI/TelegramUI/GroupStickerPackCurrentItem.swift +++ b/submodules/TelegramUI/TelegramUI/GroupStickerPackCurrentItem.swift @@ -6,6 +6,8 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI +import ActivityIndicator enum GroupStickerPackCurrentItemContent: Equatable { case notFound diff --git a/submodules/TelegramUI/TelegramUI/GroupStickerPackSetupController.swift b/submodules/TelegramUI/TelegramUI/GroupStickerPackSetupController.swift index e37813635f..f058201ac6 100644 --- a/submodules/TelegramUI/TelegramUI/GroupStickerPackSetupController.swift +++ b/submodules/TelegramUI/TelegramUI/GroupStickerPackSetupController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class GroupStickerPackSetupControllerArguments { let account: Account @@ -302,7 +303,7 @@ private func groupStickerPackSetupControllerEntries(presentationData: Presentati return entries } -public func groupStickerPackSetupController(context: AccountContext, peerId: PeerId, currentPackInfo: StickerPackCollectionInfo?) -> ViewController { +public func groupStickerPackSetupController(context: AccountContextImpl, peerId: PeerId, currentPackInfo: StickerPackCollectionInfo?) -> ViewController { let initialState = GroupStickerPackSetupControllerState(isSaving: false) let statePromise = ValuePromise(initialState, ignoreRepeated: true) diff --git a/submodules/TelegramUI/TelegramUI/GroupsInCommonController.swift b/submodules/TelegramUI/TelegramUI/GroupsInCommonController.swift index 27ff7ee61d..af6a4d468d 100644 --- a/submodules/TelegramUI/TelegramUI/GroupsInCommonController.swift +++ b/submodules/TelegramUI/TelegramUI/GroupsInCommonController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class GroupsInCommonControllerArguments { let account: Account @@ -132,7 +133,7 @@ private func groupsInCommonControllerEntries(presentationData: PresentationData, return entries } -public func groupsInCommonController(context: AccountContext, peerId: PeerId) -> ViewController { +public func groupsInCommonController(context: AccountContextImpl, peerId: PeerId) -> ViewController { let statePromise = ValuePromise(GroupsInCommonControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: GroupsInCommonControllerState()) let updateState: ((GroupsInCommonControllerState) -> GroupsInCommonControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/HashtagChatInputContextPanelNode.swift b/submodules/TelegramUI/TelegramUI/HashtagChatInputContextPanelNode.swift index cff69c33c4..78f8825e46 100644 --- a/submodules/TelegramUI/TelegramUI/HashtagChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/HashtagChatInputContextPanelNode.swift @@ -5,17 +5,10 @@ import Postbox import TelegramCore import Display import TelegramPresentationData +import MergeLists private struct HashtagChatInputContextPanelEntryStableId: Hashable { let text: String - - var hashValue: Int { - return self.text.hashValue - } - - static func ==(lhs: HashtagChatInputContextPanelEntryStableId, rhs: HashtagChatInputContextPanelEntryStableId) -> Bool { - return lhs.text == rhs.text - } } private struct HashtagChatInputContextPanelEntry: Comparable, Identifiable { @@ -67,7 +60,7 @@ final class HashtagChatInputContextPanelNode: ChatInputContextPanelNode { private var enqueuedTransitions: [(HashtagChatInputContextPanelTransition, Bool)] = [] private var validLayout: (CGSize, CGFloat, CGFloat)? - override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + override init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.listView = ListView() self.listView.isOpaque = false self.listView.stackFromBottom = true diff --git a/submodules/TelegramUI/TelegramUI/HashtagSearchController.swift b/submodules/TelegramUI/TelegramUI/HashtagSearchController.swift index a82feb8dcd..58669c3b76 100644 --- a/submodules/TelegramUI/TelegramUI/HashtagSearchController.swift +++ b/submodules/TelegramUI/TelegramUI/HashtagSearchController.swift @@ -9,7 +9,7 @@ import TelegramPresentationData final class HashtagSearchController: TelegramController { private let queue = Queue() - private let context: AccountContext + private let context: AccountContextImpl private let peer: Peer? private let query: String private var transitionDisposable: Disposable? @@ -21,7 +21,7 @@ final class HashtagSearchController: TelegramController { return self.displayNode as! HashtagSearchControllerNode } - init(context: AccountContext, peer: Peer?, query: String) { + init(context: AccountContextImpl, peer: Peer?, query: String) { self.context = context self.peer = peer self.query = query diff --git a/submodules/TelegramUI/TelegramUI/HashtagSearchControllerNode.swift b/submodules/TelegramUI/TelegramUI/HashtagSearchControllerNode.swift index ef0de12e0a..03a2404d7e 100644 --- a/submodules/TelegramUI/TelegramUI/HashtagSearchControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/HashtagSearchControllerNode.swift @@ -13,7 +13,7 @@ final class HashtagSearchControllerNode: ASDisplayNode { var chatController: ChatController? - private let context: AccountContext + private let context: AccountContextImpl private let query: String private var containerLayout: (ContainerViewLayout, CGFloat)? @@ -22,7 +22,7 @@ final class HashtagSearchControllerNode: ASDisplayNode { var navigationBar: NavigationBar? - init(context: AccountContext, peer: Peer?, query: String, theme: PresentationTheme, strings: PresentationStrings) { + init(context: AccountContextImpl, peer: Peer?, query: String, theme: PresentationTheme, strings: PresentationStrings) { self.context = context self.query = query self.listNode = ListView() diff --git a/submodules/TelegramUI/TelegramUI/HorizontalListContextResultsChatInputContextPanelNode.swift b/submodules/TelegramUI/TelegramUI/HorizontalListContextResultsChatInputContextPanelNode.swift index 2e269b83fe..f877c3dafa 100644 --- a/submodules/TelegramUI/TelegramUI/HorizontalListContextResultsChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/HorizontalListContextResultsChatInputContextPanelNode.swift @@ -6,6 +6,7 @@ import TelegramCore import Display import SwiftSignalKit import TelegramPresentationData +import MergeLists private struct ChatContextResultStableId: Hashable { let result: ChatContextResult @@ -82,7 +83,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont private var enqueuedTransitions: [(HorizontalListContextResultsChatInputContextPanelTransition, Bool)] = [] private var hasValidLayout = false - override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + override init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.strings = strings self.separatorNode = ASDisplayNode() diff --git a/submodules/TelegramUI/TelegramUI/HorizontalListContextResultsChatInputPanelItem.swift b/submodules/TelegramUI/TelegramUI/HorizontalListContextResultsChatInputPanelItem.swift index 54b531a1b2..a189395b04 100644 --- a/submodules/TelegramUI/TelegramUI/HorizontalListContextResultsChatInputPanelItem.swift +++ b/submodules/TelegramUI/TelegramUI/HorizontalListContextResultsChatInputPanelItem.swift @@ -117,19 +117,19 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode let displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent)) self.displayLink = displayLink - displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + displayLink.add(to: RunLoop.main, forMode: .common) if #available(iOS 10.0, *) { displayLink.preferredFramesPerSecond = 25 } else { displayLink.frameInterval = 2 } displayLink.isPaused = false - CMTimebaseSetRate(self.timebase, 1.0) + CMTimebaseSetRate(self.timebase, rate: 1.0) } else if let displayLink = self.displayLink { self.displayLink = nil displayLink.isPaused = true displayLink.invalidate() - CMTimebaseSetRate(self.timebase, 0.0) + CMTimebaseSetRate(self.timebase, rate: 0.0) } } } @@ -150,8 +150,8 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode self.imageNode.displaysAsynchronously = false var timebase: CMTimebase? - CMTimebaseCreateWithMasterClock(nil, CMClockGetHostTimeClock(), &timebase) - CMTimebaseSetRate(timebase!, 0.0) + CMTimebaseCreateWithMasterClock(allocator: nil, masterClock: CMClockGetHostTimeClock(), timebaseOut: &timebase) + CMTimebaseSetRate(timebase!, rate: 0.0) self.timebase = timebase! super.init(layerBacked: false, dynamicBounce: false) @@ -442,6 +442,6 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode guard let item = self.item else { return } - item.resultSelected(item.result, self, self.bounds) + let _ = item.resultSelected(item.result, self, self.bounds) } } diff --git a/submodules/TelegramUI/TelegramUI/HorizontalStickersChatContextPanelNode.swift b/submodules/TelegramUI/TelegramUI/HorizontalStickersChatContextPanelNode.swift index 5b4d56c212..5cbb688673 100755 --- a/submodules/TelegramUI/TelegramUI/HorizontalStickersChatContextPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/HorizontalStickersChatContextPanelNode.swift @@ -6,6 +6,7 @@ import TelegramCore import Display import SwiftSignalKit import TelegramPresentationData +import MergeLists final class HorizontalStickersChatContextPanelInteraction { var previewedStickerItem: StickerPackItem? @@ -105,7 +106,7 @@ final class HorizontalStickersChatContextPanelNode: ChatInputContextPanelNode { private var stickerPreviewController: StickerPreviewController? - override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + override init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.strings = strings self.backgroundNode = ASImageNode() diff --git a/submodules/TelegramUI/TelegramUI/ICloudResources.swift b/submodules/TelegramUI/TelegramUI/ICloudResources.swift index b9553f4e4c..653fed8643 100644 --- a/submodules/TelegramUI/TelegramUI/ICloudResources.swift +++ b/submodules/TelegramUI/TelegramUI/ICloudResources.swift @@ -185,7 +185,7 @@ func fetchICloudFileResource(resource: ICloudFileResource) -> Signal Signal Bool { + public func isEqual(to other: ItemListItemTag) -> Bool { if let other = other as? InstalledStickerPacksEntryTag, self == other { return true } else { @@ -442,7 +444,7 @@ public enum InstalledStickerPacksControllerMode { case masks } -public func installedStickerPacksController(context: AccountContext, mode: InstalledStickerPacksControllerMode, archivedPacks: [ArchivedStickerPackItem]? = nil, updatedPacks: @escaping ([ArchivedStickerPackItem]?) -> Void = { _ in }, focusOnItemTag: InstalledStickerPacksEntryTag? = nil) -> ViewController { +public func installedStickerPacksController(context: AccountContextImpl, mode: InstalledStickerPacksControllerMode, archivedPacks: [ArchivedStickerPackItem]? = nil, updatedPacks: @escaping ([ArchivedStickerPackItem]?) -> Void = { _ in }, focusOnItemTag: InstalledStickerPacksEntryTag? = nil) -> ViewController { let initialState = InstalledStickerPacksControllerState().withUpdatedEditing(mode == .modal) let statePromise = ValuePromise(initialState, ignoreRepeated: true) let stateValue = Atomic(value: initialState) diff --git a/submodules/TelegramUI/TelegramUI/InstantImageGalleryItem.swift b/submodules/TelegramUI/TelegramUI/InstantImageGalleryItem.swift index bcfd2415ce..72b1195e51 100644 --- a/submodules/TelegramUI/TelegramUI/InstantImageGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantImageGalleryItem.swift @@ -31,7 +31,7 @@ private struct InstantImageGalleryThumbnailItem: GalleryThumbnailItem { } class InstantImageGalleryItem: GalleryItem { - let context: AccountContext + let context: AccountContextImpl let presentationData: PresentationData let imageReference: ImageMediaReference let caption: NSAttributedString @@ -40,7 +40,7 @@ class InstantImageGalleryItem: GalleryItem { let openUrl: (InstantPageUrlItem) -> Void let openUrlOptions: (InstantPageUrlItem) -> Void - init(context: AccountContext, presentationData: PresentationData, imageReference: ImageMediaReference, caption: NSAttributedString, credit: NSAttributedString, location: InstantPageGalleryEntryLocation?, openUrl: @escaping (InstantPageUrlItem) -> Void, openUrlOptions: @escaping (InstantPageUrlItem) -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, imageReference: ImageMediaReference, caption: NSAttributedString, credit: NSAttributedString, location: InstantPageGalleryEntryLocation?, openUrl: @escaping (InstantPageUrlItem) -> Void, openUrlOptions: @escaping (InstantPageUrlItem) -> Void) { self.context = context self.presentationData = presentationData self.imageReference = imageReference @@ -81,18 +81,18 @@ class InstantImageGalleryItem: GalleryItem { } final class InstantImageGalleryItemNode: ZoomableContentGalleryItemNode { - private let context: AccountContext + private let context: AccountContextImpl private let imageNode: TransformImageNode fileprivate let _ready = Promise() fileprivate let _title = Promise() private let footerContentNode: InstantPageGalleryFooterContentNode - private var contextAndMedia: (AccountContext, AnyMediaReference)? + private var contextAndMedia: (AccountContextImpl, AnyMediaReference)? private var fetchDisposable = MetaDisposable() - init(context: AccountContext, presentationData: PresentationData, openUrl: @escaping (InstantPageUrlItem) -> Void, openUrlOptions: @escaping (InstantPageUrlItem) -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, openUrl: @escaping (InstantPageUrlItem) -> Void, openUrlOptions: @escaping (InstantPageUrlItem) -> Void) { self.context = context self.imageNode = TransformImageNode() @@ -142,7 +142,7 @@ final class InstantImageGalleryItemNode: ZoomableContentGalleryItemNode { self.footerContentNode.setShareMedia(imageReference.abstract) } - func setFile(context: AccountContext, fileReference: FileMediaReference) { + func setFile(context: AccountContextImpl, fileReference: FileMediaReference) { if self.contextAndMedia == nil || !self.contextAndMedia!.1.media.isEqual(to: fileReference.media) { if let largestSize = fileReference.media.dimensions { let displaySize = largestSize.dividedByScreenScale() @@ -278,7 +278,7 @@ final class InstantImageGalleryItemNode: ZoomableContentGalleryItemNode { }) /*self.statusNodeContainer.layer.animatePosition(from: self.statusNodeContainer.position, to: CGPoint(x: transformedSuperFrame.midX, y: transformedSuperFrame.midY), duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false) - self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false)*/ + self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false)*/ } override func visibilityUpdated(isVisible: Bool) { diff --git a/submodules/TelegramUI/TelegramUI/InstantPageAnchorItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageAnchorItem.swift index 4620a145e1..8527391ca9 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageAnchorItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageAnchorItem.swift @@ -25,7 +25,7 @@ final class InstantPageAnchorItem: InstantPageItem { func drawInTile(context: CGContext) { } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return nil } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageArticleItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageArticleItem.swift index 7b44506e6c..407b14458a 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageArticleItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageArticleItem.swift @@ -30,7 +30,7 @@ final class InstantPageArticleItem: InstantPageItem { self.rtl = rtl } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return InstantPageArticleNode(context: context, item: self, webPage: self.webPage, strings: strings, theme: theme, contentItems: self.contentItems, contentSize: self.contentSize, cover: self.cover, url: self.url, webpageId: self.webpageId, rtl: self.rtl, openUrl: openUrl) } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageArticleNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageArticleNode.swift index 49a2fb4831..a0c17cf1db 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageArticleNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageArticleNode.swift @@ -26,7 +26,7 @@ final class InstantPageArticleNode: ASDisplayNode, InstantPageNode { private var fetchedDisposable = MetaDisposable() - init(context: AccountContext, item: InstantPageArticleItem, webPage: TelegramMediaWebpage, strings: PresentationStrings, theme: InstantPageTheme, contentItems: [InstantPageItem], contentSize: CGSize, cover: TelegramMediaImage?, url: String, webpageId: MediaId, rtl: Bool, openUrl: @escaping (InstantPageUrlItem) -> Void) { + init(context: AccountContextImpl, item: InstantPageArticleItem, webPage: TelegramMediaWebpage, strings: PresentationStrings, theme: InstantPageTheme, contentItems: [InstantPageItem], contentSize: CGSize, cover: TelegramMediaImage?, url: String, webpageId: MediaId, rtl: Bool, openUrl: @escaping (InstantPageUrlItem) -> Void) { self.item = item self.url = url self.webpageId = webpageId diff --git a/submodules/TelegramUI/TelegramUI/InstantPageAudioItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageAudioItem.swift index a053a80e4f..852a16bcc3 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageAudioItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageAudioItem.swift @@ -21,7 +21,7 @@ final class InstantPageAudioItem: InstantPageItem { self.medias = [media] } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return InstantPageAudioNode(context: context, strings: strings, theme: theme, webPage: self.webpage, media: self.media, openMedia: openMedia) } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageAudioNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageAudioNode.swift index 014b7c8f64..861031357a 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageAudioNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageAudioNode.swift @@ -54,7 +54,7 @@ private func titleString(media: InstantPageMedia, theme: InstantPageTheme) -> NS } final class InstantPageAudioNode: ASDisplayNode, InstantPageNode { - private let context: AccountContext + private let context: AccountContextImpl let media: InstantPageMedia private let openMedia: (InstantPageMedia) -> Void private var strings: PresentationStrings @@ -75,7 +75,7 @@ final class InstantPageAudioNode: ASDisplayNode, InstantPageNode { private var isPlaying: Bool = false private var playbackState: SharedMediaPlayerItemPlaybackState? - init(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, webPage: TelegramMediaWebpage, media: InstantPageMedia, openMedia: @escaping (InstantPageMedia) -> Void) { + init(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, webPage: TelegramMediaWebpage, media: InstantPageMedia, openMedia: @escaping (InstantPageMedia) -> Void) { self.context = context self.strings = strings self.theme = theme diff --git a/submodules/TelegramUI/TelegramUI/InstantPageContentNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageContentNode.swift index bcef539cde..9e215c7483 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageContentNode.swift @@ -8,7 +8,7 @@ import SwiftSignalKit import TelegramPresentationData final class InstantPageContentNode : ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private let strings: PresentationStrings private let theme: InstantPageTheme @@ -36,7 +36,7 @@ final class InstantPageContentNode : ASDisplayNode { private var previousVisibleBounds: CGRect? - init(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, items: [InstantPageItem], contentSize: CGSize, inOverlayPanel: Bool = false, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void) { + init(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, items: [InstantPageItem], contentSize: CGSize, inOverlayPanel: Bool = false, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void) { self.context = context self.strings = strings self.theme = theme diff --git a/submodules/TelegramUI/TelegramUI/InstantPageController.swift b/submodules/TelegramUI/TelegramUI/InstantPageController.swift index 156e9e56c1..aae509e3d4 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageController.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageController.swift @@ -8,7 +8,7 @@ import TelegramPresentationData import TelegramUIPreferences final class InstantPageController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private var webPage: TelegramMediaWebpage private let sourcePeerType: MediaAutoDownloadPeerType private let anchor: String? @@ -31,7 +31,7 @@ final class InstantPageController: ViewController { private var settingsDisposable: Disposable? private var themeSettings: PresentationThemeSettings? - init(context: AccountContext, webPage: TelegramMediaWebpage, sourcePeerType: MediaAutoDownloadPeerType, anchor: String? = nil) { + init(context: AccountContextImpl, webPage: TelegramMediaWebpage, sourcePeerType: MediaAutoDownloadPeerType, anchor: String? = nil) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageControllerNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageControllerNode.swift index 32a15ba75b..0513ae696c 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageControllerNode.swift @@ -10,7 +10,7 @@ import TelegramPresentationData import TelegramUIPreferences final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate { - private let context: AccountContext + private let context: AccountContextImpl private var settings: InstantPagePresentationSettings? private var themeSettings: PresentationThemeSettings? private var presentationTheme: PresentationTheme @@ -78,7 +78,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate { return InstantPageStoredState(contentOffset: Double(self.scrollNode.view.contentOffset.y), details: details) } - init(context: AccountContext, settings: InstantPagePresentationSettings?, themeSettings: PresentationThemeSettings?, presentationTheme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, statusBar: StatusBar, sourcePeerType: MediaAutoDownloadPeerType, getNavigationController: @escaping () -> NavigationController?, present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, openPeer: @escaping (PeerId) -> Void, navigateBack: @escaping () -> Void) { + init(context: AccountContextImpl, settings: InstantPagePresentationSettings?, themeSettings: PresentationThemeSettings?, presentationTheme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, statusBar: StatusBar, sourcePeerType: MediaAutoDownloadPeerType, getNavigationController: @escaping () -> NavigationController?, present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, openPeer: @escaping (PeerId) -> Void, navigateBack: @escaping () -> Void) { self.context = context self.presentationTheme = presentationTheme self.dateTimeFormat = dateTimeFormat @@ -338,7 +338,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate { if self.scrollNode.bounds.size != layout.size || !self.scrollNode.view.contentInset.top.isEqual(to: scrollInsetTop) { self.scrollNode.frame = CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: layout.size.height) self.scrollNodeHeader.frame = CGRect(origin: CGPoint(x: 0.0, y: -2000.0), size: CGSize(width: layout.size.width, height: 2000.0)) - self.scrollNode.view.contentInset = UIEdgeInsetsMake(scrollInsetTop, 0.0, layout.intrinsicInsets.bottom, 0.0) + self.scrollNode.view.contentInset = UIEdgeInsets(top: scrollInsetTop, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0) if widthUpdated { self.updateLayout() } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageDetailsItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageDetailsItem.swift index 8fb6383e13..02503ba2f3 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageDetailsItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageDetailsItem.swift @@ -31,7 +31,7 @@ final class InstantPageDetailsItem: InstantPageItem { self.index = index } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { var expanded: Bool? if let expandedDetails = currentExpandedDetails, let currentlyExpanded = expandedDetails[self.index] { expanded = currentlyExpanded diff --git a/submodules/TelegramUI/TelegramUI/InstantPageDetailsNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageDetailsNode.swift index 4d4dac96cd..fd6d414d7b 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageDetailsNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageDetailsNode.swift @@ -11,7 +11,7 @@ private let detailsInset: CGFloat = 17.0 private let titleInset: CGFloat = 22.0 final class InstantPageDetailsNode: ASDisplayNode, InstantPageNode { - private let context: AccountContext + private let context: AccountContextImpl private let strings: PresentationStrings private let theme: InstantPageTheme let item: InstantPageDetailsItem @@ -32,7 +32,7 @@ final class InstantPageDetailsNode: ASDisplayNode, InstantPageNode { var requestLayoutUpdate: ((Bool) -> Void)? - init(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, item: InstantPageDetailsItem, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, currentlyExpanded: Bool?, updateDetailsExpanded: @escaping (Bool) -> Void) { + init(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, item: InstantPageDetailsItem, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, currentlyExpanded: Bool?, updateDetailsExpanded: @escaping (Bool) -> Void) { self.context = context self.strings = strings self.theme = theme @@ -238,7 +238,7 @@ final class InstantPageDetailsArrowNode : ASDisplayNode { self.displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent)) self.displayLink?.isPaused = true - self.displayLink?.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink?.add(to: RunLoop.main, forMode: .common) } deinit { diff --git a/submodules/TelegramUI/TelegramUI/InstantPageFeedbackItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageFeedbackItem.swift index 57072965f2..fe25996829 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageFeedbackItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageFeedbackItem.swift @@ -18,7 +18,7 @@ final class InstantPageFeedbackItem: InstantPageItem { self.webPage = webPage } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return InstantPageFeedbackNode(context: context, strings: strings, theme: theme, webPage: self.webPage, openUrl: openUrl) } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageFeedbackNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageFeedbackNode.swift index d64014b437..46fa08056d 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageFeedbackNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageFeedbackNode.swift @@ -8,7 +8,7 @@ import SwiftSignalKit import TelegramPresentationData final class InstantPageFeedbackNode: ASDisplayNode, InstantPageNode { - private let context: AccountContext + private let context: AccountContextImpl private let webPage: TelegramMediaWebpage private let openUrl: (InstantPageUrlItem) -> Void @@ -18,7 +18,7 @@ final class InstantPageFeedbackNode: ASDisplayNode, InstantPageNode { private let resolveDisposable = MetaDisposable() - init(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, webPage: TelegramMediaWebpage, openUrl: @escaping (InstantPageUrlItem) -> Void) { + init(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, webPage: TelegramMediaWebpage, openUrl: @escaping (InstantPageUrlItem) -> Void) { self.context = context self.webPage = webPage self.openUrl = openUrl diff --git a/submodules/TelegramUI/TelegramUI/InstantPageGalleryController.swift b/submodules/TelegramUI/TelegramUI/InstantPageGalleryController.swift index bb01ec4cfe..f985e8b8ab 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageGalleryController.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageGalleryController.swift @@ -30,7 +30,7 @@ struct InstantPageGalleryEntry: Equatable { return lhs.index == rhs.index && lhs.pageId == rhs.pageId && lhs.media == rhs.media && lhs.caption == rhs.caption && lhs.credit == rhs.credit && lhs.location == rhs.location } - func item(context: AccountContext, webPage: TelegramMediaWebpage, message: Message?, presentationData: PresentationData, fromPlayingVideo: Bool, landscape: Bool, openUrl: @escaping (InstantPageUrlItem) -> Void, openUrlOptions: @escaping (InstantPageUrlItem) -> Void) -> GalleryItem { + func item(context: AccountContextImpl, webPage: TelegramMediaWebpage, message: Message?, presentationData: PresentationData, fromPlayingVideo: Bool, landscape: Bool, openUrl: @escaping (InstantPageUrlItem) -> Void, openUrlOptions: @escaping (InstantPageUrlItem) -> Void) -> GalleryItem { let caption: NSAttributedString let credit: NSAttributedString @@ -129,7 +129,7 @@ class InstantPageGalleryController: ViewController { return self.displayNode as! GalleryControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let webPage: TelegramMediaWebpage private let message: Message? private var presentationData: PresentationData @@ -166,7 +166,7 @@ class InstantPageGalleryController: ViewController { private var innerOpenUrl: (InstantPageUrlItem) -> Void private var openUrlOptions: (InstantPageUrlItem) -> Void - init(context: AccountContext, webPage: TelegramMediaWebpage, message: Message? = nil, entries: [InstantPageGalleryEntry], centralIndex: Int, fromPlayingVideo: Bool = false, landscape: Bool = false, timecode: Double? = nil, replaceRootController: @escaping (ViewController, ValuePromise?) -> Void, baseNavigationController: NavigationController?) { + init(context: AccountContextImpl, webPage: TelegramMediaWebpage, message: Message? = nil, entries: [InstantPageGalleryEntry], centralIndex: Int, fromPlayingVideo: Bool = false, landscape: Bool = false, timecode: Double? = nil, replaceRootController: @escaping (ViewController, ValuePromise?) -> Void, baseNavigationController: NavigationController?) { self.context = context self.webPage = webPage self.message = message diff --git a/submodules/TelegramUI/TelegramUI/InstantPageGalleryFooterContentNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageGalleryFooterContentNode.swift index 6ae2224d43..f91f7f9359 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageGalleryFooterContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageGalleryFooterContentNode.swift @@ -7,13 +7,14 @@ import TelegramCore import SwiftSignalKit import Photos import TelegramPresentationData +import TextFormat private let actionImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionAction"), color: .white) private let textFont = Font.regular(16.0) final class InstantPageGalleryFooterContentNode: GalleryFooterContentNode { - private let context: AccountContext + private let context: AccountContextImpl private var theme: PresentationTheme private var strings: PresentationStrings private var shareMedia: AnyMediaReference? @@ -26,7 +27,7 @@ final class InstantPageGalleryFooterContentNode: GalleryFooterContentNode { var openUrl: ((InstantPageUrlItem) -> Void)? var openUrlOptions: ((InstantPageUrlItem) -> Void)? - init(context: AccountContext, presentationData: PresentationData) { + init(context: AccountContextImpl, presentationData: PresentationData) { self.context = context self.theme = presentationData.theme self.strings = presentationData.strings @@ -43,19 +44,19 @@ final class InstantPageGalleryFooterContentNode: GalleryFooterContentNode { super.init() self.textNode.highlightAttributeAction = { attributes in - if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] { - return NSAttributedStringKey(rawValue: TelegramTextAttributes.URL) + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) } else { return nil } } self.textNode.tapAttributeAction = { [weak self] attributes in - if let strongSelf = self, let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? InstantPageUrlItem { + if let strongSelf = self, let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? InstantPageUrlItem { strongSelf.openUrl?(url) } } self.textNode.longTapAttributeAction = { [weak self] attributes in - if let strongSelf = self, let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? InstantPageUrlItem { + if let strongSelf = self, let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? InstantPageUrlItem { strongSelf.openUrlOptions?(url) } } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageImageItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageImageItem.swift index 07ae7288f1..e113f60084 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageImageItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageImageItem.swift @@ -42,7 +42,7 @@ final class InstantPageImageItem: InstantPageItem { self.fit = fit } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return InstantPageImageNode(context: context, theme: theme, webPage: self.webPage, media: self.media, attributes: self.attributes, interactive: self.interactive, roundCorners: self.roundCorners, fit: self.fit, openMedia: openMedia, longPressMedia: longPressMedia) } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageImageNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageImageNode.swift index b553633486..180a4944a4 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageImageNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageImageNode.swift @@ -13,7 +13,7 @@ private struct FetchControls { } final class InstantPageImageNode: ASDisplayNode, InstantPageNode { - private let context: AccountContext + private let context: AccountContextImpl private let webPage: TelegramMediaWebpage private var theme: InstantPageTheme let media: InstantPageMedia @@ -39,7 +39,7 @@ final class InstantPageImageNode: ASDisplayNode, InstantPageNode { private var themeUpdated: Bool = false - init(context: AccountContext, theme: InstantPageTheme, webPage: TelegramMediaWebpage, media: InstantPageMedia, attributes: [InstantPageImageAttribute], interactive: Bool, roundCorners: Bool, fit: Bool, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void) { + init(context: AccountContextImpl, theme: InstantPageTheme, webPage: TelegramMediaWebpage, media: InstantPageMedia, attributes: [InstantPageImageAttribute], interactive: Bool, roundCorners: Bool, fit: Bool, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void) { self.context = context self.theme = theme self.webPage = webPage diff --git a/submodules/TelegramUI/TelegramUI/InstantPageItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageItem.swift index 8f6266aa20..f0c8fb4ad9 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageItem.swift @@ -13,7 +13,7 @@ protocol InstantPageItem { func matchesAnchor(_ anchor: String) -> Bool func drawInTile(context: CGContext) - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? func matchesNode(_ node: InstantPageNode) -> Bool func linkSelectionRects(at point: CGPoint) -> [CGRect] diff --git a/submodules/TelegramUI/TelegramUI/InstantPagePeerReferenceItem.swift b/submodules/TelegramUI/TelegramUI/InstantPagePeerReferenceItem.swift index 0da2123e97..6b89efa3d2 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPagePeerReferenceItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPagePeerReferenceItem.swift @@ -24,7 +24,7 @@ final class InstantPagePeerReferenceItem: InstantPageItem { self.rtl = rtl } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return InstantPagePeerReferenceNode(context: context, strings: strings, theme: theme, initialPeer: self.initialPeer, safeInset: self.safeInset, transparent: self.transparent, rtl: self.rtl, openPeer: openPeer) } diff --git a/submodules/TelegramUI/TelegramUI/InstantPagePeerReferenceNode.swift b/submodules/TelegramUI/TelegramUI/InstantPagePeerReferenceNode.swift index b8638410de..324610758d 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPagePeerReferenceNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPagePeerReferenceNode.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import AsyncDisplayKit import Display import TelegramPresentationData +import ActivityIndicator private enum JoinState: Equatable { case none @@ -44,7 +45,7 @@ private enum JoinState: Equatable { } final class InstantPagePeerReferenceNode: ASDisplayNode, InstantPageNode { - private let context: AccountContext + private let context: AccountContextImpl let safeInset: CGFloat private let transparent: Bool private let rtl: Bool @@ -65,7 +66,7 @@ final class InstantPagePeerReferenceNode: ASDisplayNode, InstantPageNode { private let joinDisposable = MetaDisposable() private var joinState: JoinState = .none - init(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, initialPeer: Peer, safeInset: CGFloat, transparent: Bool, rtl: Bool, openPeer: @escaping (PeerId) -> Void) { + init(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, initialPeer: Peer, safeInset: CGFloat, transparent: Bool, rtl: Bool, openPeer: @escaping (PeerId) -> Void) { self.context = context self.strings = strings self.theme = theme diff --git a/submodules/TelegramUI/TelegramUI/InstantPagePlayableVideoItem.swift b/submodules/TelegramUI/TelegramUI/InstantPagePlayableVideoItem.swift index 6327c3bbc6..61ba4234ca 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPagePlayableVideoItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPagePlayableVideoItem.swift @@ -26,7 +26,7 @@ final class InstantPagePlayableVideoItem: InstantPageItem { self.interactive = interactive } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return InstantPagePlayableVideoNode(context: context, webPage: self.webPage, theme: theme, media: self.media, interactive: self.interactive, openMedia: openMedia) } diff --git a/submodules/TelegramUI/TelegramUI/InstantPagePlayableVideoNode.swift b/submodules/TelegramUI/TelegramUI/InstantPagePlayableVideoNode.swift index 2bcee6071d..8b156133f0 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPagePlayableVideoNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPagePlayableVideoNode.swift @@ -13,7 +13,7 @@ private struct FetchControls { } final class InstantPagePlayableVideoNode: ASDisplayNode, InstantPageNode { - private let context: AccountContext + private let context: AccountContextImpl let media: InstantPageMedia private let interactive: Bool private let openMedia: (InstantPageMedia) -> Void @@ -30,7 +30,7 @@ final class InstantPagePlayableVideoNode: ASDisplayNode, InstantPageNode { private var localIsVisible = false - init(context: AccountContext, webPage: TelegramMediaWebpage, theme: InstantPageTheme, media: InstantPageMedia, interactive: Bool, openMedia: @escaping (InstantPageMedia) -> Void) { + init(context: AccountContextImpl, webPage: TelegramMediaWebpage, theme: InstantPageTheme, media: InstantPageMedia, interactive: Bool, openMedia: @escaping (InstantPageMedia) -> Void) { self.context = context self.media = media self.interactive = interactive diff --git a/submodules/TelegramUI/TelegramUI/InstantPageReferenceController.swift b/submodules/TelegramUI/TelegramUI/InstantPageReferenceController.swift index 2b621f3da2..7cf5480fde 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageReferenceController.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageReferenceController.swift @@ -13,7 +13,7 @@ final class InstantPageReferenceController: ViewController { private var animatedIn = false - private let context: AccountContext + private let context: AccountContextImpl private let theme: InstantPageTheme private let webPage: TelegramMediaWebpage private let anchorText: NSAttributedString @@ -21,7 +21,7 @@ final class InstantPageReferenceController: ViewController { private let openUrlIn: (InstantPageUrlItem) -> Void private let present: (ViewController, Any?) -> Void - init(context: AccountContext, theme: InstantPageTheme, webPage: TelegramMediaWebpage, anchorText: NSAttributedString, openUrl: @escaping (InstantPageUrlItem) -> Void, openUrlIn: @escaping (InstantPageUrlItem) -> Void, present: @escaping (ViewController, Any?) -> Void) { + init(context: AccountContextImpl, theme: InstantPageTheme, webPage: TelegramMediaWebpage, anchorText: NSAttributedString, openUrl: @escaping (InstantPageUrlItem) -> Void, openUrlIn: @escaping (InstantPageUrlItem) -> Void, present: @escaping (ViewController, Any?) -> Void) { self.context = context self.theme = theme self.webPage = webPage diff --git a/submodules/TelegramUI/TelegramUI/InstantPageReferenceControllerNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageReferenceControllerNode.swift index f297d34ca0..53b3c63dc4 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageReferenceControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageReferenceControllerNode.swift @@ -8,7 +8,7 @@ import SafariServices import TelegramPresentationData class InstantPageReferenceControllerNode: ViewControllerTracingNode, UIScrollViewDelegate { - private let context: AccountContext + private let context: AccountContextImpl private let theme: InstantPageTheme private var presentationData: PresentationData private let webPage: TelegramMediaWebpage @@ -34,7 +34,7 @@ class InstantPageReferenceControllerNode: ViewControllerTracingNode, UIScrollVie var dismiss: (() -> Void)? var close: (() -> Void)? - init(context: AccountContext, theme: InstantPageTheme, webPage: TelegramMediaWebpage, anchorText: NSAttributedString, openUrl: @escaping (InstantPageUrlItem) -> Void, openUrlIn: @escaping (InstantPageUrlItem) -> Void, present: @escaping (ViewController, Any?) -> Void) { + init(context: AccountContextImpl, theme: InstantPageTheme, webPage: TelegramMediaWebpage, anchorText: NSAttributedString, openUrl: @escaping (InstantPageUrlItem) -> Void, openUrlIn: @escaping (InstantPageUrlItem) -> Void, present: @escaping (ViewController, Any?) -> Void) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.theme = theme diff --git a/submodules/TelegramUI/TelegramUI/InstantPageSettingsItemNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageSettingsItemNode.swift index 970ac7013d..0397eec304 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageSettingsItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageSettingsItemNode.swift @@ -50,7 +50,7 @@ class InstantPageSettingsItemNode: ASDisplayNode { highlightButtonNode.highligthedChanged = { [weak self] highlighted in if let strongSelf = self, let highlightedBackgroundNode = strongSelf.highlightedBackgroundNode { if highlighted { - strongSelf.supernode?.view.bringSubview(toFront: strongSelf.view) + strongSelf.supernode?.view.bringSubviewToFront(strongSelf.view) highlightedBackgroundNode.layer.removeAnimation(forKey: "opacity") highlightedBackgroundNode.alpha = 1.0 } else { diff --git a/submodules/TelegramUI/TelegramUI/InstantPageShapeItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageShapeItem.swift index 521a97b162..f23715b788 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageShapeItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageShapeItem.swift @@ -59,7 +59,7 @@ final class InstantPageShapeItem: InstantPageItem { return false } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return nil } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageSlideshowItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageSlideshowItem.swift index 93f07a1b10..85de36b564 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageSlideshowItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageSlideshowItem.swift @@ -18,7 +18,7 @@ final class InstantPageSlideshowItem: InstantPageItem { self.medias = medias } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return InstantPageSlideshowNode(context: context, theme: theme, webPage: webPage, medias: self.medias, openMedia: openMedia, longPressMedia: longPressMedia) } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageSlideshowItemNode.swift b/submodules/TelegramUI/TelegramUI/InstantPageSlideshowItemNode.swift index 441ae8391e..79f511b4fd 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageSlideshowItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageSlideshowItemNode.swift @@ -61,7 +61,7 @@ private final class InstantPageSlideshowItemNode: ASDisplayNode { } private final class InstantPageSlideshowPagerNode: ASDisplayNode, UIScrollViewDelegate { - private let context: AccountContext + private let context: AccountContextImpl private let theme: InstantPageTheme private let webPage: TelegramMediaWebpage private let openMedia: (InstantPageMedia) -> Void @@ -95,7 +95,7 @@ private final class InstantPageSlideshowPagerNode: ASDisplayNode, UIScrollViewDe } } - init(context: AccountContext, theme: InstantPageTheme, webPage: TelegramMediaWebpage, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, pageGap: CGFloat = 0.0) { + init(context: AccountContextImpl, theme: InstantPageTheme, webPage: TelegramMediaWebpage, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, pageGap: CGFloat = 0.0) { self.context = context self.theme = theme self.webPage = webPage @@ -377,7 +377,7 @@ final class InstantPageSlideshowNode: ASDisplayNode, InstantPageNode { private let pagerNode: InstantPageSlideshowPagerNode private let pageControlNode: PageControlNode - init(context: AccountContext, theme: InstantPageTheme, webPage: TelegramMediaWebpage, medias: [InstantPageMedia], openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void) { + init(context: AccountContextImpl, theme: InstantPageTheme, webPage: TelegramMediaWebpage, medias: [InstantPageMedia], openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void) { self.medias = medias self.pagerNode = InstantPageSlideshowPagerNode(context: context, theme: theme, webPage: webPage, openMedia: openMedia, longPressMedia: longPressMedia) diff --git a/submodules/TelegramUI/TelegramUI/InstantPageTableItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageTableItem.swift index edb73dd1d0..77c4b1e110 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageTableItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageTableItem.swift @@ -93,7 +93,7 @@ private struct InstantPageTableCellItem { } } -private let tableCellInsets = UIEdgeInsetsMake(14.0, 12.0, 14.0, 12.0) +private let tableCellInsets = UIEdgeInsets(top: 14.0, left: 12.0, bottom: 14.0, right: 12.0) private let tableBorderWidth: CGFloat = 1.0 private let tableCornerRadius: CGFloat = 5.0 @@ -197,7 +197,7 @@ final class InstantPageTableItem: InstantPageScrollableItem { return false } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { var additionalNodes: [InstantPageNode] = [] for cell in self.cells { for item in cell.additionalItems { diff --git a/submodules/TelegramUI/TelegramUI/InstantPageTextItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageTextItem.swift index 048d3732e9..9602f03928 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageTextItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageTextItem.swift @@ -5,6 +5,7 @@ import Display import Postbox import AsyncDisplayKit import TelegramPresentationData +import TextFormat final class InstantPageUrlItem: Equatable { let url: String @@ -167,7 +168,7 @@ final class InstantPageTextItem: InstantPageItem { context.restoreGState() } - private func attributesAtPoint(_ point: CGPoint) -> (Int, [NSAttributedStringKey: Any])? { + private func attributesAtPoint(_ point: CGPoint) -> (Int, [NSAttributedString.Key: Any])? { let transformedPoint = CGPoint(x: point.x, y: point.y) let boundsWidth = self.frame.width for i in 0 ..< self.lines.count { @@ -194,7 +195,7 @@ final class InstantPageTextItem: InstantPageItem { return nil } - private func attributeRects(name: NSAttributedStringKey, at index: Int) -> [CGRect]? { + private func attributeRects(name: NSAttributedString.Key, at index: Int) -> [CGRect]? { var range = NSRange() let _ = self.attributedString.attribute(name, at: index, effectiveRange: &range) if range.length != 0 { @@ -228,8 +229,8 @@ final class InstantPageTextItem: InstantPageItem { func linkSelectionRects(at point: CGPoint) -> [CGRect] { if let (index, dict) = self.attributesAtPoint(point) { - if let _ = dict[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] { - if let rects = self.attributeRects(name: NSAttributedStringKey(rawValue: TelegramTextAttributes.URL), at: index) { + if let _ = dict[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { + if let rects = self.attributeRects(name: NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), at: index) { return rects.compactMap { rect in if rect.width > 5.0 { return rect.insetBy(dx: 0.0, dy: -3.0) @@ -245,7 +246,7 @@ final class InstantPageTextItem: InstantPageItem { func urlAttribute(at point: CGPoint) -> InstantPageUrlItem? { if let (_, dict) = self.attributesAtPoint(point) { - if let url = dict[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? InstantPageUrlItem { + if let url = dict[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? InstantPageUrlItem { return url } } @@ -329,7 +330,7 @@ final class InstantPageTextItem: InstantPageItem { return false } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return nil } @@ -378,7 +379,7 @@ final class InstantPageScrollableTextItem: InstantPageScrollableItem { context.restoreGState() } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (ASDisplayNode & InstantPageNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (ASDisplayNode & InstantPageNode)? { var additionalNodes: [InstantPageNode] = [] for item in additionalItems { if item.wantsNode { @@ -430,7 +431,7 @@ func attributedStringForRichText(_ text: RichText, styleStack: InstantPageTextSt case let .plain(string): var attributes = styleStack.textAttributes() if let url = url { - attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] = url + attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] = url } return NSAttributedString(string: string, attributes: attributes) case let .bold(text): @@ -523,7 +524,7 @@ func attributedStringForRichText(_ text: RichText, styleStack: InstantPageTextSt return d.pointee.width }) let delegate = CTRunDelegateCreate(&callbacks, extentBuffer) - let attrDictionaryDelegate = [(kCTRunDelegateAttributeName as NSAttributedStringKey): (delegate as Any), NSAttributedStringKey(rawValue: InstantPageMediaIdAttribute): id.id, NSAttributedStringKey(rawValue: InstantPageMediaDimensionsAttribute): dimensions] + let attrDictionaryDelegate = [(kCTRunDelegateAttributeName as NSAttributedString.Key): (delegate as Any), NSAttributedString.Key(rawValue: InstantPageMediaIdAttribute): id.id, NSAttributedString.Key(rawValue: InstantPageMediaDimensionsAttribute): dimensions] let mutableAttributedString = attributedStringForRichText(.plain(" "), styleStack: styleStack, url: url).mutableCopy() as! NSMutableAttributedString mutableAttributedString.addAttributes(attrDictionaryDelegate, range: NSMakeRange(0, mutableAttributedString.length)) return mutableAttributedString @@ -549,22 +550,22 @@ func layoutTextItemWithString(_ string: NSAttributedString, boundingWidth: CGFlo var lines: [InstantPageTextLine] = [] var imageItems: [InstantPageTextImageItem] = [] - var font = string.attribute(NSAttributedStringKey.font, at: 0, effectiveRange: nil) as? UIFont + var font = string.attribute(NSAttributedString.Key.font, at: 0, effectiveRange: nil) as? UIFont if font == nil { let range = NSMakeRange(0, string.length) string.enumerateAttributes(in: range, options: []) { attributes, range, _ in - if font == nil, let furtherFont = attributes[NSAttributedStringKey.font] as? UIFont { + if font == nil, let furtherFont = attributes[NSAttributedString.Key.font] as? UIFont { font = furtherFont } } } - let image = string.attribute(NSAttributedStringKey.init(rawValue: InstantPageMediaIdAttribute), at: 0, effectiveRange: nil) + let image = string.attribute(NSAttributedString.Key.init(rawValue: InstantPageMediaIdAttribute), at: 0, effectiveRange: nil) guard font != nil || image != nil else { return (nil, [], CGSize()) } var lineSpacingFactor: CGFloat = 1.12 - if let lineSpacingFactorAttribute = string.attribute(NSAttributedStringKey(rawValue: InstantPageLineSpacingFactorAttribute), at: 0, effectiveRange: nil) { + if let lineSpacingFactorAttribute = string.attribute(NSAttributedString.Key(rawValue: InstantPageLineSpacingFactorAttribute), at: 0, effectiveRange: nil) { lineSpacingFactor = CGFloat((lineSpacingFactorAttribute as! NSNumber).floatValue) } @@ -646,7 +647,7 @@ func layoutTextItemWithString(_ string: NSAttributedString, boundingWidth: CGFlo let cfRunRange = CTRunGetStringRange(run) let runRange = NSMakeRange(cfRunRange.location == kCFNotFound ? NSNotFound : cfRunRange.location, cfRunRange.length) string.enumerateAttributes(in: runRange, options: []) { attributes, range, _ in - if let id = attributes[NSAttributedStringKey.init(rawValue: InstantPageMediaIdAttribute)] as? Int64, let dimensions = attributes[NSAttributedStringKey.init(rawValue: InstantPageMediaDimensionsAttribute)] as? CGSize { + if let id = attributes[NSAttributedString.Key.init(rawValue: InstantPageMediaIdAttribute)] as? Int64, let dimensions = attributes[NSAttributedString.Key.init(rawValue: InstantPageMediaDimensionsAttribute)] as? CGSize { var imageFrame = CGRect(origin: CGPoint(), size: dimensions) let xOffset = CTLineGetOffsetForStringIndex(line, CTRunGetStringRange(run).location, nil) @@ -684,17 +685,17 @@ func layoutTextItemWithString(_ string: NSAttributedString, boundingWidth: CGFlo var anchorItems: [InstantPageTextAnchorItem] = [] string.enumerateAttributes(in: lineRange, options: []) { attributes, range, _ in - if let _ = attributes[NSAttributedStringKey.strikethroughStyle] { + if let _ = attributes[NSAttributedString.Key.strikethroughStyle] { let lowerX = floor(CTLineGetOffsetForStringIndex(line, range.location, nil)) let upperX = ceil(CTLineGetOffsetForStringIndex(line, range.location + range.length, nil)) let x = lowerX < upperX ? lowerX : upperX strikethroughItems.append(InstantPageTextStrikethroughItem(frame: CGRect(x: workingLineOrigin.x + x, y: workingLineOrigin.y, width: abs(upperX - lowerX), height: fontLineHeight))) } - if let color = attributes[NSAttributedStringKey.init(rawValue: InstantPageMarkerColorAttribute)] as? UIColor { + if let color = attributes[NSAttributedString.Key.init(rawValue: InstantPageMarkerColorAttribute)] as? UIColor { var lineHeight = fontLineHeight var delta: CGFloat = 0.0 - if let offset = attributes[NSAttributedStringKey.baselineOffset] as? CGFloat { + if let offset = attributes[NSAttributedString.Key.baselineOffset] as? CGFloat { lineHeight = floorToScreenPixels(lineHeight * 0.85) delta = offset * 0.6 } @@ -703,7 +704,7 @@ func layoutTextItemWithString(_ string: NSAttributedString, boundingWidth: CGFlo let x = lowerX < upperX ? lowerX : upperX markedItems.append(InstantPageTextMarkedItem(frame: CGRect(x: workingLineOrigin.x + x, y: workingLineOrigin.y + delta, width: abs(upperX - lowerX), height: lineHeight), color: color)) } - if let item = attributes[NSAttributedStringKey.init(rawValue: InstantPageAnchorAttribute)] as? Dictionary, let name = item["name"] as? String, let empty = item["empty"] as? Bool { + if let item = attributes[NSAttributedString.Key.init(rawValue: InstantPageAnchorAttribute)] as? Dictionary, let name = item["name"] as? String, let empty = item["empty"] as? Bool { anchorItems.append(InstantPageTextAnchorItem(name: name, anchorText: item["text"] as? NSAttributedString, empty: empty)) } } diff --git a/submodules/TelegramUI/TelegramUI/InstantPageTextStyleStack.swift b/submodules/TelegramUI/TelegramUI/InstantPageTextStyleStack.swift index d1889d267a..335b66684f 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageTextStyleStack.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageTextStyleStack.swift @@ -42,7 +42,7 @@ final class InstantPageTextStyleStack { } } - func textAttributes() -> [NSAttributedStringKey: Any] { + func textAttributes() -> [NSAttributedString.Key: Any] { var fontSize: CGFloat? var fontSerif: Bool? var fontFixed: Bool? @@ -138,7 +138,7 @@ final class InstantPageTextStyleStack { } } - var attributes: [NSAttributedStringKey: Any] = [:] + var attributes: [NSAttributedString.Key: Any] = [:] var parsedFontSize: CGFloat if let fontSize = fontSize { @@ -148,75 +148,75 @@ final class InstantPageTextStyleStack { } if let baselineOffset = baselineOffset { - attributes[NSAttributedStringKey.baselineOffset] = round(parsedFontSize * baselineOffset); + attributes[NSAttributedString.Key.baselineOffset] = round(parsedFontSize * baselineOffset); parsedFontSize = round(parsedFontSize * 0.85) } if (bold != nil && bold!) && (italic != nil && italic!) { if fontSerif != nil && fontSerif! { - attributes[NSAttributedStringKey.font] = UIFont(name: "Georgia-BoldItalic", size: parsedFontSize) + attributes[NSAttributedString.Key.font] = UIFont(name: "Georgia-BoldItalic", size: parsedFontSize) } else if fontFixed != nil && fontFixed! { - attributes[NSAttributedStringKey.font] = UIFont(name: "Menlo-BoldItalic", size: parsedFontSize) + attributes[NSAttributedString.Key.font] = UIFont(name: "Menlo-BoldItalic", size: parsedFontSize) } else { - attributes[NSAttributedStringKey.font] = Font.semiboldItalic(parsedFontSize) + attributes[NSAttributedString.Key.font] = Font.semiboldItalic(parsedFontSize) } } else if bold != nil && bold! { if fontSerif != nil && fontSerif! { - attributes[NSAttributedStringKey.font] = UIFont(name: "Georgia-Bold", size: parsedFontSize) + attributes[NSAttributedString.Key.font] = UIFont(name: "Georgia-Bold", size: parsedFontSize) } else if fontFixed != nil && fontFixed! { - attributes[NSAttributedStringKey.font] = UIFont(name: "Menlo-Bold", size: parsedFontSize) + attributes[NSAttributedString.Key.font] = UIFont(name: "Menlo-Bold", size: parsedFontSize) } else { - attributes[NSAttributedStringKey.font] = Font.bold(parsedFontSize) + attributes[NSAttributedString.Key.font] = Font.bold(parsedFontSize) } } else if italic != nil && italic! { if fontSerif != nil && fontSerif! { - attributes[NSAttributedStringKey.font] = UIFont(name: "Georgia-Italic", size: parsedFontSize) + attributes[NSAttributedString.Key.font] = UIFont(name: "Georgia-Italic", size: parsedFontSize) } else if fontFixed != nil && fontFixed! { - attributes[NSAttributedStringKey.font] = UIFont(name: "Menlo-Italic", size: parsedFontSize) + attributes[NSAttributedString.Key.font] = UIFont(name: "Menlo-Italic", size: parsedFontSize) } else { - attributes[NSAttributedStringKey.font] = Font.italic(parsedFontSize) + attributes[NSAttributedString.Key.font] = Font.italic(parsedFontSize) } } else { if fontSerif != nil && fontSerif! { - attributes[NSAttributedStringKey.font] = UIFont(name: "Georgia", size: parsedFontSize) + attributes[NSAttributedString.Key.font] = UIFont(name: "Georgia", size: parsedFontSize) } else if fontFixed != nil && fontFixed! { - attributes[NSAttributedStringKey.font] = UIFont(name: "Menlo", size: parsedFontSize) + attributes[NSAttributedString.Key.font] = UIFont(name: "Menlo", size: parsedFontSize) } else { - attributes[NSAttributedStringKey.font] = Font.regular(parsedFontSize) + attributes[NSAttributedString.Key.font] = Font.regular(parsedFontSize) } } if strikethrough != nil && strikethrough! { - attributes[NSAttributedStringKey.strikethroughStyle] = (NSUnderlineStyle.styleSingle.rawValue | NSUnderlineStyle.patternSolid.rawValue) as NSNumber + attributes[NSAttributedString.Key.strikethroughStyle] = NSUnderlineStyle.single.rawValue as NSNumber } if underline != nil && underline! { - attributes[NSAttributedStringKey.underlineStyle] = NSUnderlineStyle.styleSingle.rawValue as NSNumber + attributes[NSAttributedString.Key.underlineStyle] = NSUnderlineStyle.single.rawValue as NSNumber } if let link = link, let linkColor = linkColor { - attributes[NSAttributedStringKey.foregroundColor] = linkColor + attributes[NSAttributedString.Key.foregroundColor] = linkColor if link, let linkMarkerColor = linkMarkerColor { - attributes[NSAttributedStringKey(rawValue: InstantPageMarkerColorAttribute)] = linkMarkerColor + attributes[NSAttributedString.Key(rawValue: InstantPageMarkerColorAttribute)] = linkMarkerColor } } else { if let color = color { - attributes[NSAttributedStringKey.foregroundColor] = color + attributes[NSAttributedString.Key.foregroundColor] = color } else { - attributes[NSAttributedStringKey.foregroundColor] = UIColor.black + attributes[NSAttributedString.Key.foregroundColor] = UIColor.black } } if let lineSpacingFactor = lineSpacingFactor { - attributes[NSAttributedStringKey(rawValue: InstantPageLineSpacingFactorAttribute)] = lineSpacingFactor as NSNumber + attributes[NSAttributedString.Key(rawValue: InstantPageLineSpacingFactorAttribute)] = lineSpacingFactor as NSNumber } if marker != nil && marker!, let markerColor = markerColor { - attributes[NSAttributedStringKey(rawValue: InstantPageMarkerColorAttribute)] = markerColor + attributes[NSAttributedString.Key(rawValue: InstantPageMarkerColorAttribute)] = markerColor } if let anchor = anchor { - attributes[NSAttributedStringKey(rawValue: InstantPageAnchorAttribute)] = anchor + attributes[NSAttributedString.Key(rawValue: InstantPageAnchorAttribute)] = anchor } return attributes diff --git a/submodules/TelegramUI/TelegramUI/InstantPageWebEmbedItem.swift b/submodules/TelegramUI/TelegramUI/InstantPageWebEmbedItem.swift index c528c15b14..c0e51dbcb9 100644 --- a/submodules/TelegramUI/TelegramUI/InstantPageWebEmbedItem.swift +++ b/submodules/TelegramUI/TelegramUI/InstantPageWebEmbedItem.swift @@ -22,7 +22,7 @@ final class InstantPageWebEmbedItem: InstantPageItem { self.enableScrolling = enableScrolling } - func node(context: AccountContext, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { + func node(context: AccountContextImpl, strings: PresentationStrings, theme: InstantPageTheme, openMedia: @escaping (InstantPageMedia) -> Void, longPressMedia: @escaping (InstantPageMedia) -> Void, openPeer: @escaping (PeerId) -> Void, openUrl: @escaping (InstantPageUrlItem) -> Void, updateWebEmbedHeight: @escaping (CGFloat) -> Void, updateDetailsExpanded: @escaping (Bool) -> Void, currentExpandedDetails: [Int : Bool]?) -> (InstantPageNode & ASDisplayNode)? { return InstantPageWebEmbedNode(frame: self.frame, url: self.url, html: self.html, enableScrolling: self.enableScrolling, updateWebEmbedHeight: updateWebEmbedHeight) } diff --git a/submodules/TelegramUI/TelegramUI/InstantVideoRadialStatusNode.swift b/submodules/TelegramUI/TelegramUI/InstantVideoRadialStatusNode.swift index 293bb32b7f..fdf26c0233 100644 --- a/submodules/TelegramUI/TelegramUI/InstantVideoRadialStatusNode.swift +++ b/submodules/TelegramUI/TelegramUI/InstantVideoRadialStatusNode.swift @@ -134,7 +134,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode { }) as? POPAnimatableProperty animation.fromValue = progress as NSNumber animation.toValue = 1.0 as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = max(0.0, duration - timestamp) / baseRate animation.beginTime = statusValue.generationTimestamp self.pop_add(animation, forKey: "progress") diff --git a/submodules/TelegramUI/TelegramUI/InviteContactsController.swift b/submodules/TelegramUI/TelegramUI/InviteContactsController.swift index a97a23d565..c8e476c4e9 100644 --- a/submodules/TelegramUI/TelegramUI/InviteContactsController.swift +++ b/submodules/TelegramUI/TelegramUI/InviteContactsController.swift @@ -9,7 +9,7 @@ import MessageUI import TelegramPresentationData public class InviteContactsController: ViewController, MFMessageComposeViewControllerDelegate, UINavigationControllerDelegate { - private let context: AccountContext + private let context: AccountContextImpl private var contactsNode: InviteContactsControllerNode { return self.displayNode as! InviteContactsControllerNode @@ -27,7 +27,7 @@ public class InviteContactsController: ViewController, MFMessageComposeViewContr private var searchContentNode: NavigationBarSearchContentNode? - public init(context: AccountContext) { + public init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/InviteContactsControllerNode.swift b/submodules/TelegramUI/TelegramUI/InviteContactsControllerNode.swift index d674b85775..ddce79f55e 100644 --- a/submodules/TelegramUI/TelegramUI/InviteContactsControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/InviteContactsControllerNode.swift @@ -7,6 +7,8 @@ import TelegramCore import SwiftSignalKit import TelegramPresentationData import TelegramUIPreferences +import MergeLists +import ActivityIndicator private enum InviteContactsEntryId: Hashable { case option(index: Int) @@ -215,7 +217,7 @@ final class InviteContactsControllerNode: ASDisplayNode { let listNode: ListView private var activityIndicator: ActivityIndicator? - private let context: AccountContext + private let context: AccountContextImpl private var searchDisplayController: SearchDisplayController? private var validLayout: (ContainerViewLayout, CGFloat, CGFloat)? @@ -271,7 +273,7 @@ final class InviteContactsControllerNode: ASDisplayNode { private let currentContactIds = Atomic<[String]>(value: []) - init(context: AccountContext) { + init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/ItemListAddressItem.swift b/submodules/TelegramUI/TelegramUI/ItemListAddressItem.swift index c5eaa57a47..f6dc8c6087 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListAddressItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListAddressItem.swift @@ -4,6 +4,9 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI +import AccountContext +import TextFormat final class ItemListAddressItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/ItemListAvatarAndNameItem.swift b/submodules/TelegramUI/TelegramUI/ItemListAvatarAndNameItem.swift index ecfc4dacee..898e94270e 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListAvatarAndNameItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListAvatarAndNameItem.swift @@ -6,6 +6,8 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import ItemListUI +import ActivityIndicator private let updatingAvatarOverlayImage = generateFilledCircleImage(diameter: 66.0, color: UIColor(white: 0.0, alpha: 0.4), backgroundColor: nil) diff --git a/submodules/TelegramUI/TelegramUI/ItemListCallListItem.swift b/submodules/TelegramUI/TelegramUI/ItemListCallListItem.swift index 285eef3010..60fae63e8b 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListCallListItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListCallListItem.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI class ItemListCallListItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/ItemListInfoItem.swift b/submodules/TelegramUI/TelegramUI/ItemListInfoItem.swift index d8bf3a574e..9d6bba8c17 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListInfoItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListInfoItem.swift @@ -4,6 +4,8 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI +import TextFormat enum InfoListItemText { case plain(String) @@ -160,10 +162,10 @@ class InfoItemNode: ListViewItemNode { self.textNode.isUserInteractionEnabled = false self.activateArea = AccessibilityAreaNode() - self.activateArea.accessibilityTraits = UIAccessibilityTraitStaticText + self.activateArea.accessibilityTraits = .staticText self.closeButton = HighlightableButtonNode() - self.closeButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0) + self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0) self.closeButton.displaysAsynchronously = false super.init(layerBacked: false, dynamicBounce: false) @@ -361,7 +363,7 @@ class InfoItemNode: ListViewItemNode { let titleFrame = self.textNode.frame if let item = self.item, titleFrame.contains(location) { if let (_, attributes) = self.textNode.attributesAtPoint(CGPoint(x: location.x - titleFrame.minX, y: location.y - titleFrame.minY)) { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { item.linkAction?(.tap(url)) } } @@ -389,7 +391,7 @@ class InfoItemNode: ListViewItemNode { TelegramTextAttributes.Hashtag ] for name in possibleNames { - if let _ = attributes[NSAttributedStringKey(rawValue: name)] { + if let _ = attributes[NSAttributedString.Key(rawValue: name)] { rects = self.textNode.attributeRects(name: name, at: index) break } diff --git a/submodules/TelegramUI/TelegramUI/ItemListPeerActionItem.swift b/submodules/TelegramUI/TelegramUI/ItemListPeerActionItem.swift index 8578b41a5e..eac6c36800 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListPeerActionItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListPeerActionItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI enum ItemListPeerActionItemHeight { case generic diff --git a/submodules/TelegramUI/TelegramUI/ItemListPeerItem.swift b/submodules/TelegramUI/TelegramUI/ItemListPeerItem.swift index 0d9130d3c4..fa9935dd02 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListPeerItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListPeerItem.swift @@ -7,6 +7,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI struct ItemListPeerItemEditing: Equatable { let editable: Bool diff --git a/submodules/TelegramUI/TelegramUI/ItemListPlaceholderItem.swift b/submodules/TelegramUI/TelegramUI/ItemListPlaceholderItem.swift index 9f8ebed1b0..4571968f81 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListPlaceholderItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListPlaceholderItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI class ItemListPlaceholderItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/ItemListRecentSessionItem.swift b/submodules/TelegramUI/TelegramUI/ItemListRecentSessionItem.swift index 213c6cbc76..1973d79f90 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListRecentSessionItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListRecentSessionItem.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI struct ItemListRecentSessionItemEditing: Equatable { let editable: Bool diff --git a/submodules/TelegramUI/TelegramUI/ItemListSecretChatKeyItem.swift b/submodules/TelegramUI/TelegramUI/ItemListSecretChatKeyItem.swift index ff37b41d8b..ad91fa855c 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListSecretChatKeyItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListSecretChatKeyItem.swift @@ -5,6 +5,7 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ItemListUI class ItemListSecretChatKeyItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/ItemListSectionHeaderItem.swift b/submodules/TelegramUI/TelegramUI/ItemListSectionHeaderItem.swift index 2c729af3c2..ef42c6da4d 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListSectionHeaderItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListSectionHeaderItem.swift @@ -4,6 +4,8 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI +import ActivityIndicator enum ItemListSectionHeaderAccessoryTextColor { case generic @@ -94,7 +96,7 @@ class ItemListSectionHeaderItemNode: ListViewItemNode { self.accessoryTextNode.contentsScale = UIScreen.main.scale self.activateArea = AccessibilityAreaNode() - self.activateArea.accessibilityTraits = UIAccessibilityTraitStaticText | UIAccessibilityTraitHeader + self.activateArea.accessibilityTraits = [.staticText, .header] super.init(layerBacked: false, dynamicBounce: false) diff --git a/submodules/TelegramUI/TelegramUI/ItemListSingleLineInputItem.swift b/submodules/TelegramUI/TelegramUI/ItemListSingleLineInputItem.swift index b897f85320..a834f03637 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListSingleLineInputItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListSingleLineInputItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI enum ItemListSingleLineInputItemType: Equatable { case regular(capitalization: Bool, autocorrection: Bool) @@ -148,7 +149,7 @@ class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDelegate, It override func didLoad() { super.didLoad() - self.textNode.textField.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(17.0)] + self.textNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(17.0)] self.textNode.textField.font = Font.regular(17.0) if let item = self.item { self.textNode.textField.textColor = item.theme.list.itemPrimaryTextColor @@ -183,8 +184,8 @@ class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDelegate, It } let titleString = NSMutableAttributedString(attributedString: item.title) - titleString.removeAttribute(NSAttributedStringKey.font, range: NSMakeRange(0, titleString.length)) - titleString.addAttributes([NSAttributedStringKey.font: Font.regular(17.0)], range: NSMakeRange(0, titleString.length)) + titleString.removeAttribute(NSAttributedString.Key.font, range: NSMakeRange(0, titleString.length)) + titleString.addAttributes([NSAttributedString.Key.font: Font.regular(17.0)], range: NSMakeRange(0, titleString.length)) let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleString, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - 32.0 - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) diff --git a/submodules/TelegramUI/TelegramUI/ItemListStickerPackItem.swift b/submodules/TelegramUI/TelegramUI/ItemListStickerPackItem.swift index ed64411a6b..c7cfa58cfb 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListStickerPackItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListStickerPackItem.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI struct ItemListStickerPackItemEditing: Equatable { let editable: Bool diff --git a/submodules/TelegramUI/TelegramUI/ItemListTextEmptyStateItem.swift b/submodules/TelegramUI/TelegramUI/ItemListTextEmptyStateItem.swift index bfe80bd9d0..d0a0bff5b1 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListTextEmptyStateItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListTextEmptyStateItem.swift @@ -2,6 +2,7 @@ import Foundation import UIKit import AsyncDisplayKit import Display +import ItemListUI final class ItemListTextEmptyStateItem: ItemListControllerEmptyStateItem { let text: String diff --git a/submodules/TelegramUI/TelegramUI/ItemListWebsiteItem.swift b/submodules/TelegramUI/TelegramUI/ItemListWebsiteItem.swift index c2174102be..2f4c5cfa20 100644 --- a/submodules/TelegramUI/TelegramUI/ItemListWebsiteItem.swift +++ b/submodules/TelegramUI/TelegramUI/ItemListWebsiteItem.swift @@ -7,6 +7,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI struct ItemListWebsiteItemEditing: Equatable { let editing: Bool diff --git a/submodules/TelegramUI/TelegramUI/JoinLinkPreviewController.swift b/submodules/TelegramUI/TelegramUI/JoinLinkPreviewController.swift index 6ff6b8c655..c5177d11a6 100644 --- a/submodules/TelegramUI/TelegramUI/JoinLinkPreviewController.swift +++ b/submodules/TelegramUI/TelegramUI/JoinLinkPreviewController.swift @@ -14,14 +14,14 @@ public final class JoinLinkPreviewController: ViewController { private var animatedIn = false - private let context: AccountContext + private let context: AccountContextImpl private let link: String private let navigateToPeer: (PeerId) -> Void private var presentationData: PresentationData private let disposable = MetaDisposable() - public init(context: AccountContext, link: String, navigateToPeer: @escaping (PeerId) -> Void) { + public init(context: AccountContextImpl, link: String, navigateToPeer: @escaping (PeerId) -> Void) { self.context = context self.link = link self.navigateToPeer = navigateToPeer diff --git a/submodules/TelegramUI/TelegramUI/JoinLinkPreviewControllerNode.swift b/submodules/TelegramUI/TelegramUI/JoinLinkPreviewControllerNode.swift index b2139000ea..fccbfbff3c 100644 --- a/submodules/TelegramUI/TelegramUI/JoinLinkPreviewControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/JoinLinkPreviewControllerNode.swift @@ -13,7 +13,7 @@ struct JoinLinkPreviewData { } final class JoinLinkPreviewControllerNode: ViewControllerTracingNode, UIScrollViewDelegate { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let requestLayout: (ContainedViewLayoutTransition) -> Void @@ -48,7 +48,7 @@ final class JoinLinkPreviewControllerNode: ViewControllerTracingNode, UIScrollVi private let disposable = MetaDisposable() - init(context: AccountContext, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void) { + init(context: AccountContextImpl, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -192,8 +192,8 @@ final class JoinLinkPreviewControllerNode: ViewControllerTracingNode, UIScrollVi self.contentContainerNode.insertSubnode(contentNode, at: 0) contentNode.alpha = 1.0 - let animation = contentNode.layer.makeAnimation(from: 0.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "opacity", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.35) - animation.fillMode = kCAFillModeBoth + let animation = contentNode.layer.makeAnimation(from: 0.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "opacity", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.35) + animation.fillMode = .both if !fastOut { animation.beginTime = CACurrentMediaTime() + 0.1 } diff --git a/submodules/TelegramUI/TelegramUI/JoinLinkPreviewPeerContentNode.swift b/submodules/TelegramUI/TelegramUI/JoinLinkPreviewPeerContentNode.swift index bb7c77f4c1..cb0fe62eba 100644 --- a/submodules/TelegramUI/TelegramUI/JoinLinkPreviewPeerContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/JoinLinkPreviewPeerContentNode.swift @@ -34,7 +34,7 @@ final class JoinLinkPreviewPeerContentNode: ASDisplayNode, ShareContentContainer private let peerNodes: [SelectablePeerNode] private let moreNode: MoreNode? - init(context: AccountContext, image: TelegramMediaImageRepresentation?, title: String, memberCount: Int32, members: [Peer], isGroup: Bool, theme: PresentationTheme, strings: PresentationStrings) { + init(context: AccountContextImpl, image: TelegramMediaImageRepresentation?, title: String, memberCount: Int32, members: [Peer], isGroup: Bool, theme: PresentationTheme, strings: PresentationStrings) { self.avatarNode = AvatarNode(font: avatarFont) self.titleNode = ASTextNode() self.countNode = ASTextNode() diff --git a/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewContentNode.swift b/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewContentNode.swift index 7ea90ec23f..78f5d8e6f7 100644 --- a/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewContentNode.swift @@ -5,6 +5,7 @@ import Display import Postbox import TelegramCore import TelegramPresentationData +import TextFormat final class LanguageLinkPreviewContentNode: ASDisplayNode, ShareContentContainerNode { private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)? @@ -12,7 +13,7 @@ final class LanguageLinkPreviewContentNode: ASDisplayNode, ShareContentContainer private let titleNode: ImmediateTextNode private let textNode: ImmediateTextNode - init(context: AccountContext, localizationInfo: LocalizationInfo, theme: PresentationTheme, strings: PresentationStrings, openTranslationUrl: @escaping (String) -> Void) { + init(context: AccountContextImpl, localizationInfo: LocalizationInfo, theme: PresentationTheme, strings: PresentationStrings, openTranslationUrl: @escaping (String) -> Void) { self.titleNode = ImmediateTextNode() self.titleNode.textAlignment = .center @@ -47,14 +48,14 @@ final class LanguageLinkPreviewContentNode: ASDisplayNode, ShareContentContainer self.textNode.attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: link, linkAttribute: { _ in nil }), textAlignment: .center) self.textNode.linkHighlightColor = theme.actionSheet.controlAccentColor.withAlphaComponent(0.5) self.textNode.highlightAttributeAction = { attributes in - if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] { - return NSAttributedStringKey(rawValue: TelegramTextAttributes.URL) + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) } else { return nil } } self.textNode.tapAttributeAction = { attributes in - if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] { + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { let url: String if localizationInfo.platformUrl.isEmpty { url = localizationInfo.platformUrl diff --git a/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewController.swift b/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewController.swift index da5709819e..0e351b2253 100644 --- a/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewController.swift +++ b/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewController.swift @@ -14,14 +14,14 @@ public final class LanguageLinkPreviewController: ViewController { private var animatedIn = false - private let context: AccountContext + private let context: AccountContextImpl private let identifier: String private var localizationInfo: LocalizationInfo? private var presentationData: PresentationData private let disposable = MetaDisposable() - public init(context: AccountContext, identifier: String) { + public init(context: AccountContextImpl, identifier: String) { self.context = context self.identifier = identifier diff --git a/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewControllerNode.swift b/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewControllerNode.swift index 9fcc8e9847..6b713fcb05 100644 --- a/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/LanguageLinkPreviewControllerNode.swift @@ -6,9 +6,10 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ActivityIndicator final class LanguageLinkPreviewControllerNode: ViewControllerTracingNode, UIScrollViewDelegate { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let requestLayout: (ContainedViewLayoutTransition) -> Void @@ -45,7 +46,7 @@ final class LanguageLinkPreviewControllerNode: ViewControllerTracingNode, UIScro private let disposable = MetaDisposable() - init(context: AccountContext, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, openUrl: @escaping (String) -> Void) { + init(context: AccountContextImpl, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, openUrl: @escaping (String) -> Void) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -194,8 +195,8 @@ final class LanguageLinkPreviewControllerNode: ViewControllerTracingNode, UIScro self.contentContainerNode.insertSubnode(contentNode, at: 0) contentNode.alpha = 1.0 - let animation = contentNode.layer.makeAnimation(from: 0.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "opacity", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.35) - animation.fillMode = kCAFillModeBoth + let animation = contentNode.layer.makeAnimation(from: 0.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "opacity", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.35) + animation.fillMode = .both if !fastOut { animation.beginTime = CACurrentMediaTime() + 0.1 } diff --git a/submodules/TelegramUI/TelegramUI/LanguageSuggestionController.swift b/submodules/TelegramUI/TelegramUI/LanguageSuggestionController.swift index f57f0a9572..62dc57cff7 100644 --- a/submodules/TelegramUI/TelegramUI/LanguageSuggestionController.swift +++ b/submodules/TelegramUI/TelegramUI/LanguageSuggestionController.swift @@ -5,6 +5,7 @@ import AsyncDisplayKit import Display import TelegramCore import TelegramPresentationData +import ActivityIndicator struct LanguageSuggestionControllerStrings { let ChooseLanguage: String @@ -323,7 +324,7 @@ private final class LanguageSuggestionAlertContentNode: AlertContentNode { } } -func languageSuggestionController(context: AccountContext, suggestedLocalization: SuggestedLocalizationInfo, currentLanguageCode: String, openSelection: @escaping () -> Void) -> AlertController? { +func languageSuggestionController(context: AccountContextImpl, suggestedLocalization: SuggestedLocalizationInfo, currentLanguageCode: String, openSelection: @escaping () -> Void) -> AlertController? { guard let localization = suggestedLocalization.availableLocalizations.filter({ $0.languageCode == suggestedLocalization.languageCode }).first else { return nil } diff --git a/submodules/TelegramUI/TelegramUI/LegacyAttachmentMenu.swift b/submodules/TelegramUI/TelegramUI/LegacyAttachmentMenu.swift index 1ed4712949..8414003f7c 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyAttachmentMenu.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyAttachmentMenu.swift @@ -8,7 +8,7 @@ import TelegramCore import TelegramPresentationData import DeviceAccess -func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions: MessageMediaEditingOptions?, saveEditedPhotos: Bool, allowGrouping: Bool, theme: PresentationTheme, strings: PresentationStrings, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void) -> TGMenuSheetController { +func legacyAttachmentMenu(context: AccountContextImpl, peer: Peer, editMediaOptions: MessageMediaEditingOptions?, saveEditedPhotos: Bool, allowGrouping: Bool, theme: PresentationTheme, strings: PresentationStrings, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void) -> TGMenuSheetController { let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat let controller = TGMenuSheetController(context: parentController.context, dark: false)! @@ -171,7 +171,7 @@ func legacyMenuPaletteFromTheme(_ theme: PresentationTheme) -> TGMenuSheetPallet return TGMenuSheetPallete(dark: theme.overallDarkAppearance, backgroundColor: sheetTheme.opaqueItemBackgroundColor, selectionColor: sheetTheme.opaqueItemHighlightedBackgroundColor, separatorColor: sheetTheme.opaqueItemSeparatorColor, accentColor: sheetTheme.controlAccentColor, destructiveColor: sheetTheme.destructiveActionTextColor, textColor: sheetTheme.primaryTextColor, secondaryTextColor: sheetTheme.secondaryTextColor, spinnerColor: sheetTheme.secondaryTextColor, badgeTextColor: sheetTheme.controlAccentColor, badgeImage: nil, cornersImage: generateStretchableFilledCircleImage(diameter: 11.0, color: nil, strokeColor: nil, strokeWidth: nil, backgroundColor: sheetTheme.opaqueItemBackgroundColor)) } -func presentLegacyPasteMenu(context: AccountContext, peer: Peer, saveEditedPhotos: Bool, allowGrouping: Bool, theme: PresentationTheme, strings: PresentationStrings, images: [UIImage], sendMessagesWithSignals: @escaping ([Any]?) -> Void, present: (ViewController, Any?) -> Void, initialLayout: ContainerViewLayout? = nil) -> ViewController { +func presentLegacyPasteMenu(context: AccountContextImpl, peer: Peer, saveEditedPhotos: Bool, allowGrouping: Bool, theme: PresentationTheme, strings: PresentationStrings, images: [UIImage], sendMessagesWithSignals: @escaping ([Any]?) -> Void, present: (ViewController, Any?) -> Void, initialLayout: ContainerViewLayout? = nil) -> ViewController { let legacyController = LegacyController(presentation: .custom, theme: theme, initialLayout: initialLayout) legacyController.statusBar.statusBarStyle = .Ignore legacyController.controllerLoaded = { [weak legacyController] in diff --git a/submodules/TelegramUI/TelegramUI/LegacyCamera.swift b/submodules/TelegramUI/TelegramUI/LegacyCamera.swift index 1983295f52..af50abc977 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyCamera.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyCamera.swift @@ -6,7 +6,7 @@ import TelegramCore import Postbox import SwiftSignalKit -func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAttachmentCameraView?, menuController: TGMenuSheetController?, parentController: ViewController, editingMedia: Bool, saveCapturedPhotos: Bool, mediaGrouping: Bool, initialCaption: String, sendMessagesWithSignals: @escaping ([Any]?) -> Void, recognizedQRCode: @escaping (String) -> Void = { _ in }) { +func presentedLegacyCamera(context: AccountContextImpl, peer: Peer, cameraView: TGAttachmentCameraView?, menuController: TGMenuSheetController?, parentController: ViewController, editingMedia: Bool, saveCapturedPhotos: Bool, mediaGrouping: Bool, initialCaption: String, sendMessagesWithSignals: @escaping ([Any]?) -> Void, recognizedQRCode: @escaping (String) -> Void = { _ in }) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme) legacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .portrait, compactSize: .portrait) @@ -153,7 +153,7 @@ func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAt parentController.present(legacyController, in: .window(.root)) } -func presentedLegacyShortcutCamera(context: AccountContext, saveCapturedMedia: Bool, saveEditedPhotos: Bool, mediaGrouping: Bool, parentController: ViewController) { +func presentedLegacyShortcutCamera(context: AccountContextImpl, saveCapturedMedia: Bool, saveEditedPhotos: Bool, mediaGrouping: Bool, parentController: ViewController) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme) legacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .portrait, compactSize: .portrait) diff --git a/submodules/TelegramUI/TelegramUI/LegacyControllerNode.swift b/submodules/TelegramUI/TelegramUI/LegacyControllerNode.swift index 9993bf64da..7017078654 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyControllerNode.swift @@ -38,7 +38,7 @@ final class LegacyControllerNode: ASDisplayNode { } func animateModalOut(completion: @escaping () -> Void) { - self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, additive: true, completion: { _ in + self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, completion: { _ in completion() }) } diff --git a/submodules/TelegramUI/TelegramUI/LegacyImagePicker.swift b/submodules/TelegramUI/TelegramUI/LegacyImagePicker.swift index ac7c3e4303..34a1b38046 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyImagePicker.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyImagePicker.swift @@ -36,7 +36,7 @@ func legacyImagePicker(theme: PresentationTheme, completion: @escaping (UIImage? }) let imagePickerController = TGLegacyCameraController(context: legacyController.context)! - imagePickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary + imagePickerController.sourceType = UIImagePickerController.SourceType.photoLibrary imagePickerController.completionDelegate = legacyController legacyController.bind(controller: imagePickerController) diff --git a/submodules/TelegramUI/TelegramUI/LegacyInstantVideoController.swift b/submodules/TelegramUI/TelegramUI/LegacyInstantVideoController.swift index ebcc264049..48ad746ebf 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyInstantVideoController.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyInstantVideoController.swift @@ -91,7 +91,7 @@ func legacyInputMicPalette(from theme: PresentationTheme) -> TGModernConversatio return TGModernConversationInputMicPallete(dark: theme.overallDarkAppearance, buttonColor: inputPanelTheme.actionControlFillColor, iconColor: inputPanelTheme.actionControlForegroundColor, backgroundColor: inputPanelTheme.panelBackgroundColor, borderColor: inputPanelTheme.panelSeparatorColor, lock: inputPanelTheme.panelControlAccentColor, textColor: inputPanelTheme.primaryTextColor, secondaryTextColor: inputPanelTheme.secondaryTextColor, recording: inputPanelTheme.mediaRecordingDotColor) } -func legacyInstantVideoController(theme: PresentationTheme, panelFrame: CGRect, context: AccountContext, peerId: PeerId, slowmodeState: ChatSlowmodeState?, send: @escaping (EnqueueMessage) -> Void, displaySlowmodeTooltip: @escaping (ASDisplayNode, CGRect) -> Void) -> InstantVideoController { +func legacyInstantVideoController(theme: PresentationTheme, panelFrame: CGRect, context: AccountContextImpl, peerId: PeerId, slowmodeState: ChatSlowmodeState?, send: @escaping (EnqueueMessage) -> Void, displaySlowmodeTooltip: @escaping (ASDisplayNode, CGRect) -> Void) -> InstantVideoController { let legacyController = InstantVideoController(presentation: .custom, theme: theme) legacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .all) legacyController.lockOrientation = true @@ -133,7 +133,7 @@ func legacyInstantVideoController(theme: PresentationTheme, panelFrame: CGRect, let resource = LocalFileMediaResource(fileId: arc4random64()) let thumbnailSize = finalDimensions.aspectFitted(CGSize(width: 320.0, height: 320.0)) let thumbnailImage = TGScaleImageToPixelSize(previewImage, thumbnailSize)! - if let thumbnailData = UIImageJPEGRepresentation(thumbnailImage, 0.4) { + if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { context.account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: thumbnailSize, resource: resource)) } diff --git a/submodules/TelegramUI/TelegramUI/LegacyLocationController.swift b/submodules/TelegramUI/TelegramUI/LegacyLocationController.swift index 2d72d868f4..f09f138bea 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyLocationController.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyLocationController.swift @@ -122,7 +122,7 @@ func legacyLocationPalette(from theme: PresentationTheme) -> TGLocationPallete { return TGLocationPallete(backgroundColor: listTheme.plainBackgroundColor, selectionColor: listTheme.itemHighlightedBackgroundColor, separatorColor: listTheme.itemPlainSeparatorColor, textColor: listTheme.itemPrimaryTextColor, secondaryTextColor: listTheme.itemSecondaryTextColor, accentColor: listTheme.itemAccentColor, destructiveColor: listTheme.itemDestructiveColor, locationColor: UIColor(rgb: 0x008df2), liveLocationColor: UIColor(rgb: 0xff6464), iconColor: searchTheme.backgroundColor, sectionHeaderBackgroundColor: theme.chatList.sectionHeaderFillColor, sectionHeaderTextColor: theme.chatList.sectionHeaderTextColor, searchBarPallete: TGSearchBarPallete(dark: theme.overallDarkAppearance, backgroundColor: searchTheme.backgroundColor, highContrastBackgroundColor: searchTheme.backgroundColor, textColor: searchTheme.inputTextColor, placeholderColor: searchTheme.inputPlaceholderTextColor, clearIcon: generateClearIcon(color: theme.rootController.navigationSearchBar.inputClearButtonColor), barBackgroundColor: searchTheme.backgroundColor, barSeparatorColor: searchTheme.separatorColor, plainBackgroundColor: searchTheme.backgroundColor, accentColor: searchTheme.accentColor, accentContrastColor: searchTheme.backgroundColor, menuBackgroundColor: searchTheme.backgroundColor, segmentedControlBackgroundImage: nil, segmentedControlSelectedImage: nil, segmentedControlHighlightedImage: nil, segmentedControlDividerImage: nil), avatarPlaceholder: nil) } -func legacyLocationController(message: Message?, mapMedia: TelegramMediaMap, context: AccountContext, isModal: Bool, openPeer: @escaping (Peer) -> Void, sendLiveLocation: @escaping (CLLocationCoordinate2D, Int32) -> Void, stopLiveLocation: @escaping () -> Void, openUrl: @escaping (String) -> Void) -> ViewController { +func legacyLocationController(message: Message?, mapMedia: TelegramMediaMap, context: AccountContextImpl, isModal: Bool, openPeer: @escaping (Peer) -> Void, sendLiveLocation: @escaping (CLLocationCoordinate2D, Int32) -> Void, stopLiveLocation: @escaping () -> Void, openUrl: @escaping (String) -> Void) -> ViewController { let legacyLocation = TGLocationMediaAttachment() legacyLocation.latitude = mapMedia.latitude legacyLocation.longitude = mapMedia.longitude diff --git a/submodules/TelegramUI/TelegramUI/LegacyLocationPicker.swift b/submodules/TelegramUI/TelegramUI/LegacyLocationPicker.swift index 09b725d7d1..2bd5bc898c 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyLocationPicker.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyLocationPicker.swift @@ -11,7 +11,7 @@ private func generateClearIcon(color: UIColor) -> UIImage? { return generateTintedImage(image: UIImage(bundleImageName: "Components/Search Bar/Clear"), color: color) } -func legacyLocationPickerController(context: AccountContext, selfPeer: Peer, peer: Peer, sendLocation: @escaping (CLLocationCoordinate2D, MapVenue?, String?) -> Void, sendLiveLocation: @escaping (CLLocationCoordinate2D, Int32) -> Void, theme: PresentationTheme, customLocationPicker: Bool = false, presentationCompleted: @escaping () -> Void = {}) -> ViewController { +func legacyLocationPickerController(context: AccountContextImpl, selfPeer: Peer, peer: Peer, sendLocation: @escaping (CLLocationCoordinate2D, MapVenue?, String?) -> Void, sendLiveLocation: @escaping (CLLocationCoordinate2D, Int32) -> Void, theme: PresentationTheme, customLocationPicker: Bool = false, presentationCompleted: @escaping () -> Void = {}) -> ViewController { let legacyController = LegacyController(presentation: .modal(animateIn: true), theme: theme) legacyController.presentationCompleted = { presentationCompleted() diff --git a/submodules/TelegramUI/TelegramUI/LegacyMediaPickers.swift b/submodules/TelegramUI/TelegramUI/LegacyMediaPickers.swift index 3b8a7f0b84..f2e9f0b587 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyMediaPickers.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyMediaPickers.swift @@ -14,7 +14,7 @@ func guessMimeTypeByFileExtension(_ ext: String) -> String { return TGMimeTypeMap.mimeType(forExtension: ext) ?? "application/binary" } -func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: String, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void) { +func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContextImpl, peer: Peer, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: String, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void) { let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat controller.captionsEnabled = captionsEnabled @@ -39,7 +39,7 @@ func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: controller.editingContext.setInitialCaption(initialCaption, entities: []) } -func legacyAssetPicker(context: AccountContext, presentationData: PresentationData, editingMedia: Bool, fileMode: Bool, peer: Peer?, saveEditedPhotos: Bool, allowGrouping: Bool, selectionLimit: Int) -> Signal<(LegacyComponentsContext) -> TGMediaAssetsController, Void> { +func legacyAssetPicker(context: AccountContextImpl, presentationData: PresentationData, editingMedia: Bool, fileMode: Bool, peer: Peer?, saveEditedPhotos: Bool, allowGrouping: Bool, selectionLimit: Int) -> Signal<(LegacyComponentsContext) -> TGMediaAssetsController, Void> { let isSecretChat = (peer?.id.namespace ?? 0) == Namespaces.Peer.SecretChat return Signal { subscriber in @@ -225,7 +225,7 @@ func legacyEnqueueGifMessage(account: Account, data: Data) -> Signal Signa let resource = LocalFileMediaResource(fileId: arc4random64()) let thumbnailSize = thumbnail.size.aspectFitted(CGSize(width: 320.0, height: 320.0)) let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)! - if let thumbnailData = UIImageJPEGRepresentation(thumbnailImage, 0.4) { + if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) representations.append(TelegramMediaImageRepresentation(dimensions: thumbnailSize, resource: resource)) } @@ -373,7 +373,7 @@ func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -> Signa let resource = LocalFileMediaResource(fileId: arc4random64()) let thumbnailSize = finalDimensions.aspectFitted(CGSize(width: 320.0, height: 320.0)) let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)! - if let thumbnailData = UIImageJPEGRepresentation(thumbnailImage, 0.4) { + if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: thumbnailSize, resource: resource)) } diff --git a/submodules/TelegramUI/TelegramUI/LegacySecureIdAttachmentMenu.swift b/submodules/TelegramUI/TelegramUI/LegacySecureIdAttachmentMenu.swift index 17d89a1883..c8ac6bb7fa 100644 --- a/submodules/TelegramUI/TelegramUI/LegacySecureIdAttachmentMenu.swift +++ b/submodules/TelegramUI/TelegramUI/LegacySecureIdAttachmentMenu.swift @@ -26,7 +26,7 @@ struct SecureIdRecognizedDocumentData { let expiryDate: Date? } -func presentLegacySecureIdAttachmentMenu(context: AccountContext, present: @escaping (ViewController) -> Void, validLayout: ContainerViewLayout, type: SecureIdAttachmentMenuType, recognizeDocumentData: Bool, completion: @escaping ([TelegramMediaResource], SecureIdRecognizedDocumentData?) -> Void) { +func presentLegacySecureIdAttachmentMenu(context: AccountContextImpl, present: @escaping (ViewController) -> Void, validLayout: ContainerViewLayout, type: SecureIdAttachmentMenuType, recognizeDocumentData: Bool, completion: @escaping ([TelegramMediaResource], SecureIdRecognizedDocumentData?) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme, initialLayout: validLayout) legacyController.statusBar.statusBarStyle = .Ignore diff --git a/submodules/TelegramUI/TelegramUI/LegacyWallpaperPicker.swift b/submodules/TelegramUI/TelegramUI/LegacyWallpaperPicker.swift index b8322739a2..119ecefba6 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyWallpaperPicker.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyWallpaperPicker.swift @@ -6,7 +6,7 @@ import LegacyComponents import TelegramPresentationData import DeviceAccess -func legacyWallpaperPicker(context: AccountContext, presentationData: PresentationData) -> Signal<(LegacyComponentsContext) -> TGMediaAssetsController, Void> { +func legacyWallpaperPicker(context: AccountContextImpl, presentationData: PresentationData) -> Signal<(LegacyComponentsContext) -> TGMediaAssetsController, Void> { return Signal { subscriber in let intent = TGMediaAssetsControllerSetCustomWallpaperIntent diff --git a/submodules/TelegramUI/TelegramUI/LegacyWebSearchEditor.swift b/submodules/TelegramUI/TelegramUI/LegacyWebSearchEditor.swift index db093b3d9a..5785628b97 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyWebSearchEditor.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyWebSearchEditor.swift @@ -8,7 +8,7 @@ import SSignalKit import Display import TelegramPresentationData -func presentLegacyWebSearchEditor(context: AccountContext, theme: PresentationTheme, result: ChatContextResult, initialLayout: ContainerViewLayout?, updateHiddenMedia: @escaping (String?) -> Void, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (ChatContextResult) -> UIView?, completed: @escaping (UIImage) -> Void, present: @escaping (ViewController, Any?) -> Void) { +func presentLegacyWebSearchEditor(context: AccountContextImpl, theme: PresentationTheme, result: ChatContextResult, initialLayout: ContainerViewLayout?, updateHiddenMedia: @escaping (String?) -> Void, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (ChatContextResult) -> UIView?, completed: @escaping (UIImage) -> Void, present: @escaping (ViewController, Any?) -> Void) { guard let item = legacyWebSearchItem(account: context.account, result: result) else { return } diff --git a/submodules/TelegramUI/TelegramUI/LegacyWebSearchGallery.swift b/submodules/TelegramUI/TelegramUI/LegacyWebSearchGallery.swift index bc6fc23852..d484f969c4 100644 --- a/submodules/TelegramUI/TelegramUI/LegacyWebSearchGallery.swift +++ b/submodules/TelegramUI/TelegramUI/LegacyWebSearchGallery.swift @@ -308,7 +308,7 @@ private func galleryItems(account: Account, results: [ChatContextResult], curren return (galleryItems, focusItem) } -func presentLegacyWebSearchGallery(context: AccountContext, peer: Peer?, theme: PresentationTheme, results: [ChatContextResult], current: ChatContextResult, selectionContext: TGMediaSelectionContext?, editingContext: TGMediaEditingContext, updateHiddenMedia: @escaping (String?) -> Void, initialLayout: ContainerViewLayout?, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (ChatContextResult) -> UIView?, completed: @escaping (ChatContextResult) -> Void, present: (ViewController, Any?) -> Void) { +func presentLegacyWebSearchGallery(context: AccountContextImpl, peer: Peer?, theme: PresentationTheme, results: [ChatContextResult], current: ChatContextResult, selectionContext: TGMediaSelectionContext?, editingContext: TGMediaEditingContext, updateHiddenMedia: @escaping (String?) -> Void, initialLayout: ContainerViewLayout?, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (ChatContextResult) -> UIView?, completed: @escaping (ChatContextResult) -> Void, present: (ViewController, Any?) -> Void) { let legacyController = LegacyController(presentation: .custom, theme: theme, initialLayout: nil) legacyController.statusBar.statusBarStyle = theme.rootController.statusBarStyle.style diff --git a/submodules/TelegramUI/TelegramUI/ListMessageDateHeader.swift b/submodules/TelegramUI/TelegramUI/ListMessageDateHeader.swift index 22b75af6f9..5fcdd2b559 100644 --- a/submodules/TelegramUI/TelegramUI/ListMessageDateHeader.swift +++ b/submodules/TelegramUI/TelegramUI/ListMessageDateHeader.swift @@ -80,7 +80,7 @@ final class ListMessageDateHeaderNode: ListViewItemHeaderNode { func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) { self.theme = theme if let attributedString = self.titleNode.attributedText?.mutableCopy() as? NSMutableAttributedString { - attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: theme.list.itemPrimaryTextColor, range: NSMakeRange(0, attributedString.length)) + attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: theme.list.itemPrimaryTextColor, range: NSMakeRange(0, attributedString.length)) self.titleNode.attributedText = attributedString } diff --git a/submodules/TelegramUI/TelegramUI/ListMessageFileItemNode.swift b/submodules/TelegramUI/TelegramUI/ListMessageFileItemNode.swift index 82d6464ed2..bf2f2fc0e3 100644 --- a/submodules/TelegramUI/TelegramUI/ListMessageFileItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ListMessageFileItemNode.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import ItemListUI private let extensionImageCache = Atomic<[UInt32: UIImage]>(value: [:]) @@ -169,7 +170,7 @@ final class ListMessageFileItemNode: ListMessageNode { private let progressNode: RadialProgressNode private var playbackOverlayNode: ListMessagePlaybackOverlayNode? - private var context: AccountContext? + private var context: AccountContextImpl? private (set) var message: Message? private var appliedItem: ListMessageItem? diff --git a/submodules/TelegramUI/TelegramUI/ListMessageHoleItem.swift b/submodules/TelegramUI/TelegramUI/ListMessageHoleItem.swift index 3c15a59943..bb3e062657 100644 --- a/submodules/TelegramUI/TelegramUI/ListMessageHoleItem.swift +++ b/submodules/TelegramUI/TelegramUI/ListMessageHoleItem.swift @@ -72,7 +72,7 @@ final class ListMessageHoleItemNode: ListViewItemNode { override func didLoad() { super.didLoad() - let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray) + let activityIndicator = UIActivityIndicatorView(style: .gray) self.activityIndicator = activityIndicator self.view.addSubview(activityIndicator) let size = activityIndicator.bounds.size diff --git a/submodules/TelegramUI/TelegramUI/ListMessageItem.swift b/submodules/TelegramUI/TelegramUI/ListMessageItem.swift index 84e34aa529..d8aae5a3ad 100644 --- a/submodules/TelegramUI/TelegramUI/ListMessageItem.swift +++ b/submodules/TelegramUI/TelegramUI/ListMessageItem.swift @@ -11,7 +11,7 @@ final class ListMessageItem: ListViewItem { let theme: PresentationTheme let strings: PresentationStrings let dateTimeFormat: PresentationDateTimeFormat - let context: AccountContext + let context: AccountContextImpl let chatLocation: ChatLocation let controllerInteraction: ChatControllerInteraction let message: Message @@ -21,7 +21,7 @@ final class ListMessageItem: ListViewItem { let selectable: Bool = true - public init(theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, context: AccountContext, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, message: Message, selection: ChatHistoryMessageSelection, displayHeader: Bool) { + public init(theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, context: AccountContextImpl, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, message: Message, selection: ChatHistoryMessageSelection, displayHeader: Bool) { self.theme = theme self.strings = strings self.dateTimeFormat = dateTimeFormat diff --git a/submodules/TelegramUI/TelegramUI/ListMessagePlaybackOverlayNode.swift b/submodules/TelegramUI/TelegramUI/ListMessagePlaybackOverlayNode.swift index 86b3863f00..73431446e1 100644 --- a/submodules/TelegramUI/TelegramUI/ListMessagePlaybackOverlayNode.swift +++ b/submodules/TelegramUI/TelegramUI/ListMessagePlaybackOverlayNode.swift @@ -85,7 +85,7 @@ final class ListMessagePlaybackOverlayNode: ASDisplayNode { animation.autoreverses = true animation.duration = 0.25 + 0.25 * randDurationMul animation.repeatCount = Float.greatestFiniteMagnitude; - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn) barNode.layer.removeAnimation(forKey: "transform.scale.y") barNode.layer.add(animation, forKey: "transform.scale.y") diff --git a/submodules/TelegramUI/TelegramUI/ListMessageSnippetItemNode.swift b/submodules/TelegramUI/TelegramUI/ListMessageSnippetItemNode.swift index 76d3ea1023..510eb52909 100644 --- a/submodules/TelegramUI/TelegramUI/ListMessageSnippetItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ListMessageSnippetItemNode.swift @@ -6,6 +6,8 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import ItemListUI +import TextFormat private let titleFont = Font.medium(16.0) private let descriptionFont = Font.regular(14.0) @@ -214,7 +216,7 @@ final class ListMessageSnippetItemNode: ListMessageNode { let plainUrlString = NSAttributedString(string: content.displayUrl, font: descriptionFont, textColor: item.theme.list.itemAccentColor) let urlString = NSMutableAttributedString() urlString.append(plainUrlString) - urlString.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.URL), value: content.displayUrl, range: NSMakeRange(0, urlString.length)) + urlString.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: content.displayUrl, range: NSMakeRange(0, urlString.length)) linkText = urlString descriptionText = mutableDescriptionText @@ -273,9 +275,9 @@ final class ListMessageSnippetItemNode: ListMessageNode { let urlAttributedString = NSMutableAttributedString() urlAttributedString.append(NSAttributedString(string: urlString, font: descriptionFont, textColor: item.theme.list.itemAccentColor)) if item.theme.list.itemAccentColor.isEqual(item.theme.list.itemPrimaryTextColor) { - urlAttributedString.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue as NSNumber, range: NSMakeRange(0, urlAttributedString.length)) + urlAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: NSMakeRange(0, urlAttributedString.length)) } - urlAttributedString.addAttribute(NSAttributedStringKey(rawValue: TelegramTextAttributes.URL), value: urlString, range: NSMakeRange(0, urlAttributedString.length)) + urlAttributedString.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: urlString, range: NSMakeRange(0, urlAttributedString.length)) linkText = urlAttributedString descriptionText = mutableDescriptionText @@ -527,7 +529,7 @@ final class ListMessageSnippetItemNode: ListMessageNode { TelegramTextAttributes.URL, ] for name in possibleNames { - if let value = attributes[NSAttributedStringKey(rawValue: name)] as? String { + if let value = attributes[NSAttributedString.Key(rawValue: name)] as? String { return value } } @@ -575,7 +577,7 @@ final class ListMessageSnippetItemNode: ListMessageNode { TelegramTextAttributes.URL ] for name in possibleNames { - if let _ = attributes[NSAttributedStringKey(rawValue: name)] { + if let _ = attributes[NSAttributedString.Key(rawValue: name)] { rects = self.linkNode.attributeRects(name: name, at: index) break } diff --git a/submodules/TelegramUI/TelegramUI/LocalizationListController.swift b/submodules/TelegramUI/TelegramUI/LocalizationListController.swift index 9d9a2d4b32..16d6e12f59 100644 --- a/submodules/TelegramUI/TelegramUI/LocalizationListController.swift +++ b/submodules/TelegramUI/TelegramUI/LocalizationListController.swift @@ -8,7 +8,7 @@ import TelegramCore import TelegramPresentationData public class LocalizationListController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private var controllerNode: LocalizationListControllerNode { return self.displayNode as! LocalizationListControllerNode @@ -27,7 +27,7 @@ public class LocalizationListController: ViewController { private var searchContentNode: NavigationBarSearchContentNode? - public init(context: AccountContext) { + public init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/LocalizationListControllerNode.swift b/submodules/TelegramUI/TelegramUI/LocalizationListControllerNode.swift index 5f55acc0ed..70ab35c561 100644 --- a/submodules/TelegramUI/TelegramUI/LocalizationListControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/LocalizationListControllerNode.swift @@ -6,6 +6,8 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import MergeLists +import ItemListUI private enum LanguageListSection: ItemListSectionId { case official @@ -85,7 +87,7 @@ private final class LocalizationListSearchContainerNode: SearchDisplayController private let themeAndStringsPromise: Promise<(PresentationTheme, PresentationStrings)> - init(context: AccountContext, listState: LocalizationListState, selectLocalization: @escaping (LocalizationInfo) -> Void, applyingCode: Signal) { + init(context: AccountContextImpl, listState: LocalizationListState, selectLocalization: @escaping (LocalizationInfo) -> Void, applyingCode: Signal) { self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings)) @@ -273,7 +275,7 @@ private func preparedLanguageListNodeTransition(theme: PresentationTheme, string } final class LocalizationListControllerNode: ViewControllerTracingNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let navigationBar: NavigationBar private let requestActivateSearch: () -> Void @@ -303,7 +305,7 @@ final class LocalizationListControllerNode: ViewControllerTracingNode { } } - init(context: AccountContext, presentationData: PresentationData, navigationBar: NavigationBar, requestActivateSearch: @escaping () -> Void, requestDeactivateSearch: @escaping () -> Void, updateCanStartEditing: @escaping (Bool?) -> Void, present: @escaping (ViewController, Any?) -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, navigationBar: NavigationBar, requestActivateSearch: @escaping () -> Void, requestDeactivateSearch: @escaping () -> Void, updateCanStartEditing: @escaping (Bool?) -> Void, present: @escaping (ViewController, Any?) -> Void) { self.context = context self.presentationData = presentationData self.presentationDataValue.set(.single((presentationData.theme, presentationData.strings))) diff --git a/submodules/TelegramUI/TelegramUI/LocalizationListItem.swift b/submodules/TelegramUI/TelegramUI/LocalizationListItem.swift index 435259b752..84829baa70 100644 --- a/submodules/TelegramUI/TelegramUI/LocalizationListItem.swift +++ b/submodules/TelegramUI/TelegramUI/LocalizationListItem.swift @@ -4,6 +4,8 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI +import ActivityIndicator struct LocalizationListItemEditing: Equatable { let editable: Bool diff --git a/submodules/TelegramUI/TelegramUI/LocationBroadcastActionSheetItem.swift b/submodules/TelegramUI/TelegramUI/LocationBroadcastActionSheetItem.swift index 3641e27fcc..f528d012e1 100644 --- a/submodules/TelegramUI/TelegramUI/LocationBroadcastActionSheetItem.swift +++ b/submodules/TelegramUI/TelegramUI/LocationBroadcastActionSheetItem.swift @@ -7,7 +7,7 @@ import Postbox import TelegramPresentationData public class LocationBroadcastActionSheetItem: ActionSheetItem { - public let context: AccountContext + public let context: AccountContextImpl public let peer: Peer public let title: String public let beginTimestamp: Double @@ -15,7 +15,7 @@ public class LocationBroadcastActionSheetItem: ActionSheetItem { public let strings: PresentationStrings public let action: () -> Void - public init(context: AccountContext, peer: Peer, title: String, beginTimestamp: Double, timeout: Double, strings: PresentationStrings, action: @escaping () -> Void) { + public init(context: AccountContextImpl, peer: Peer, title: String, beginTimestamp: Double, timeout: Double, strings: PresentationStrings, action: @escaping () -> Void) { self.context = context self.peer = peer self.title = title diff --git a/submodules/TelegramUI/TelegramUI/LocationBroadcastNavigationAccessoryPanel.swift b/submodules/TelegramUI/TelegramUI/LocationBroadcastNavigationAccessoryPanel.swift index f8d6f8f136..7a7557828e 100644 --- a/submodules/TelegramUI/TelegramUI/LocationBroadcastNavigationAccessoryPanel.swift +++ b/submodules/TelegramUI/TelegramUI/LocationBroadcastNavigationAccessoryPanel.swift @@ -5,6 +5,7 @@ import Display import TelegramCore import Postbox import TelegramPresentationData +import TextFormat private let titleFont = Font.regular(12.0) private let subtitleFont = Font.regular(10.0) @@ -61,7 +62,7 @@ final class LocationBroadcastNavigationAccessoryPanel: ASDisplayNode { self.closeButton = HighlightableButtonNode() self.closeButton.setImage(PresentationResourcesRootController.navigationPlayerCloseButton(self.theme), for: []) - self.closeButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0) + self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0) self.closeButton.displaysAsynchronously = false self.separatorNode = ASDisplayNode() diff --git a/submodules/TelegramUI/TelegramUI/LocationBroadcastPanelWavesNode.swift b/submodules/TelegramUI/TelegramUI/LocationBroadcastPanelWavesNode.swift index bcdfc10da7..5c19d1782d 100644 --- a/submodules/TelegramUI/TelegramUI/LocationBroadcastPanelWavesNode.swift +++ b/submodules/TelegramUI/TelegramUI/LocationBroadcastPanelWavesNode.swift @@ -60,7 +60,7 @@ final class LocationBroadcastPanelWavesNode: ASDisplayNode { }) as! POPAnimatableProperty) animation.fromValue = CGFloat(0.0) as NSNumber animation.toValue = CGFloat(1.0) as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 2.5 animation.repeatForever = true self.pop_add(animation, forKey: "indefiniteProgress") diff --git a/submodules/TelegramUI/TelegramUI/LogoutOptionsController.swift b/submodules/TelegramUI/TelegramUI/LogoutOptionsController.swift index f3a53cbcb9..bd36721293 100644 --- a/submodules/TelegramUI/TelegramUI/LogoutOptionsController.swift +++ b/submodules/TelegramUI/TelegramUI/LogoutOptionsController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import LegacyComponents import TelegramPresentationData +import ItemListUI private struct LogoutOptionsItemArguments { let addAccount: () -> Void @@ -116,7 +117,7 @@ private func logoutOptionsEntries(presentationData: PresentationData, canAddAcco return entries } -func logoutOptionsController(context: AccountContext, navigationController: NavigationController, canAddAccounts: Bool, phoneNumber: String) -> ViewController { +func logoutOptionsController(context: AccountContextImpl, navigationController: NavigationController, canAddAccounts: Bool, phoneNumber: String) -> ViewController { var pushControllerImpl: ((ViewController) -> Void)? var presentControllerImpl: ((ViewController, Any?) -> Void)? var replaceTopControllerImpl: ((ViewController) -> Void)? diff --git a/submodules/TelegramUI/TelegramUI/ManagedAudioRecorder.swift b/submodules/TelegramUI/TelegramUI/ManagedAudioRecorder.swift index f9c0b5a34e..45d02f89f6 100644 --- a/submodules/TelegramUI/TelegramUI/ManagedAudioRecorder.swift +++ b/submodules/TelegramUI/TelegramUI/ManagedAudioRecorder.swift @@ -241,7 +241,7 @@ final class ManagedAudioRecorderContext { toneData.withUnsafeBytes { (dataBytes: UnsafePointer) -> Void in memcpy(bytes, dataBytes.advanced(by: takeRange.lowerBound), takeRange.count) } - let status = CMBlockBufferCreateWithMemoryBlock(nil, bytes, takeRange.count, nil, nil, 0, takeRange.count, 0, &blockBuffer) + let status = CMBlockBufferCreateWithMemoryBlock(allocator: nil, memoryBlock: bytes, blockLength: takeRange.count, blockAllocator: nil, customBlockSource: nil, offsetToData: 0, dataLength: takeRange.count, flags: 0, blockBufferOut: &blockBuffer) if status != noErr { return .finished } @@ -252,7 +252,7 @@ final class ManagedAudioRecorderContext { var timingInfo = CMSampleTimingInfo(duration: CMTime(value: Int64(sampleCount), timescale: 44100), presentationTimeStamp: pts, decodeTimeStamp: pts) var sampleBuffer: CMSampleBuffer? var sampleSize = takeRange.count - guard CMSampleBufferCreate(nil, blockBuffer, true, nil, nil, nil, 1, 1, &timingInfo, 1, &sampleSize, &sampleBuffer) == noErr else { + guard CMSampleBufferCreate(allocator: nil, dataBuffer: blockBuffer, dataReady: true, makeDataReadyCallback: nil, refcon: nil, formatDescription: nil, sampleCount: 1, sampleTimingEntryCount: 1, sampleTimingArray: &timingInfo, sampleSizeEntryCount: 1, sampleSizeArray: &sampleSize, sampleBufferOut: &sampleBuffer) == noErr else { return .finished } diff --git a/submodules/TelegramUI/TelegramUI/MapResourceToAvatarSizes.swift b/submodules/TelegramUI/TelegramUI/MapResourceToAvatarSizes.swift index 18190f0946..d949c565d9 100644 --- a/submodules/TelegramUI/TelegramUI/MapResourceToAvatarSizes.swift +++ b/submodules/TelegramUI/TelegramUI/MapResourceToAvatarSizes.swift @@ -14,7 +14,7 @@ func mapResourceToAvatarSizes(postbox: Postbox, resource: MediaResource, represe } var result: [Int: Data] = [:] for i in 0 ..< representations.count { - if let scaledImage = generateScaledImage(image: image, size: representations[i].dimensions, scale: 1.0), let scaledData = UIImageJPEGRepresentation(scaledImage, 0.8) { + if let scaledImage = generateScaledImage(image: image, size: representations[i].dimensions, scale: 1.0), let scaledData = scaledImage.jpegData(compressionQuality: 0.8) { result[i] = scaledData } } diff --git a/submodules/TelegramUI/TelegramUI/MapResources.swift b/submodules/TelegramUI/TelegramUI/MapResources.swift index 3b4fb7c02e..5806475e29 100644 --- a/submodules/TelegramUI/TelegramUI/MapResources.swift +++ b/submodules/TelegramUI/TelegramUI/MapResources.swift @@ -89,9 +89,9 @@ func fetchMapSnapshotResource(resource: MapSnapshotMediaResource) -> Signal Signal Void)? var playNext: (() -> Void)? - init(context: AccountContext) { + init(context: AccountContextImpl) { self.containerNode = MediaNavigationAccessoryContainerNode(context: context) super.init() diff --git a/submodules/TelegramUI/TelegramUI/MentionChatInputContextPanelNode.swift b/submodules/TelegramUI/TelegramUI/MentionChatInputContextPanelNode.swift index 4359741458..ab1df098d9 100644 --- a/submodules/TelegramUI/TelegramUI/MentionChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/MentionChatInputContextPanelNode.swift @@ -5,6 +5,8 @@ import Postbox import TelegramCore import Display import TelegramPresentationData +import MergeLists +import TextFormat private struct MentionChatInputContextPanelEntry: Comparable, Identifiable { let index: Int @@ -57,7 +59,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode { private var enqueuedTransitions: [(CommandChatInputContextPanelTransition, Bool)] = [] private var validLayout: (CGSize, CGFloat, CGFloat)? - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, mode: MentionChatInputContextPanelMode) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings, mode: MentionChatInputContextPanelMode) { self.mode = mode self.listView = ListView() diff --git a/submodules/TelegramUI/TelegramUI/ModernCheckNode.swift b/submodules/TelegramUI/TelegramUI/ModernCheckNode.swift index eec293ba23..b266ac7972 100644 --- a/submodules/TelegramUI/TelegramUI/ModernCheckNode.swift +++ b/submodules/TelegramUI/TelegramUI/ModernCheckNode.swift @@ -74,7 +74,7 @@ class ModernCheckNode: ASDisplayNode { }) as! POPAnimatableProperty) animation.fromValue = 0.0 as NSNumber animation.toValue = 1.0 as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 0.21 self.pop_add(animation, forKey: "progress") } else { diff --git a/submodules/TelegramUI/TelegramUI/MultipleAvatarsNode.swift b/submodules/TelegramUI/TelegramUI/MultipleAvatarsNode.swift index 3caabf364e..0642cad9fc 100644 --- a/submodules/TelegramUI/TelegramUI/MultipleAvatarsNode.swift +++ b/submodules/TelegramUI/TelegramUI/MultipleAvatarsNode.swift @@ -59,7 +59,7 @@ final class MultipleAvatarsNode: ASDisplayNode { let distance = CGPoint(x: avatarNode.frame.midX - avatarFrame.midX, y: avatarNode.frame.midY - avatarFrame.midY) avatarNode.frame = avatarFrame if animated { - avatarNode.layer.animatePosition(from: distance, to: CGPoint(), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, additive: true) + avatarNode.layer.animatePosition(from: distance, to: CGPoint(), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, additive: true) } } avatarNode.setPeer(account: account, theme: theme, peer: peer) diff --git a/submodules/TelegramUI/TelegramUI/MultiplexedVideoNode.swift b/submodules/TelegramUI/TelegramUI/MultiplexedVideoNode.swift index 57e6d0f7b4..fb03be4a5f 100644 --- a/submodules/TelegramUI/TelegramUI/MultiplexedVideoNode.swift +++ b/submodules/TelegramUI/TelegramUI/MultiplexedVideoNode.swift @@ -77,8 +77,8 @@ final class MultiplexedVideoNode: ASScrollNode, UIScrollViewDelegate { self.trackingNode.isLayerBacked = true var timebase: CMTimebase? - CMTimebaseCreateWithMasterClock(nil, CMClockGetHostTimeClock(), &timebase) - CMTimebaseSetRate(timebase!, 0.0) + CMTimebaseCreateWithMasterClock(allocator: nil, masterClock: CMClockGetHostTimeClock(), timebaseOut: &timebase) + CMTimebaseSetRate(timebase!, rate: 0.0) self.timebase = timebase! super.init() @@ -102,7 +102,7 @@ final class MultiplexedVideoNode: ASScrollNode, UIScrollViewDelegate { } self.displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent)) - self.displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink.add(to: RunLoop.main, forMode: .common) if #available(iOS 10.0, *) { self.displayLink.preferredFramesPerSecond = 25 } else { @@ -113,9 +113,9 @@ final class MultiplexedVideoNode: ASScrollNode, UIScrollViewDelegate { self.trackingNode.inHierarchyUpdated = { [weak self] value in if let strongSelf = self { if !value { - CMTimebaseSetRate(strongSelf.timebase, 0.0) + CMTimebaseSetRate(strongSelf.timebase, rate: 0.0) } else { - CMTimebaseSetRate(strongSelf.timebase, 1.0) + CMTimebaseSetRate(strongSelf.timebase, rate: 1.0) } strongSelf.displayLink.isPaused = !value if value && !strongSelf.enableVideoNodes { diff --git a/submodules/TelegramUI/TelegramUI/NavigateToChatController.swift b/submodules/TelegramUI/TelegramUI/NavigateToChatController.swift index 0fcb9c3d46..fffac3a39b 100644 --- a/submodules/TelegramUI/TelegramUI/NavigateToChatController.swift +++ b/submodules/TelegramUI/TelegramUI/NavigateToChatController.swift @@ -10,7 +10,7 @@ public enum NavigateToChatKeepStack { case never } -public func navigateToChatController(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: ChatLocation, messageId: MessageId? = nil, botStart: ChatControllerInitialBotStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: Bool = false, keepStack: NavigateToChatKeepStack = .default, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, completion: @escaping () -> Void = {}) { +public func navigateToChatController(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContextImpl, chatLocation: ChatLocation, messageId: MessageId? = nil, botStart: ChatControllerInitialBotStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: Bool = false, keepStack: NavigateToChatKeepStack = .default, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, completion: @escaping () -> Void = {}) { var found = false var isFirst = true for controller in navigationController.viewControllers.reversed() { diff --git a/submodules/TelegramUI/TelegramUI/NavigationBarSearchContentNode.swift b/submodules/TelegramUI/TelegramUI/NavigationBarSearchContentNode.swift index cfda4fccc3..f36c919d82 100644 --- a/submodules/TelegramUI/TelegramUI/NavigationBarSearchContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/NavigationBarSearchContentNode.swift @@ -29,7 +29,7 @@ class NavigationBarSearchContentNode: NavigationBarContentNode { self.placeholderNode.isAccessibilityElement = true self.placeholderNode.accessibilityLabel = placeholder - self.placeholderNode.accessibilityTraits = UIAccessibilityTraitSearchField + self.placeholderNode.accessibilityTraits = .searchField self.addSubnode(self.placeholderNode) self.placeholderNode.activate = activate diff --git a/submodules/TelegramUI/TelegramUI/NetworkUsageStatsController.swift b/submodules/TelegramUI/TelegramUI/NetworkUsageStatsController.swift index 5cf874e97c..877f913272 100644 --- a/submodules/TelegramUI/TelegramUI/NetworkUsageStatsController.swift +++ b/submodules/TelegramUI/TelegramUI/NetworkUsageStatsController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private enum NetworkUsageControllerSection { case cellular @@ -375,7 +376,7 @@ private func networkUsageStatsControllerEntries(presentationData: PresentationDa return entries } -func networkUsageStatsController(context: AccountContext) -> ViewController { +func networkUsageStatsController(context: AccountContextImpl) -> ViewController { let section = ValuePromise(.cellular) let stats = Promise() stats.set(accountNetworkUsageStats(account: context.account, reset: [])) diff --git a/submodules/TelegramUI/TelegramUI/NotificationContainerController.swift b/submodules/TelegramUI/TelegramUI/NotificationContainerController.swift index e2ffbef98e..b1fac0c262 100644 --- a/submodules/TelegramUI/TelegramUI/NotificationContainerController.swift +++ b/submodules/TelegramUI/TelegramUI/NotificationContainerController.swift @@ -14,7 +14,7 @@ public final class NotificationContainerController: ViewController { private var presentationData: PresentationData private var presentationDataDisposable: Disposable? - public init(context: AccountContext) { + public init(context: AccountContextImpl) { self.presentationData = context.sharedContext.currentPresentationData.with { $0 } super.init(navigationBarPresentationData: nil) diff --git a/submodules/TelegramUI/TelegramUI/NotificationContentContext.swift b/submodules/TelegramUI/TelegramUI/NotificationContentContext.swift index aec6d9471d..4a33ce2d55 100644 --- a/submodules/TelegramUI/TelegramUI/NotificationContentContext.swift +++ b/submodules/TelegramUI/TelegramUI/NotificationContentContext.swift @@ -8,12 +8,13 @@ import Postbox import TelegramPresentationData import TelegramUIPreferences import TelegramUIPrivateModule +import AccountContext private enum NotificationContentAuthorizationError { case unauthorized } -private var sharedAccountContext: SharedAccountContext? +private var sharedAccountContext: SharedAccountContextImpl? private var installedSharedLogger = false @@ -138,7 +139,7 @@ public final class NotificationViewControllerImpl { f(false) }) - sharedAccountContext = SharedAccountContext(mainWindow: nil, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, appData: .single(self.initializationData.bundleData)), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }) + sharedAccountContext = SharedAccountContextImpl(mainWindow: nil, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, appData: .single(self.initializationData.bundleData)), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }) } } diff --git a/submodules/TelegramUI/TelegramUI/NotificationExceptionControllerNode.swift b/submodules/TelegramUI/TelegramUI/NotificationExceptionControllerNode.swift index 5332875288..e4c1522194 100644 --- a/submodules/TelegramUI/TelegramUI/NotificationExceptionControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/NotificationExceptionControllerNode.swift @@ -7,6 +7,8 @@ import TelegramCore import SwiftSignalKit import TelegramPresentationData import TelegramUIPreferences +import ItemListUI +import MergeLists private final class NotificationExceptionState : Equatable { let mode:NotificationExceptionMode @@ -633,7 +635,7 @@ private extension PeerMuteState { } final class NotificationExceptionsControllerNode: ViewControllerTracingNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let navigationBar: NavigationBar private let requestActivateSearch: () -> Void @@ -662,7 +664,7 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode { self.arguments?.selectPeer() } - init(context: AccountContext, presentationData: PresentationData, navigationBar: NavigationBar, mode: NotificationExceptionMode, updatedMode:@escaping(NotificationExceptionMode)->Void, requestActivateSearch: @escaping () -> Void, requestDeactivateSearch: @escaping (Bool) -> Void, updateCanStartEditing: @escaping (Bool?) -> Void, present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, navigationBar: NavigationBar, mode: NotificationExceptionMode, updatedMode:@escaping(NotificationExceptionMode)->Void, requestActivateSearch: @escaping () -> Void, requestDeactivateSearch: @escaping (Bool) -> Void, updateCanStartEditing: @escaping (Bool?) -> Void, present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void) { self.context = context self.presentationData = presentationData self.presentationDataValue.set(.single((presentationData.theme, presentationData.strings))) @@ -1136,7 +1138,7 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont private let updateNotificationsDisposable = MetaDisposable() private let themeAndStringsPromise: Promise<(PresentationTheme, PresentationStrings)> - init(context: AccountContext, mode: NotificationExceptionMode, arguments: NotificationExceptionArguments) { + init(context: AccountContextImpl, mode: NotificationExceptionMode, arguments: NotificationExceptionArguments) { self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.themeAndStringsPromise = Promise((self.presentationData.theme, self.presentationData.strings)) diff --git a/submodules/TelegramUI/TelegramUI/NotificationExceptionSettingsController.swift b/submodules/TelegramUI/TelegramUI/NotificationExceptionSettingsController.swift index d3b68f54e4..998fc270ef 100644 --- a/submodules/TelegramUI/TelegramUI/NotificationExceptionSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/NotificationExceptionSettingsController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import ItemListUI private enum NotificationPeerExceptionSection: Int32 { case remove @@ -306,7 +307,7 @@ private struct NotificationExceptionPeerState : Equatable { } -func notificationPeerExceptionController(context: AccountContext, peer: Peer, mode: NotificationExceptionMode, updatePeerSound: @escaping(PeerId, PeerMessageSound) -> Void, updatePeerNotificationInterval: @escaping(PeerId, Int32?) -> Void, updatePeerDisplayPreviews: @escaping(PeerId, PeerNotificationDisplayPreviews) -> Void, removePeerFromExceptions: @escaping () -> Void, modifiedPeer: @escaping () -> Void) -> ViewController { +func notificationPeerExceptionController(context: AccountContextImpl, peer: Peer, mode: NotificationExceptionMode, updatePeerSound: @escaping(PeerId, PeerMessageSound) -> Void, updatePeerNotificationInterval: @escaping(PeerId, Int32?) -> Void, updatePeerDisplayPreviews: @escaping(PeerId, PeerNotificationDisplayPreviews) -> Void, removePeerFromExceptions: @escaping () -> Void, modifiedPeer: @escaping () -> Void) -> ViewController { let initialState = NotificationExceptionPeerState(canRemove: false) let statePromise = Promise(initialState) let stateValue = Atomic(value: initialState) diff --git a/submodules/TelegramUI/TelegramUI/NotificationExceptions.swift b/submodules/TelegramUI/TelegramUI/NotificationExceptions.swift index 3a5a55694e..8705fb73fd 100644 --- a/submodules/TelegramUI/TelegramUI/NotificationExceptions.swift +++ b/submodules/TelegramUI/TelegramUI/NotificationExceptions.swift @@ -7,7 +7,7 @@ import TelegramCore import TelegramPresentationData public class NotificationExceptionsController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private var controllerNode: NotificationExceptionsControllerNode { return self.displayNode as! NotificationExceptionsControllerNode @@ -30,7 +30,7 @@ public class NotificationExceptionsController: ViewController { private var searchContentNode: NavigationBarSearchContentNode? - public init(context: AccountContext, mode: NotificationExceptionMode, updatedMode: @escaping(NotificationExceptionMode) -> Void) { + public init(context: AccountContextImpl, mode: NotificationExceptionMode, updatedMode: @escaping(NotificationExceptionMode) -> Void) { self.context = context self.mode = mode self.updatedMode = updatedMode diff --git a/submodules/TelegramUI/TelegramUI/NotificationItemContainerNode.swift b/submodules/TelegramUI/TelegramUI/NotificationItemContainerNode.swift index 06aadc5a36..8d0216626c 100644 --- a/submodules/TelegramUI/TelegramUI/NotificationItemContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/NotificationItemContainerNode.swift @@ -206,7 +206,7 @@ final class NotificationItemContainerNode: ASDisplayNode { var bounds = self.bounds bounds.origin.y = 0.0 self.bounds = bounds - self.layer.animateBounds(from: previousBounds, to: self.bounds, duration: 0.3, timingFunction: kCAMediaTimingFunctionEaseInEaseOut) + self.layer.animateBounds(from: previousBounds, to: self.bounds, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue) self.willBeExpanded = false } @@ -217,7 +217,7 @@ final class NotificationItemContainerNode: ASDisplayNode { var bounds = self.bounds bounds.origin.y = 0.0 self.bounds = bounds - self.layer.animateBounds(from: previousBounds, to: self.bounds, duration: 0.3, timingFunction: kCAMediaTimingFunctionEaseInEaseOut) + self.layer.animateBounds(from: previousBounds, to: self.bounds, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue) default: break } diff --git a/submodules/TelegramUI/TelegramUI/NotificationSearchItem.swift b/submodules/TelegramUI/TelegramUI/NotificationSearchItem.swift index c1ea630ab9..52b1397a1f 100644 --- a/submodules/TelegramUI/TelegramUI/NotificationSearchItem.swift +++ b/submodules/TelegramUI/TelegramUI/NotificationSearchItem.swift @@ -5,6 +5,7 @@ import Postbox import Display import SwiftSignalKit import TelegramPresentationData +import ItemListUI private let searchBarFont = Font.regular(14.0) diff --git a/submodules/TelegramUI/TelegramUI/NotificationSoundSelection.swift b/submodules/TelegramUI/TelegramUI/NotificationSoundSelection.swift index 28c0da2b12..341e62223c 100644 --- a/submodules/TelegramUI/TelegramUI/NotificationSoundSelection.swift +++ b/submodules/TelegramUI/TelegramUI/NotificationSoundSelection.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import AVFoundation import TelegramPresentationData +import ItemListUI private struct NotificationSoundSelectionArguments { let account: Account @@ -211,7 +212,7 @@ public func fileNameForNotificationSound(_ sound: PeerMessageSound, defaultSound } } -func playSound(context: AccountContext, sound: PeerMessageSound, defaultSound: PeerMessageSound?) -> Signal { +func playSound(context: AccountContextImpl, sound: PeerMessageSound, defaultSound: PeerMessageSound?) -> Signal { if case .none = sound { return .complete() } else { @@ -252,7 +253,7 @@ func playSound(context: AccountContext, sound: PeerMessageSound, defaultSound: P } } -public func notificationSoundSelectionController(context: AccountContext, isModal: Bool, currentSound: PeerMessageSound, defaultSound: PeerMessageSound?, completion: @escaping (PeerMessageSound) -> Void) -> ViewController { +public func notificationSoundSelectionController(context: AccountContextImpl, isModal: Bool, currentSound: PeerMessageSound, defaultSound: PeerMessageSound?, completion: @escaping (PeerMessageSound) -> Void) -> ViewController { let statePromise = ValuePromise(NotificationSoundSelectionState(selectedSound: currentSound), ignoreRepeated: true) let stateValue = Atomic(value: NotificationSoundSelectionState(selectedSound: currentSound)) let updateState: ((NotificationSoundSelectionState) -> NotificationSoundSelectionState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/NotificationsAndSounds.swift b/submodules/TelegramUI/TelegramUI/NotificationsAndSounds.swift index 117eeb2e3d..ad8d4d6f17 100644 --- a/submodules/TelegramUI/TelegramUI/NotificationsAndSounds.swift +++ b/submodules/TelegramUI/TelegramUI/NotificationsAndSounds.swift @@ -7,9 +7,10 @@ import TelegramCore import TelegramPresentationData import TelegramUIPreferences import DeviceAccess +import ItemListUI private final class NotificationsAndSoundsArguments { - let context: AccountContext + let context: AccountContextImpl let presentController: (ViewController, ViewControllerPresentationArguments?) -> Void let pushController: (ViewController) -> Void let soundSelectionDisposable: MetaDisposable @@ -48,7 +49,7 @@ private final class NotificationsAndSoundsArguments { let updateNotificationsFromAllAccounts: (Bool) -> Void - init(context: AccountContext, presentController: @escaping (ViewController, ViewControllerPresentationArguments?) -> Void, pushController: @escaping(ViewController)->Void, soundSelectionDisposable: MetaDisposable, authorizeNotifications: @escaping () -> Void, suppressWarning: @escaping () -> Void, updateMessageAlerts: @escaping (Bool) -> Void, updateMessagePreviews: @escaping (Bool) -> Void, updateMessageSound: @escaping (PeerMessageSound) -> Void, updateGroupAlerts: @escaping (Bool) -> Void, updateGroupPreviews: @escaping (Bool) -> Void, updateGroupSound: @escaping (PeerMessageSound) -> Void, updateChannelAlerts: @escaping (Bool) -> Void, updateChannelPreviews: @escaping (Bool) -> Void, updateChannelSound: @escaping (PeerMessageSound) -> Void, updateInAppSounds: @escaping (Bool) -> Void, updateInAppVibration: @escaping (Bool) -> Void, updateInAppPreviews: @escaping (Bool) -> Void, updateDisplayNameOnLockscreen: @escaping (Bool) -> Void, updateTotalUnreadCountStyle: @escaping (Bool) -> Void, updateIncludeTag: @escaping (PeerSummaryCounterTags, Bool) -> Void, updateTotalUnreadCountCategory: @escaping (Bool) -> Void, resetNotifications: @escaping () -> Void, updatedExceptionMode: @escaping(NotificationExceptionMode) -> Void, openAppSettings: @escaping () -> Void, updateJoinedNotifications: @escaping (Bool) -> Void, updateNotificationsFromAllAccounts: @escaping (Bool) -> Void) { + init(context: AccountContextImpl, presentController: @escaping (ViewController, ViewControllerPresentationArguments?) -> Void, pushController: @escaping(ViewController)->Void, soundSelectionDisposable: MetaDisposable, authorizeNotifications: @escaping () -> Void, suppressWarning: @escaping () -> Void, updateMessageAlerts: @escaping (Bool) -> Void, updateMessagePreviews: @escaping (Bool) -> Void, updateMessageSound: @escaping (PeerMessageSound) -> Void, updateGroupAlerts: @escaping (Bool) -> Void, updateGroupPreviews: @escaping (Bool) -> Void, updateGroupSound: @escaping (PeerMessageSound) -> Void, updateChannelAlerts: @escaping (Bool) -> Void, updateChannelPreviews: @escaping (Bool) -> Void, updateChannelSound: @escaping (PeerMessageSound) -> Void, updateInAppSounds: @escaping (Bool) -> Void, updateInAppVibration: @escaping (Bool) -> Void, updateInAppPreviews: @escaping (Bool) -> Void, updateDisplayNameOnLockscreen: @escaping (Bool) -> Void, updateTotalUnreadCountStyle: @escaping (Bool) -> Void, updateIncludeTag: @escaping (PeerSummaryCounterTags, Bool) -> Void, updateTotalUnreadCountCategory: @escaping (Bool) -> Void, resetNotifications: @escaping () -> Void, updatedExceptionMode: @escaping(NotificationExceptionMode) -> Void, openAppSettings: @escaping () -> Void, updateJoinedNotifications: @escaping (Bool) -> Void, updateNotificationsFromAllAccounts: @escaping (Bool) -> Void) { self.context = context self.presentController = presentController self.pushController = pushController @@ -111,7 +112,7 @@ public enum NotificationsAndSoundsEntryTag: ItemListItemTag { case joinedNotifications case reset - func isEqual(to other: ItemListItemTag) -> Bool { + public func isEqual(to other: ItemListItemTag) -> Bool { if let other = other as? NotificationsAndSoundsEntryTag, self == other { return true } else { @@ -801,7 +802,7 @@ private func notificationsAndSoundsEntries(authorizationStatus: AccessType, warn return entries } -public func notificationsAndSoundsController(context: AccountContext, exceptionsList: NotificationExceptionsList?, focusOnItemTag: NotificationsAndSoundsEntryTag? = nil) -> ViewController { +public func notificationsAndSoundsController(context: AccountContextImpl, exceptionsList: NotificationExceptionsList?, focusOnItemTag: NotificationsAndSoundsEntryTag? = nil) -> ViewController { var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)? var pushControllerImpl: ((ViewController) -> Void)? diff --git a/submodules/TelegramUI/TelegramUI/OpenAddContact.swift b/submodules/TelegramUI/TelegramUI/OpenAddContact.swift index da1669eb36..b39dfd0f92 100644 --- a/submodules/TelegramUI/TelegramUI/OpenAddContact.swift +++ b/submodules/TelegramUI/TelegramUI/OpenAddContact.swift @@ -4,7 +4,7 @@ import TelegramCore import Display import DeviceAccess -func openAddContact(context: AccountContext, firstName: String = "", lastName: String = "", phoneNumber: String, label: String = "_$!!$_", present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, completed: @escaping () -> Void = {}) { +func openAddContact(context: AccountContextImpl, firstName: String = "", lastName: String = "", phoneNumber: String, label: String = "_$!!$_", present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, completed: @escaping () -> Void = {}) { let _ = (DeviceAccess.authorizationStatus(subject: .contacts) |> take(1) |> deliverOnMainQueue).start(next: { value in diff --git a/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift b/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift index b4d6f7a54a..76302f996f 100644 --- a/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift +++ b/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift @@ -24,7 +24,7 @@ private enum ChatMessageGalleryControllerData { case other(Media) } -private func chatMessageGalleryControllerData(context: AccountContext, message: Message, navigationController: NavigationController?, standalone: Bool, reverseMessageGalleryOrder: Bool, mode: ChatControllerInteractionOpenMessageMode, synchronousLoad: Bool, actionInteraction: GalleryControllerActionInteraction?) -> ChatMessageGalleryControllerData? { +private func chatMessageGalleryControllerData(context: AccountContextImpl, message: Message, navigationController: NavigationController?, standalone: Bool, reverseMessageGalleryOrder: Bool, mode: ChatControllerInteractionOpenMessageMode, synchronousLoad: Bool, actionInteraction: GalleryControllerActionInteraction?) -> ChatMessageGalleryControllerData? { var galleryMedia: Media? var otherMedia: Media? var instantPageMedia: (TelegramMediaWebpage, [InstantPageGalleryEntry])? @@ -179,7 +179,7 @@ enum ChatMessagePreviewControllerData { case gallery(GalleryController) } -func chatMessagePreviewControllerData(context: AccountContext, message: Message, standalone: Bool, reverseMessageGalleryOrder: Bool, navigationController: NavigationController?) -> ChatMessagePreviewControllerData? { +func chatMessagePreviewControllerData(context: AccountContextImpl, message: Message, standalone: Bool, reverseMessageGalleryOrder: Bool, navigationController: NavigationController?) -> ChatMessagePreviewControllerData? { if let mediaData = chatMessageGalleryControllerData(context: context, message: message, navigationController: navigationController, standalone: standalone, reverseMessageGalleryOrder: reverseMessageGalleryOrder, mode: .default, synchronousLoad: true, actionInteraction: nil) { switch mediaData { case let .gallery(gallery): @@ -193,7 +193,7 @@ func chatMessagePreviewControllerData(context: AccountContext, message: Message, return nil } -func openChatMessage(context: AccountContext, message: Message, standalone: Bool, reverseMessageGalleryOrder: Bool, mode: ChatControllerInteractionOpenMessageMode = .default, navigationController: NavigationController?, modal: Bool = false, dismissInput: @escaping () -> Void, present: @escaping (ViewController, Any?) -> Void, transitionNode: @escaping (MessageId, Media) -> (ASDisplayNode, () -> (UIView?, UIView?))?, addToTransitionSurface: @escaping (UIView) -> Void, openUrl: @escaping (String) -> Void, openPeer: @escaping (Peer, ChatControllerInteractionNavigateToPeer) -> Void, callPeer: @escaping (PeerId) -> Void, enqueueMessage: @escaping (EnqueueMessage) -> Void, sendSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)?, setupTemporaryHiddenMedia: @escaping (Signal, Int, Media) -> Void, chatAvatarHiddenMedia: @escaping (Signal, Media) -> Void, actionInteraction: GalleryControllerActionInteraction? = nil) -> Bool { +func openChatMessage(context: AccountContextImpl, message: Message, standalone: Bool, reverseMessageGalleryOrder: Bool, mode: ChatControllerInteractionOpenMessageMode = .default, navigationController: NavigationController?, modal: Bool = false, dismissInput: @escaping () -> Void, present: @escaping (ViewController, Any?) -> Void, transitionNode: @escaping (MessageId, Media) -> (ASDisplayNode, () -> (UIView?, UIView?))?, addToTransitionSurface: @escaping (UIView) -> Void, openUrl: @escaping (String) -> Void, openPeer: @escaping (Peer, ChatControllerInteractionNavigateToPeer) -> Void, callPeer: @escaping (PeerId) -> Void, enqueueMessage: @escaping (EnqueueMessage) -> Void, sendSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)?, setupTemporaryHiddenMedia: @escaping (Signal, Int, Media) -> Void, chatAvatarHiddenMedia: @escaping (Signal, Media) -> Void, actionInteraction: GalleryControllerActionInteraction? = nil) -> Bool { if let mediaData = chatMessageGalleryControllerData(context: context, message: message, navigationController: navigationController, standalone: standalone, reverseMessageGalleryOrder: reverseMessageGalleryOrder, mode: mode, synchronousLoad: false, actionInteraction: actionInteraction) { switch mediaData { case let .url(url): @@ -207,10 +207,7 @@ func openChatMessage(context: AccountContext, message: Message, standalone: Bool return } if data.complete, let content = try? Data(contentsOf: URL(fileURLWithPath: data.path)) { - var error: NSError? - let pass = PKPass(data: content, error: &error) - if error == nil { - let controller = PKAddPassesViewController(pass: pass) + if let pass = try? PKPass(data: content), let controller = PKAddPassesViewController(pass: pass) { if let window = navigationController.view.window { controller.popoverPresentationController?.sourceView = window controller.popoverPresentationController?.sourceRect = CGRect(origin: CGPoint(x: window.bounds.width / 2.0, y: window.bounds.size.height - 1.0), size: CGSize(width: 1.0, height: 1.0)) @@ -360,7 +357,7 @@ func openChatMessage(context: AccountContext, message: Message, standalone: Bool return false } -func openChatInstantPage(context: AccountContext, message: Message, sourcePeerType: MediaAutoDownloadPeerType?, navigationController: NavigationController) { +func openChatInstantPage(context: AccountContextImpl, message: Message, sourcePeerType: MediaAutoDownloadPeerType?, navigationController: NavigationController) { for media in message.media { if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content { if let _ = content.instantPage { @@ -410,7 +407,7 @@ func openChatInstantPage(context: AccountContext, message: Message, sourcePeerTy } } -func openChatWallpaper(context: AccountContext, message: Message, present: @escaping (ViewController, Any?) -> Void) { +func openChatWallpaper(context: AccountContextImpl, message: Message, present: @escaping (ViewController, Any?) -> Void) { for media in message.media { if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content { let _ = (resolveUrl(account: context.account, url: content.url) diff --git a/submodules/TelegramUI/TelegramUI/OpenInActionSheetController.swift b/submodules/TelegramUI/TelegramUI/OpenInActionSheetController.swift index aedc3e4b1d..ba6fc7534a 100644 --- a/submodules/TelegramUI/TelegramUI/OpenInActionSheetController.swift +++ b/submodules/TelegramUI/TelegramUI/OpenInActionSheetController.swift @@ -21,7 +21,7 @@ final class OpenInActionSheetController: ActionSheetController { return self._ready } - init(context: AccountContext, item: OpenInItem, additionalAction: OpenInControllerAction? = nil, openUrl: @escaping (String) -> Void) { + init(context: AccountContextImpl, item: OpenInItem, additionalAction: OpenInControllerAction? = nil, openUrl: @escaping (String) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings @@ -86,12 +86,12 @@ final class OpenInActionSheetController: ActionSheetController { private final class OpenInActionSheetItem: ActionSheetItem { let postbox: Postbox - let context: AccountContext + let context: AccountContextImpl let strings: PresentationStrings let options: [OpenInOption] let invokeAction: (OpenInAction) -> Void - init(postbox: Postbox, context: AccountContext, strings: PresentationStrings, options: [OpenInOption], invokeAction: @escaping (OpenInAction) -> Void) { + init(postbox: Postbox, context: AccountContextImpl, strings: PresentationStrings, options: [OpenInOption], invokeAction: @escaping (OpenInAction) -> Void) { self.postbox = postbox self.context = context self.strings = strings @@ -119,7 +119,7 @@ private final class OpenInActionSheetItemNode: ActionSheetItemNode { let openInNodes: [OpenInAppNode] - init(postbox: Postbox, context: AccountContext, theme: ActionSheetControllerTheme, strings: PresentationStrings, options: [OpenInOption], invokeAction: @escaping (OpenInAction) -> Void) { + init(postbox: Postbox, context: AccountContextImpl, theme: ActionSheetControllerTheme, strings: PresentationStrings, options: [OpenInOption], invokeAction: @escaping (OpenInAction) -> Void) { self.theme = theme self.strings = strings @@ -206,7 +206,7 @@ private final class OpenInAppNode : ASDisplayNode { self.addSubnode(self.textNode) } - func setup(postbox: Postbox, context: AccountContext, theme: ActionSheetControllerTheme, option: OpenInOption, invokeAction: @escaping (OpenInAction) -> Void) { + func setup(postbox: Postbox, context: AccountContextImpl, theme: ActionSheetControllerTheme, option: OpenInOption, invokeAction: @escaping (OpenInAction) -> Void) { self.textNode.attributedText = NSAttributedString(string: option.title, font: textFont, textColor: theme.primaryTextColor, paragraphAlignment: .center) let iconSize = CGSize(width: 60.0, height: 60.0) diff --git a/submodules/TelegramUI/TelegramUI/OpenInOptions.swift b/submodules/TelegramUI/TelegramUI/OpenInOptions.swift index 1a5e612612..0cc35bd781 100644 --- a/submodules/TelegramUI/TelegramUI/OpenInOptions.swift +++ b/submodules/TelegramUI/TelegramUI/OpenInOptions.swift @@ -44,7 +44,7 @@ final class OpenInOption { } } -func availableOpenInOptions(context: AccountContext, item: OpenInItem) -> [OpenInOption] { +func availableOpenInOptions(context: AccountContextImpl, item: OpenInItem) -> [OpenInOption] { return allOpenInOptions(context: context, item: item).filter { option in if case let .other(_, _, scheme, _) = option.application { return context.sharedContext.applicationBindings.canOpenUrl("\(scheme)://") @@ -54,7 +54,7 @@ func availableOpenInOptions(context: AccountContext, item: OpenInItem) -> [OpenI } } -private func allOpenInOptions(context: AccountContext, item: OpenInItem) -> [OpenInOption] { +private func allOpenInOptions(context: AccountContextImpl, item: OpenInItem) -> [OpenInOption] { var options: [OpenInOption] = [] switch item { case let .url(url): diff --git a/submodules/TelegramUI/TelegramUI/OpenResolvedUrl.swift b/submodules/TelegramUI/TelegramUI/OpenResolvedUrl.swift index 21189a85a6..1110bb1c42 100644 --- a/submodules/TelegramUI/TelegramUI/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/TelegramUI/OpenResolvedUrl.swift @@ -22,7 +22,7 @@ private func defaultNavigationForPeerId(_ peerId: PeerId?, navigation: ChatContr } } -func openResolvedUrl(_ resolvedUrl: ResolvedUrl, context: AccountContext, urlContext: OpenURLContext = .generic, navigationController: NavigationController?, openPeer: @escaping (PeerId, ChatControllerInteractionNavigateToPeer) -> Void, sendFile: ((FileMediaReference) -> Void)? = nil, sendSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)? = nil, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void) { +func openResolvedUrl(_ resolvedUrl: ResolvedUrl, context: AccountContextImpl, urlContext: OpenURLContext = .generic, navigationController: NavigationController?, openPeer: @escaping (PeerId, ChatControllerInteractionNavigateToPeer) -> Void, sendFile: ((FileMediaReference) -> Void)? = nil, sendSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)? = nil, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } switch resolvedUrl { case let .externalUrl(url): diff --git a/submodules/TelegramUI/TelegramUI/OpenSettings.swift b/submodules/TelegramUI/TelegramUI/OpenSettings.swift index 9c1b10095a..8f5455567f 100644 --- a/submodules/TelegramUI/TelegramUI/OpenSettings.swift +++ b/submodules/TelegramUI/TelegramUI/OpenSettings.swift @@ -6,7 +6,7 @@ import TelegramCore private let maximumNumberOfAccounts = 3 -func openEditSettings(context: AccountContext, accountsAndPeers: Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError>, focusOnItemTag: EditSettingsEntryTag? = nil, presentController: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void) -> Disposable { +func openEditSettings(context: AccountContextImpl, accountsAndPeers: Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError>, focusOnItemTag: EditSettingsEntryTag? = nil, presentController: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void) -> Disposable { let openEditingDisposable = MetaDisposable() var cancelImpl: (() -> Void)? let presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/OpenUrl.swift b/submodules/TelegramUI/TelegramUI/OpenUrl.swift index bcc25d3423..8bebf26b2a 100644 --- a/submodules/TelegramUI/TelegramUI/OpenUrl.swift +++ b/submodules/TelegramUI/TelegramUI/OpenUrl.swift @@ -10,6 +10,7 @@ import MtProtoKit import MtProtoKitDynamic #endif import TelegramPresentationData +import AccountContext public struct ParsedSecureIdUrl { public let peerId: PeerId @@ -139,7 +140,7 @@ public enum OpenURLContext { case chat } -public func openExternalUrl(context: AccountContext, urlContext: OpenURLContext = .generic, url: String, forceExternal: Bool = false, presentationData: PresentationData, navigationController: NavigationController?, dismissInput: @escaping () -> Void) { +public func openExternalUrl(context: AccountContextImpl, urlContext: OpenURLContext = .generic, url: String, forceExternal: Bool = false, presentationData: PresentationData, navigationController: NavigationController?, dismissInput: @escaping () -> Void) { if forceExternal || url.lowercased().hasPrefix("tel:") || url.lowercased().hasPrefix("calshow:") { context.sharedContext.applicationBindings.openUrl(url) return diff --git a/submodules/TelegramUI/TelegramUI/OverlayPlayerController.swift b/submodules/TelegramUI/TelegramUI/OverlayPlayerController.swift index f3446a7fbb..f67b492a9c 100644 --- a/submodules/TelegramUI/TelegramUI/OverlayPlayerController.swift +++ b/submodules/TelegramUI/TelegramUI/OverlayPlayerController.swift @@ -7,7 +7,7 @@ import SwiftSignalKit import TelegramUIPreferences final class OverlayPlayerController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl let peerId: PeerId let type: MediaManagerPlayerType let initialMessageId: MessageId @@ -23,7 +23,7 @@ final class OverlayPlayerController: ViewController { private var accountInUseDisposable: Disposable? - init(context: AccountContext, peerId: PeerId, type: MediaManagerPlayerType, initialMessageId: MessageId, initialOrder: MusicPlaybackSettingsOrder, parentNavigationController: NavigationController?) { + init(context: AccountContextImpl, peerId: PeerId, type: MediaManagerPlayerType, initialMessageId: MessageId, initialOrder: MusicPlaybackSettingsOrder, parentNavigationController: NavigationController?) { self.context = context self.peerId = peerId self.type = type diff --git a/submodules/TelegramUI/TelegramUI/OverlayPlayerControllerNode.swift b/submodules/TelegramUI/TelegramUI/OverlayPlayerControllerNode.swift index a06a008712..53d89b9773 100644 --- a/submodules/TelegramUI/TelegramUI/OverlayPlayerControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/OverlayPlayerControllerNode.swift @@ -11,7 +11,7 @@ import TelegramUIPreferences final class OverlayPlayerControllerNode: ViewControllerTracingNode, UIGestureRecognizerDelegate { let ready = Promise() - private let context: AccountContext + private let context: AccountContextImpl private let peerId: PeerId private var presentationData: PresentationData private let type: MediaManagerPlayerType @@ -37,7 +37,7 @@ final class OverlayPlayerControllerNode: ViewControllerTracingNode, UIGestureRec private var presentationDataDisposable: Disposable? private let replacementHistoryNodeReadyDisposable = MetaDisposable() - init(context: AccountContext, peerId: PeerId, type: MediaManagerPlayerType, initialMessageId: MessageId, initialOrder: MusicPlaybackSettingsOrder, requestDismiss: @escaping () -> Void, requestShare: @escaping (MessageId) -> Void) { + init(context: AccountContextImpl, peerId: PeerId, type: MediaManagerPlayerType, initialMessageId: MessageId, initialOrder: MusicPlaybackSettingsOrder, requestDismiss: @escaping () -> Void, requestShare: @escaping (MessageId) -> Void) { self.context = context self.peerId = peerId self.presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -381,14 +381,14 @@ final class OverlayPlayerControllerNode: ViewControllerTracingNode, UIGestureRec var bounds = self.bounds bounds.origin.y = 0.0 self.contentNode.bounds = bounds - self.contentNode.layer.animateBounds(from: previousBounds, to: self.contentNode.bounds, duration: 0.3, timingFunction: kCAMediaTimingFunctionEaseInEaseOut) + self.contentNode.layer.animateBounds(from: previousBounds, to: self.contentNode.bounds, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue) } case .cancelled: let previousBounds = self.contentNode.bounds var bounds = self.contentNode.bounds bounds.origin.y = 0.0 self.contentNode.bounds = bounds - self.contentNode.layer.animateBounds(from: previousBounds, to: self.contentNode.bounds, duration: 0.3, timingFunction: kCAMediaTimingFunctionEaseInEaseOut) + self.contentNode.layer.animateBounds(from: previousBounds, to: self.contentNode.bounds, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue) default: break } diff --git a/submodules/TelegramUI/TelegramUI/OverlayPlayerControlsNode.swift b/submodules/TelegramUI/TelegramUI/OverlayPlayerControlsNode.swift index cc429c15ca..13848820cb 100644 --- a/submodules/TelegramUI/TelegramUI/OverlayPlayerControlsNode.swift +++ b/submodules/TelegramUI/TelegramUI/OverlayPlayerControlsNode.swift @@ -482,7 +482,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode { if animateIn && transition.isAnimated { largeAlbumArtNode.frame = largeAlbumArtFrame transition.animatePositionAdditive(node: largeAlbumArtNode, offset: CGPoint(x: previousAlbumArtNodeFrame.center.x - largeAlbumArtFrame.center.x, y: previousAlbumArtNodeFrame.center.y - largeAlbumArtFrame.center.y)) - //largeAlbumArtNode.layer.animatePosition(from: CGPoint(x: -50.0, y: 0.0), to: CGPoint(), duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, additive: true) + //largeAlbumArtNode.layer.animatePosition(from: CGPoint(x: -50.0, y: 0.0), to: CGPoint(), duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, additive: true) transition.animateTransformScale(node: largeAlbumArtNode, from: previousAlbumArtNodeFrame.size.height / largeAlbumArtFrame.size.height) largeAlbumArtNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.12) if let copyView = self.albumArtNode.view.snapshotContentTree() { @@ -492,7 +492,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode { transition.animatePositionAdditive(layer: copyView.layer, offset: CGPoint(x: previousAlbumArtNodeFrame.center.x - largeAlbumArtFrame.center.x, y: previousAlbumArtNodeFrame.center.y - largeAlbumArtFrame.center.y), completion: { [weak copyView] in copyView?.removeFromSuperview() }) - //copyView.layer.animatePosition(from: CGPoint(x: -50.0, y: 0.0), to: CGPoint(), duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, additive: true) + //copyView.layer.animatePosition(from: CGPoint(x: -50.0, y: 0.0), to: CGPoint(), duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, additive: true) copyView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.28, removeOnCompletion: false) transition.updateTransformScale(layer: copyView.layer, scale: largeAlbumArtFrame.size.height / previousAlbumArtNodeFrame.size.height) } diff --git a/submodules/TelegramUI/TelegramUI/PaneSearchBarNode.swift b/submodules/TelegramUI/TelegramUI/PaneSearchBarNode.swift index 8f54e5ab9c..bd33c25ea0 100644 --- a/submodules/TelegramUI/TelegramUI/PaneSearchBarNode.swift +++ b/submodules/TelegramUI/TelegramUI/PaneSearchBarNode.swift @@ -4,6 +4,7 @@ import SwiftSignalKit import AsyncDisplayKit import Display import TelegramPresentationData +import ActivityIndicator private func generateLoupeIcon(color: UIColor) -> UIImage? { return generateTintedImage(image: UIImage(bundleImageName: "Components/Search Bar/Loupe"), color: color) @@ -336,7 +337,7 @@ class PaneSearchBarNode: ASDisplayNode, UITextFieldDelegate { let initialBackgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: self.bounds.size.width, height: max(0.0, initialTextBackgroundFrame.maxY + 8.0))) if let fromBackgroundColor = node.backgroundColor, let toBackgroundColor = self.backgroundNode.backgroundColor { - self.backgroundNode.layer.animate(from: fromBackgroundColor.cgColor, to: toBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: duration * 0.7) + self.backgroundNode.layer.animate(from: fromBackgroundColor.cgColor, to: toBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: duration * 0.7) } else { self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration) } @@ -400,7 +401,7 @@ class PaneSearchBarNode: ASDisplayNode, UITextFieldDelegate { let targetBackgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: self.bounds.size.width, height: max(0.0, targetTextBackgroundFrame.maxY + 8.0))) if let toBackgroundColor = node.backgroundColor, let fromBackgroundColor = self.backgroundNode.backgroundColor { - self.backgroundNode.layer.animate(from: fromBackgroundColor.cgColor, to: toBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: duration * 0.5, removeOnCompletion: false) + self.backgroundNode.layer.animate(from: fromBackgroundColor.cgColor, to: toBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: duration * 0.5, removeOnCompletion: false) } else { self.backgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration / 2.0, removeOnCompletion: false) } @@ -436,8 +437,8 @@ class PaneSearchBarNode: ASDisplayNode, UITextFieldDelegate { if let snapshot = node.labelNode.layer.snapshotContentTree() { snapshot.frame = CGRect(origin: self.textField.placeholderLabel.frame.origin, size: node.labelNode.frame.size) self.textField.layer.addSublayer(snapshot) - snapshot.animateAlpha(from: 0.0, to: 1.0, duration: duration * 2.0 / 3.0, timingFunction: kCAMediaTimingFunctionLinear) - self.textField.placeholderLabel.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration * 3.0 / 2.0, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false) + snapshot.animateAlpha(from: 0.0, to: 1.0, duration: duration * 2.0 / 3.0, timingFunction: CAMediaTimingFunctionName.linear.rawValue) + self.textField.placeholderLabel.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration * 3.0 / 2.0, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false) } diff --git a/submodules/TelegramUI/TelegramUI/PaneSearchContainerNode.swift b/submodules/TelegramUI/TelegramUI/PaneSearchContainerNode.swift index 862508da9c..8fc09763bc 100644 --- a/submodules/TelegramUI/TelegramUI/PaneSearchContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/PaneSearchContainerNode.swift @@ -26,7 +26,7 @@ protocol PaneSearchContentNode { } final class PaneSearchContainerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private let mode: ChatMediaInputSearchMode public private(set) var contentNode: PaneSearchContentNode & ASDisplayNode private let controllerInteraction: ChatControllerInteraction @@ -41,7 +41,7 @@ final class PaneSearchContainerNode: ASDisplayNode { return self.contentNode.ready } - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction, mode: ChatMediaInputSearchMode, trendingGifsPromise: Promise<[FileMediaReference]?>, cancel: @escaping () -> Void) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction, mode: ChatMediaInputSearchMode, trendingGifsPromise: Promise<[FileMediaReference]?>, cancel: @escaping () -> Void) { self.context = context self.mode = mode self.controllerInteraction = controllerInteraction diff --git a/submodules/TelegramUI/TelegramUI/PasscodeEntryController.swift b/submodules/TelegramUI/TelegramUI/PasscodeEntryController.swift index dcf47391ba..be79aa49c2 100644 --- a/submodules/TelegramUI/TelegramUI/PasscodeEntryController.swift +++ b/submodules/TelegramUI/TelegramUI/PasscodeEntryController.swift @@ -31,7 +31,7 @@ final public class PasscodeEntryController: ViewController { return self.displayNode as! PasscodeEntryControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private var presentationDataDisposable: Disposable? @@ -49,7 +49,7 @@ final public class PasscodeEntryController: ViewController { private var inBackground: Bool = false private var inBackgroundDisposable: Disposable? - public init(context: AccountContext, challengeData: PostboxAccessChallengeData, biometrics: PasscodeEntryControllerBiometricsMode, arguments: PasscodeEntryControllerPresentationArguments) { + public init(context: AccountContextImpl, challengeData: PostboxAccessChallengeData, biometrics: PasscodeEntryControllerBiometricsMode, arguments: PasscodeEntryControllerPresentationArguments) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.challengeData = challengeData diff --git a/submodules/TelegramUI/TelegramUI/PasscodeEntryControllerNode.swift b/submodules/TelegramUI/TelegramUI/PasscodeEntryControllerNode.swift index 5f40b7e5e9..e7ca7357cf 100644 --- a/submodules/TelegramUI/TelegramUI/PasscodeEntryControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/PasscodeEntryControllerNode.swift @@ -12,7 +12,7 @@ private let subtitleFont = Font.regular(15.0) private let buttonFont = Font.regular(17.0) final class PasscodeEntryControllerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private var theme: PresentationTheme private var strings: PresentationStrings private var wallpaper: TelegramWallpaper @@ -44,7 +44,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode { var checkPasscode: ((String) -> Void)? var requestBiometrics: (() -> Void)? - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper, passcodeType: PasscodeEntryFieldType, biometricsType: LocalAuthBiometricAuthentication?, arguments: PasscodeEntryControllerPresentationArguments, statusBar: StatusBar) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper, passcodeType: PasscodeEntryFieldType, biometricsType: LocalAuthBiometricAuthentication?, arguments: PasscodeEntryControllerPresentationArguments, statusBar: StatusBar) { self.context = context self.theme = theme self.strings = strings @@ -230,7 +230,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode { } func hideBiometrics() { - self.biometricButtonNode.layer.animateScale(from: 1.0, to: 0.00001, duration: 0.25, delay: 0.0, timingFunction: kCAMediaTimingFunctionEaseOut, completion: { [weak self] _ in + self.biometricButtonNode.layer.animateScale(from: 1.0, to: 0.00001, duration: 0.25, delay: 0.0, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, completion: { [weak self] _ in self?.biometricButtonNode.isHidden = true }) self.animateError() @@ -292,10 +292,10 @@ final class PasscodeEntryControllerNode: ASDisplayNode { if case .alphanumeric = self.passcodeType { biometricDelay = 0.0 } else { - self.cancelButtonNode.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, delay: 0.15, timingFunction: kCAMediaTimingFunctionEaseOut) - self.deleteButtonNode.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, delay: 0.15, timingFunction: kCAMediaTimingFunctionEaseOut) + self.cancelButtonNode.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, delay: 0.15, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue) + self.deleteButtonNode.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, delay: 0.15, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue) } - self.biometricButtonNode.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, delay: biometricDelay, timingFunction: kCAMediaTimingFunctionEaseOut) + self.biometricButtonNode.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, delay: biometricDelay, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue) Queue.mainQueue().after(1.5, { self.titleNode.setAttributedText(NSAttributedString(string: self.strings.EnterPasscode_EnterPasscode, font: titleFont, textColor: .white), animation: .crossFade) diff --git a/submodules/TelegramUI/TelegramUI/PasscodeEntryInputFieldNode.swift b/submodules/TelegramUI/TelegramUI/PasscodeEntryInputFieldNode.swift index 8ee0e18c69..a40c7ef3db 100644 --- a/submodules/TelegramUI/TelegramUI/PasscodeEntryInputFieldNode.swift +++ b/submodules/TelegramUI/TelegramUI/PasscodeEntryInputFieldNode.swift @@ -115,7 +115,7 @@ private class PasscodeEntryDotNode: ASImageNode { let currentContents = self.layer.contents self.layer.removeAnimation(forKey: "contents") if let currentContents = currentContents, animated { - self.layer.animate(from: currentContents as AnyObject, to: image.cgImage!, keyPath: "contents", timingFunction: kCAMediaTimingFunctionEaseOut, duration: image === self.regularImage ? 0.25 : 0.05, delay: delay, removeOnCompletion: false, completion: { finished in + self.layer.animate(from: currentContents as AnyObject, to: image.cgImage!, keyPath: "contents", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, duration: image === self.regularImage ? 0.25 : 0.05, delay: delay, removeOnCompletion: false, completion: { finished in if finished { self.image = image } @@ -221,11 +221,11 @@ final class PasscodeEntryInputFieldNode: ASDisplayNode, UITextFieldDelegate { switch self.fieldType { case .digits6, .digits4: for node in self.dotNodes { - node.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, timingFunction: kCAMediaTimingFunctionEaseOut) + node.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue) } case .alphanumeric: - self.textFieldNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, timingFunction: kCAMediaTimingFunctionEaseOut) - self.borderNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, timingFunction: kCAMediaTimingFunctionEaseOut) + self.textFieldNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue) + self.borderNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue) } } diff --git a/submodules/TelegramUI/TelegramUI/PasscodeEntryKeyboardNode.swift b/submodules/TelegramUI/TelegramUI/PasscodeEntryKeyboardNode.swift index 74dd9731f1..0b5ecfd7e0 100644 --- a/submodules/TelegramUI/TelegramUI/PasscodeEntryKeyboardNode.swift +++ b/submodules/TelegramUI/TelegramUI/PasscodeEntryKeyboardNode.swift @@ -152,7 +152,7 @@ final class PasscodeEntryButtonNode: HighlightTrackingButtonNode { self.backgroundNode.layer.removeAnimation(forKey: "contents") if let currentContents = currentContents, let image = image { self.backgroundNode.image = image - self.backgroundNode.layer.animate(from: currentContents as AnyObject, to: image.cgImage!, keyPath: "contents", timingFunction: kCAMediaTimingFunctionEaseOut, duration: image === self.regularImage ? 0.45 : 0.05) + self.backgroundNode.layer.animate(from: currentContents as AnyObject, to: image.cgImage!, keyPath: "contents", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, duration: image === self.regularImage ? 0.45 : 0.05) } else { self.backgroundNode.image = image } @@ -230,7 +230,7 @@ final class PasscodeEntryKeyboardNode: ASDisplayNode { else if i / 3 == 3 { delay = 0.15 } - subnode.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, delay: delay, timingFunction: kCAMediaTimingFunctionEaseOut) + subnode.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, delay: delay, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue) } } } diff --git a/submodules/TelegramUI/TelegramUI/PasscodeLockIconNode.swift b/submodules/TelegramUI/TelegramUI/PasscodeLockIconNode.swift index f670bce2ce..a054f03202 100644 --- a/submodules/TelegramUI/TelegramUI/PasscodeLockIconNode.swift +++ b/submodules/TelegramUI/TelegramUI/PasscodeLockIconNode.swift @@ -62,7 +62,7 @@ final class PasscodeLockIconNode: ASDisplayNode { }) as! POPAnimatableProperty) animation.fromValue = 0.0 as NSNumber animation.toValue = 1.0 as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 0.55 self.pop_add(animation, forKey: "progress") } @@ -84,7 +84,7 @@ final class PasscodeLockIconNode: ASDisplayNode { }) as! POPAnimatableProperty) animation.fromValue = 1.0 as NSNumber animation.toValue = 0.0 as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 0.75 self.pop_add(animation, forKey: "progress") } diff --git a/submodules/TelegramUI/TelegramUI/PasscodeOptionsController.swift b/submodules/TelegramUI/TelegramUI/PasscodeOptionsController.swift index ef60ad7596..d2bb122343 100644 --- a/submodules/TelegramUI/TelegramUI/PasscodeOptionsController.swift +++ b/submodules/TelegramUI/TelegramUI/PasscodeOptionsController.swift @@ -8,6 +8,7 @@ import LegacyComponents import LocalAuthentication import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class PasscodeOptionsControllerArguments { let turnPasscodeOff: () -> Void @@ -198,7 +199,7 @@ private func passcodeOptionsControllerEntries(presentationData: PresentationData return entries } -func passcodeOptionsController(context: AccountContext) -> ViewController { +func passcodeOptionsController(context: AccountContextImpl) -> ViewController { let initialState = PasscodeOptionsControllerState() let statePromise = ValuePromise(initialState, ignoreRepeated: true) @@ -382,7 +383,7 @@ func passcodeOptionsController(context: AccountContext) -> ViewController { return controller } -public func passcodeOptionsAccessController(context: AccountContext, animateIn: Bool = true, pushController: ((ViewController) -> Void)?, completion: @escaping (Bool) -> Void) -> Signal { +public func passcodeOptionsAccessController(context: AccountContextImpl, animateIn: Bool = true, pushController: ((ViewController) -> Void)?, completion: @escaping (Bool) -> Void) -> Signal { return context.sharedContext.accountManager.transaction { transaction -> PostboxAccessChallengeData in return transaction.getAccessChallengeData() } @@ -436,7 +437,7 @@ public func passcodeOptionsAccessController(context: AccountContext, animateIn: } } -public func passcodeEntryController(context: AccountContext, animateIn: Bool = true, completion: @escaping (Bool) -> Void) -> Signal { +public func passcodeEntryController(context: AccountContextImpl, animateIn: Bool = true, completion: @escaping (Bool) -> Void) -> Signal { return context.sharedContext.accountManager.transaction { transaction -> PostboxAccessChallengeData in return transaction.getAccessChallengeData() } diff --git a/submodules/TelegramUI/TelegramUI/PasscodeSetupController.swift b/submodules/TelegramUI/TelegramUI/PasscodeSetupController.swift index 5b006850b5..13b32dd987 100644 --- a/submodules/TelegramUI/TelegramUI/PasscodeSetupController.swift +++ b/submodules/TelegramUI/TelegramUI/PasscodeSetupController.swift @@ -17,7 +17,7 @@ final class PasscodeSetupController: ViewController { return self.displayNode as! PasscodeSetupControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private var mode: PasscodeSetupControllerMode var complete: ((String, Bool) -> Void)? @@ -29,7 +29,7 @@ final class PasscodeSetupController: ViewController { private var nextAction: UIBarButtonItem? - init(context: AccountContext, mode: PasscodeSetupControllerMode) { + init(context: AccountContextImpl, mode: PasscodeSetupControllerMode) { self.context = context self.mode = mode self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/Pasteboard.swift b/submodules/TelegramUI/TelegramUI/Pasteboard.swift index 7b10d9ea40..a33c873b5b 100644 --- a/submodules/TelegramUI/TelegramUI/Pasteboard.swift +++ b/submodules/TelegramUI/TelegramUI/Pasteboard.swift @@ -3,6 +3,7 @@ import UIKit import Display import TelegramCore import MobileCoreServices +import TextFormat private func rtfStringWithAppliedEntities(_ text: String, entities: [MessageTextEntity]) -> String { let test = stringWithAppliedEntities(text, entities: entities, baseColor: .black, linkColor: .black, baseFont: Font.regular(14.0), linkFont: Font.regular(14.0), boldFont: Font.semibold(14.0), italicFont: Font.italic(14.0), boldItalicFont: Font.semiboldItalic(14.0), fixedFont: Font.monospace(14.0), blockQuoteFont: Font.regular(14.0), underlineLinks: false, external: true) diff --git a/submodules/TelegramUI/TelegramUI/PeerAvatarImageGalleryItem.swift b/submodules/TelegramUI/TelegramUI/PeerAvatarImageGalleryItem.swift index 2b289a341d..63119cb595 100644 --- a/submodules/TelegramUI/TelegramUI/PeerAvatarImageGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/PeerAvatarImageGalleryItem.swift @@ -36,13 +36,13 @@ private struct PeerAvatarImageGalleryThumbnailItem: GalleryThumbnailItem { } class PeerAvatarImageGalleryItem: GalleryItem { - let context: AccountContext + let context: AccountContextImpl let peer: Peer let presentationData: PresentationData let entry: AvatarGalleryEntry let delete: (() -> Void)? - init(context: AccountContext, peer: Peer, presentationData: PresentationData, entry: AvatarGalleryEntry, delete: (() -> Void)?) { + init(context: AccountContextImpl, peer: Peer, presentationData: PresentationData, entry: AvatarGalleryEntry, delete: (() -> Void)?) { self.context = context self.peer = peer self.presentationData = presentationData @@ -88,7 +88,7 @@ class PeerAvatarImageGalleryItem: GalleryItem { } final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode { - private let context: AccountContext + private let context: AccountContextImpl private let peer: Peer private var entry: AvatarGalleryEntry? @@ -104,7 +104,7 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode { private let statusDisposable = MetaDisposable() private var status: MediaResourceStatus? - init(context: AccountContext, presentationData: PresentationData, peer: Peer) { + init(context: AccountContextImpl, presentationData: PresentationData, peer: Peer) { self.context = context self.peer = peer @@ -252,7 +252,7 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode { self.imageNode.layer.animate(from: NSValue(caTransform3D: transform), to: NSValue(caTransform3D: self.imageNode.layer.transform), keyPath: "transform", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.25) self.imageNode.clipsToBounds = true - self.imageNode.layer.animate(from: (self.imageNode.frame.width / 2.0) as NSNumber, to: 0.0 as NSNumber, keyPath: "cornerRadius", timingFunction: kCAMediaTimingFunctionDefault, duration: 0.18, removeOnCompletion: false, completion: { [weak self] value in + self.imageNode.layer.animate(from: (self.imageNode.frame.width / 2.0) as NSNumber, to: 0.0 as NSNumber, keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.default.rawValue, duration: 0.18, removeOnCompletion: false, completion: { [weak self] value in if value { self?.imageNode.clipsToBounds = false } @@ -312,10 +312,10 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode { }) self.imageNode.clipsToBounds = true - self.imageNode.layer.animate(from: 0.0 as NSNumber, to: (self.imageNode.frame.width / 2.0) as NSNumber, keyPath: "cornerRadius", timingFunction: kCAMediaTimingFunctionDefault, duration: 0.18 * durationFactor, removeOnCompletion: false) + self.imageNode.layer.animate(from: 0.0 as NSNumber, to: (self.imageNode.frame.width / 2.0) as NSNumber, keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.default.rawValue, duration: 0.18 * durationFactor, removeOnCompletion: false) self.statusNodeContainer.layer.animatePosition(from: self.statusNodeContainer.position, to: CGPoint(x: transformedSuperFrame.midX, y: transformedSuperFrame.midY), duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false) - self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false) + self.statusNodeContainer.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false) } override func visibilityUpdated(isVisible: Bool) { diff --git a/submodules/TelegramUI/TelegramUI/PeerBanTimeoutController.swift b/submodules/TelegramUI/TelegramUI/PeerBanTimeoutController.swift index a51b481155..6bf063f91b 100644 --- a/submodules/TelegramUI/TelegramUI/PeerBanTimeoutController.swift +++ b/submodules/TelegramUI/TelegramUI/PeerBanTimeoutController.swift @@ -15,7 +15,7 @@ final class PeerBanTimeoutController: ActionSheetController { return self._ready } - init(context: AccountContext, currentValue: Int32, applyValue: @escaping (Int32?) -> Void) { + init(context: AccountContextImpl, currentValue: Int32, applyValue: @escaping (Int32?) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/PeerInfoController.swift b/submodules/TelegramUI/TelegramUI/PeerInfoController.swift index 45283a9dbf..c6ae99d8a7 100644 --- a/submodules/TelegramUI/TelegramUI/PeerInfoController.swift +++ b/submodules/TelegramUI/TelegramUI/PeerInfoController.swift @@ -5,7 +5,7 @@ import Postbox import SwiftSignalKit import TelegramCore -func peerInfoController(context: AccountContext, peer: Peer) -> ViewController? { +func peerInfoController(context: AccountContextImpl, peer: Peer) -> ViewController? { if let _ = peer as? TelegramGroup { return groupInfoController(context: context, peerId: peer.id) } else if let channel = peer as? TelegramChannel { diff --git a/submodules/TelegramUI/TelegramUI/PeerMediaCollectionController.swift b/submodules/TelegramUI/TelegramUI/PeerMediaCollectionController.swift index dd29d44265..fc29ca3c2c 100644 --- a/submodules/TelegramUI/TelegramUI/PeerMediaCollectionController.swift +++ b/submodules/TelegramUI/TelegramUI/PeerMediaCollectionController.swift @@ -12,7 +12,7 @@ import TelegramUIPreferences public class PeerMediaCollectionController: TelegramController { private var validLayout: ContainerViewLayout? - private let context: AccountContext + private let context: AccountContextImpl private let peerId: PeerId private let messageId: MessageId? @@ -42,7 +42,7 @@ public class PeerMediaCollectionController: TelegramController { private var resolveUrlDisposable: MetaDisposable? - public init(context: AccountContext, peerId: PeerId, messageId: MessageId? = nil) { + public init(context: AccountContextImpl, peerId: PeerId, messageId: MessageId? = nil) { self.context = context self.peerId = peerId self.messageId = messageId diff --git a/submodules/TelegramUI/TelegramUI/PeerMediaCollectionControllerNode.swift b/submodules/TelegramUI/TelegramUI/PeerMediaCollectionControllerNode.swift index 176542901d..d6c4a47f8d 100644 --- a/submodules/TelegramUI/TelegramUI/PeerMediaCollectionControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/PeerMediaCollectionControllerNode.swift @@ -12,7 +12,7 @@ struct PeerMediaCollectionMessageForGallery { let fromSearchResults: Bool } -private func historyNodeImplForMode(_ mode: PeerMediaCollectionMode, context: AccountContext, theme: PresentationTheme, peerId: PeerId, messageId: MessageId?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal?, NoError>) -> ChatHistoryNode & ASDisplayNode { +private func historyNodeImplForMode(_ mode: PeerMediaCollectionMode, context: AccountContextImpl, theme: PresentationTheme, peerId: PeerId, messageId: MessageId?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal?, NoError>) -> ChatHistoryNode & ASDisplayNode { switch mode { case .photoOrVideo: let node = ChatHistoryGridNode(context: context, peerId: peerId, messageId: messageId, tagMask: .photoOrVideo, controllerInteraction: controllerInteraction) @@ -92,7 +92,7 @@ private func tagMaskForMode(_ mode: PeerMediaCollectionMode) -> MessageTags { } class PeerMediaCollectionControllerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private let peerId: PeerId private let controllerInteraction: ChatControllerInteraction private let interfaceInteraction: ChatPanelInterfaceInteraction @@ -132,7 +132,7 @@ class PeerMediaCollectionControllerNode: ASDisplayNode { private var presentationData: PresentationData - init(context: AccountContext, peerId: PeerId, messageId: MessageId?, controllerInteraction: ChatControllerInteraction, interfaceInteraction: ChatPanelInterfaceInteraction, navigationBar: NavigationBar?, requestDeactivateSearch: @escaping () -> Void) { + init(context: AccountContextImpl, peerId: PeerId, messageId: MessageId?, controllerInteraction: ChatControllerInteraction, interfaceInteraction: ChatPanelInterfaceInteraction, navigationBar: NavigationBar?, requestDeactivateSearch: @escaping () -> Void) { self.context = context self.peerId = peerId self.controllerInteraction = controllerInteraction diff --git a/submodules/TelegramUI/TelegramUI/PeerMediaCollectionEmptyNode.swift b/submodules/TelegramUI/TelegramUI/PeerMediaCollectionEmptyNode.swift index 11bbfaae43..66ee3035b4 100644 --- a/submodules/TelegramUI/TelegramUI/PeerMediaCollectionEmptyNode.swift +++ b/submodules/TelegramUI/TelegramUI/PeerMediaCollectionEmptyNode.swift @@ -3,6 +3,7 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import ActivityIndicator final class PeerMediaCollectionEmptyNode: ASDisplayNode { private let mode: PeerMediaCollectionMode diff --git a/submodules/TelegramUI/TelegramUI/PeerReportController.swift b/submodules/TelegramUI/TelegramUI/PeerReportController.swift index ce7452b630..f0a8cdfd40 100644 --- a/submodules/TelegramUI/TelegramUI/PeerReportController.swift +++ b/submodules/TelegramUI/TelegramUI/PeerReportController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI enum PeerReportSubject { case peer(PeerId) @@ -20,7 +21,7 @@ private enum PeerReportOption { case other } -func peerReportOptionsController(context: AccountContext, subject: PeerReportSubject, present: @escaping (ViewController, Any?) -> Void) -> ViewController { +func peerReportOptionsController(context: AccountContextImpl, subject: PeerReportSubject, present: @escaping (ViewController, Any?) -> Void) -> ViewController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let controller = ActionSheetController(theme: ActionSheetControllerTheme(presentationTheme: presentationData.theme)) @@ -185,7 +186,7 @@ private func peerReportControllerEntries(presentationData: PresentationData, sta return entries } -private func peerReportController(context: AccountContext, subject: PeerReportSubject) -> ViewController { +private func peerReportController(context: AccountContextImpl, subject: PeerReportSubject) -> ViewController { var dismissImpl: (() -> Void)? var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)? diff --git a/submodules/TelegramUI/TelegramUI/PeerSelectionController.swift b/submodules/TelegramUI/TelegramUI/PeerSelectionController.swift index 8ef34c1e32..02e550c785 100644 --- a/submodules/TelegramUI/TelegramUI/PeerSelectionController.swift +++ b/submodules/TelegramUI/TelegramUI/PeerSelectionController.swift @@ -5,9 +5,10 @@ import Display import TelegramCore import Postbox import TelegramPresentationData +import ProgressNavigationButtonNode public final class PeerSelectionController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private var presentationDataDisposable: Disposable? @@ -48,7 +49,7 @@ public final class PeerSelectionController: ViewController { private var searchContentNode: NavigationBarSearchContentNode? - public init(context: AccountContext, filter: ChatListNodePeersFilter = [.onlyWriteable], hasContactSelector: Bool = true, title: String? = nil) { + public init(context: AccountContextImpl, filter: ChatListNodePeersFilter = [.onlyWriteable], hasContactSelector: Bool = true, title: String? = nil) { self.context = context self.filter = filter self.hasContactSelector = hasContactSelector diff --git a/submodules/TelegramUI/TelegramUI/PeerSelectionControllerNode.swift b/submodules/TelegramUI/TelegramUI/PeerSelectionControllerNode.swift index c4fc539f6e..9f33559362 100644 --- a/submodules/TelegramUI/TelegramUI/PeerSelectionControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/PeerSelectionControllerNode.swift @@ -8,7 +8,7 @@ import SwiftSignalKit import TelegramPresentationData final class PeerSelectionControllerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private let present: (ViewController, Any?) -> Void private let dismiss: () -> Void private let filter: ChatListNodePeersFilter @@ -51,7 +51,7 @@ final class PeerSelectionControllerNode: ASDisplayNode { return self.readyValue.get() } - init(context: AccountContext, filter: ChatListNodePeersFilter, hasContactSelector: Bool, present: @escaping (ViewController, Any?) -> Void, dismiss: @escaping () -> Void) { + init(context: AccountContextImpl, filter: ChatListNodePeersFilter, hasContactSelector: Bool, present: @escaping (ViewController, Any?) -> Void, dismiss: @escaping () -> Void) { self.context = context self.present = present self.dismiss = dismiss @@ -305,7 +305,7 @@ final class PeerSelectionControllerNode: ASDisplayNode { func animateOut(completion: (() -> Void)? = nil) { self.clipsToBounds = true - self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, additive: true, completion: { [weak self] _ in + self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, completion: { [weak self] _ in if let strongSelf = self { strongSelf.dismiss() } diff --git a/submodules/TelegramUI/TelegramUI/PeersNearbyController.swift b/submodules/TelegramUI/TelegramUI/PeersNearbyController.swift index 6c80479695..ec2a4b997e 100644 --- a/submodules/TelegramUI/TelegramUI/PeersNearbyController.swift +++ b/submodules/TelegramUI/TelegramUI/PeersNearbyController.swift @@ -7,6 +7,7 @@ import TelegramCore import MapKit import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private struct PeerNearbyEntry { let peer: (Peer, CachedPeerData?) @@ -35,11 +36,11 @@ private func arePeerNearbyArraysEqual(_ lhs: [PeerNearbyEntry], _ rhs: [PeerNear } private final class PeersNearbyControllerArguments { - let context: AccountContext + let context: AccountContextImpl let openChat: (Peer) -> Void let openCreateGroup: (Double, Double, String?) -> Void - init(context: AccountContext, openChat: @escaping (Peer) -> Void, openCreateGroup: @escaping (Double, Double, String?) -> Void) { + init(context: AccountContextImpl, openChat: @escaping (Peer) -> Void, openCreateGroup: @escaping (Double, Double, String?) -> Void) { self.context = context self.openChat = openChat self.openCreateGroup = openCreateGroup @@ -281,7 +282,7 @@ private func peersNearbyControllerEntries(data: PeersNearbyData?, presentationDa return entries } -public func peersNearbyController(context: AccountContext) -> ViewController { +public func peersNearbyController(context: AccountContextImpl) -> ViewController { var pushControllerImpl: ((ViewController) -> Void)? var replaceAllButRootControllerImpl: ((ViewController, Bool) -> Void)? var replaceTopControllerImpl: ((ViewController) -> Void)? diff --git a/submodules/TelegramUI/TelegramUI/PeersNearbyHeaderItem.swift b/submodules/TelegramUI/TelegramUI/PeersNearbyHeaderItem.swift index f0f990e06f..a9acae2509 100644 --- a/submodules/TelegramUI/TelegramUI/PeersNearbyHeaderItem.swift +++ b/submodules/TelegramUI/TelegramUI/PeersNearbyHeaderItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI class PeersNearbyHeaderItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/PeersNearbyIconNode.swift b/submodules/TelegramUI/TelegramUI/PeersNearbyIconNode.swift index 942ed064aa..7657bc7675 100644 --- a/submodules/TelegramUI/TelegramUI/PeersNearbyIconNode.swift +++ b/submodules/TelegramUI/TelegramUI/PeersNearbyIconNode.swift @@ -60,7 +60,7 @@ final class PeersNearbyIconWavesNode: ASDisplayNode { }) as! POPAnimatableProperty) animation.fromValue = CGFloat(0.0) as NSNumber animation.toValue = CGFloat(1.0) as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 3.5 animation.repeatForever = true self.pop_add(animation, forKey: "indefiniteProgress") diff --git a/submodules/TelegramUI/TelegramUI/Permission.swift b/submodules/TelegramUI/TelegramUI/Permission.swift index 318bf27680..06247d162e 100644 --- a/submodules/TelegramUI/TelegramUI/Permission.swift +++ b/submodules/TelegramUI/TelegramUI/Permission.swift @@ -70,7 +70,7 @@ public enum PermissionState: Equatable { } } -public func requiredPermissions(context: AccountContext) -> Signal<(contacts: PermissionState, notifications: PermissionState, cellularData: PermissionState, siri: PermissionState), NoError> { +public func requiredPermissions(context: AccountContextImpl) -> Signal<(contacts: PermissionState, notifications: PermissionState, cellularData: PermissionState, siri: PermissionState), NoError> { return combineLatest(DeviceAccess.authorizationStatus(subject: .contacts), DeviceAccess.authorizationStatus(applicationInForeground: context.sharedContext.applicationBindings.applicationInForeground, subject: .notifications), DeviceAccess.authorizationStatus(siriAuthorization: { return context.sharedContext.applicationBindings.siriAuthorization() }, subject: .cellularData), DeviceAccess.authorizationStatus(siriAuthorization: { diff --git a/submodules/TelegramUI/TelegramUI/PermissionContentNode.swift b/submodules/TelegramUI/TelegramUI/PermissionContentNode.swift index 3a8bd2b6de..8ac2896056 100644 --- a/submodules/TelegramUI/TelegramUI/PermissionContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/PermissionContentNode.swift @@ -3,6 +3,7 @@ import UIKit import Display import AsyncDisplayKit import TelegramPresentationData +import TextFormat enum PermissionContentIcon { case image(UIImage?) diff --git a/submodules/TelegramUI/TelegramUI/PermissionController.swift b/submodules/TelegramUI/TelegramUI/PermissionController.swift index 12665ef5df..80dbf1cf9d 100644 --- a/submodules/TelegramUI/TelegramUI/PermissionController.swift +++ b/submodules/TelegramUI/TelegramUI/PermissionController.swift @@ -8,7 +8,7 @@ import TelegramPresentationData import DeviceAccess public final class PermissionController : ViewController { - private let context: AccountContext + private let context: AccountContextImpl private let splitTest: PermissionUISplitTest? private var state: PermissionControllerContent? private var splashScreen = false @@ -26,7 +26,7 @@ public final class PermissionController : ViewController { private var skip: (() -> Void)? public var proceed: ((Bool) -> Void)? - public init(context: AccountContext, splashScreen: Bool = true, splitTest: PermissionUISplitTest? = nil) { + public init(context: AccountContextImpl, splashScreen: Bool = true, splitTest: PermissionUISplitTest? = nil) { self.context = context self.splitTest = splitTest self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/PermissionControllerNode.swift b/submodules/TelegramUI/TelegramUI/PermissionControllerNode.swift index 4d4272ec76..3a9a43d6f3 100644 --- a/submodules/TelegramUI/TelegramUI/PermissionControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/PermissionControllerNode.swift @@ -60,7 +60,7 @@ private func localizedString(for key: String, strings: PresentationStrings, fall } final class PermissionControllerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let splitTest: PermissionUISplitTest? @@ -72,7 +72,7 @@ final class PermissionControllerNode: ASDisplayNode { var openPrivacyPolicy: (() -> Void)? var dismiss: (() -> Void)? - init(context: AccountContext, splitTest: PermissionUISplitTest?) { + init(context: AccountContextImpl, splitTest: PermissionUISplitTest?) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.splitTest = splitTest @@ -99,7 +99,7 @@ final class PermissionControllerNode: ASDisplayNode { } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/PhoneLabelController.swift b/submodules/TelegramUI/TelegramUI/PhoneLabelController.swift index 77af1cdd18..9153b9ee4d 100644 --- a/submodules/TelegramUI/TelegramUI/PhoneLabelController.swift +++ b/submodules/TelegramUI/TelegramUI/PhoneLabelController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private struct PhoneLabelArguments { let selectLabel: (String) -> Void @@ -81,7 +82,7 @@ private func phoneLabelEntries(presentationData: PresentationData, state: PhoneL return entries } -public func phoneLabelController(context: AccountContext, currentLabel: String, completion: @escaping (String) -> Void) -> ViewController { +public func phoneLabelController(context: AccountContextImpl, currentLabel: String, completion: @escaping (String) -> Void) -> ViewController { let statePromise = ValuePromise(PhoneLabelState(currentLabel: currentLabel)) let stateValue = Atomic(value: PhoneLabelState(currentLabel: currentLabel)) let updateState: ((PhoneLabelState) -> PhoneLabelState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/PhotoResources.swift b/submodules/TelegramUI/TelegramUI/PhotoResources.swift index bccee7a2e8..acc3ac7fb0 100644 --- a/submodules/TelegramUI/TelegramUI/PhotoResources.swift +++ b/submodules/TelegramUI/TelegramUI/PhotoResources.swift @@ -706,7 +706,7 @@ public func chatMessagePhotoInternal(photoData: Signal Signal { +func chatMessagePhotoStatus(context: AccountContextImpl, messageId: MessageId, photoReference: ImageMediaReference) -> Signal { if let largestRepresentation = largestRepresentationForPhoto(photoReference.media) { return context.fetchManager.fetchStatus(category: .image, location: .chat(messageId.peerId), locationKey: .messageId(messageId), resource: largestRepresentation.resource) } else { @@ -1772,7 +1772,7 @@ public func standaloneChatMessagePhotoInteractiveFetched(account: Account, photo } } -public func chatMessagePhotoInteractiveFetched(context: AccountContext, photoReference: ImageMediaReference, storeToDownloadsPeerType: MediaAutoDownloadPeerType?) -> Signal { +public func chatMessagePhotoInteractiveFetched(context: AccountContextImpl, photoReference: ImageMediaReference, storeToDownloadsPeerType: MediaAutoDownloadPeerType?) -> Signal { if let largestRepresentation = largestRepresentationForPhoto(photoReference.media) { return fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: photoReference.resourceReference(largestRepresentation.resource), statsCategory: .image, reportResultStatus: true) |> mapToSignal { type -> Signal in @@ -1855,7 +1855,7 @@ public func chatWebpageSnippetFile(account: Account, fileReference: FileMediaRef return signal |> map { fullSizeData in return { arguments in var fullSizeImage: CGImage? - var imageOrientation: UIImageOrientation = .up + var imageOrientation: UIImage.Orientation = .up if let fullSizeData = fullSizeData { let options = NSMutableDictionary() if let imageSource = CGImageSourceCreateWithData(fullSizeData as CFData, nil), let image = CGImageSourceCreateImageAtIndex(imageSource, 0, options as CFDictionary) { @@ -1898,7 +1898,7 @@ func chatWebpageSnippetPhoto(account: Account, photoReference: ImageMediaReferen return signal |> map { fullSizeData in return { arguments in var fullSizeImage: CGImage? - var imageOrientation: UIImageOrientation = .up + var imageOrientation: UIImage.Orientation = .up if let fullSizeData = fullSizeData { let options = NSMutableDictionary() if let imageSource = CGImageSourceCreateWithData(fullSizeData as CFData, nil), let image = CGImageSourceCreateImageAtIndex(imageSource, 0, options as CFDictionary) { @@ -2034,7 +2034,7 @@ func chatSecretMessageVideo(account: Account, videoReference: FileMediaReference } } -private func orientationFromExif(orientation: Int) -> UIImageOrientation { +private func orientationFromExif(orientation: Int) -> UIImage.Orientation { switch orientation { case 1: return .up; @@ -2057,7 +2057,7 @@ private func orientationFromExif(orientation: Int) -> UIImageOrientation { } } -func imageOrientationFromSource(_ source: CGImageSource) -> UIImageOrientation { +func imageOrientationFromSource(_ source: CGImageSource) -> UIImage.Orientation { if let properties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) { let dict = properties as NSDictionary if let value = dict.object(forKey: kCGImagePropertyOrientation) as? NSNumber { @@ -2068,7 +2068,7 @@ func imageOrientationFromSource(_ source: CGImageSource) -> UIImageOrientation { return .up } -private func rotationFor(_ orientation: UIImageOrientation) -> CGFloat { +private func rotationFor(_ orientation: UIImage.Orientation) -> CGFloat { switch orientation { case .left: return CGFloat.pi / 2.0 @@ -2081,7 +2081,7 @@ private func rotationFor(_ orientation: UIImageOrientation) -> CGFloat { } } -func drawImage(context: CGContext, image: CGImage, orientation: UIImageOrientation, in rect: CGRect) { +func drawImage(context: CGContext, image: CGImage, orientation: UIImage.Orientation, in rect: CGRect) { var restore = true var drawRect = rect switch orientation { @@ -2145,7 +2145,7 @@ func chatMessageImageFile(account: Account, fileReference: FileMediaReference, t } var fullSizeImage: CGImage? - var imageOrientation: UIImageOrientation = .up + var imageOrientation: UIImage.Orientation = .up if let fullSizePath = fullSizePath { if fullSizeComplete { let options = NSMutableDictionary() @@ -2267,7 +2267,7 @@ func instantPageImageFile(account: Account, fileReference: FileMediaReference, f let fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize) var fullSizeImage: CGImage? - var imageOrientation: UIImageOrientation = .up + var imageOrientation: UIImage.Orientation = .up if let fullSizePath = fullSizePath { if fullSizeComplete { let options = NSMutableDictionary() @@ -2384,7 +2384,7 @@ func chatAvatarGalleryPhoto(account: Account, representations: [ImageRepresentat 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 fullSizeImage: CGImage? - var imageOrientation: UIImageOrientation = .up + var imageOrientation: UIImage.Orientation = .up if let fullSizeData = fullSizeData { if fullSizeComplete { let options = NSMutableDictionary() @@ -2512,7 +2512,7 @@ func chatMapSnapshotImage(account: Account, resource: MapSnapshotMediaResource) let context = DrawingContext(size: arguments.drawingSize, clear: true) var fullSizeImage: CGImage? - var imageOrientation: UIImageOrientation = .up + var imageOrientation: UIImage.Orientation = .up if let fullSizeData = fullSizeData { let options = NSMutableDictionary() options[kCGImageSourceShouldCache as NSString] = false as NSNumber @@ -2579,7 +2579,7 @@ func chatWebFileImage(account: Account, file: TelegramMediaWebFile) -> Signal<(T let context = DrawingContext(size: arguments.drawingSize, clear: true) var fullSizeImage: CGImage? - var imageOrientation: UIImageOrientation = .up + var imageOrientation: UIImage.Orientation = .up if fullSizeData.complete { let options = NSMutableDictionary() options[kCGImageSourceShouldCache as NSString] = false as NSNumber @@ -2898,7 +2898,7 @@ func securePhotoInternal(account: Account, resource: TelegramMediaResource, acce return CGSize(width: 128.0, height: 128.0) }, { arguments in var fullSizeImage: CGImage? - var imageOrientation: UIImageOrientation = .up + var imageOrientation: UIImage.Orientation = .up if let fullSizeData = fullSizeData { let options = NSMutableDictionary() if let imageSource = CGImageSourceCreateWithData(fullSizeData as CFData, nil), let image = CGImageSourceCreateImageAtIndex(imageSource, 0, options as CFDictionary) { diff --git a/submodules/TelegramUI/TelegramUI/PrefetchManager.swift b/submodules/TelegramUI/TelegramUI/PrefetchManager.swift index 5b03639883..ab99e39646 100644 --- a/submodules/TelegramUI/TelegramUI/PrefetchManager.swift +++ b/submodules/TelegramUI/TelegramUI/PrefetchManager.swift @@ -20,7 +20,7 @@ private final class PrefetchManagerImpl { private var contexts: [MediaId: PrefetchMediaContext] = [:] - init(queue: Queue, sharedContext: SharedAccountContext, account: Account, fetchManager: FetchManager) { + init(queue: Queue, sharedContext: SharedAccountContextImpl, account: Account, fetchManager: FetchManager) { self.queue = queue self.account = account self.fetchManager = fetchManager @@ -142,7 +142,7 @@ final class PrefetchManager { private let impl: QueueLocalObject - init(sharedContext: SharedAccountContext, account: Account, fetchManager: FetchManager) { + init(sharedContext: SharedAccountContextImpl, account: Account, fetchManager: FetchManager) { let queue = Queue.mainQueue() self.queue = queue self.impl = QueueLocalObject(queue: queue, generate: { diff --git a/submodules/TelegramUI/TelegramUI/PrepareSecretThumbnailData.swift b/submodules/TelegramUI/TelegramUI/PrepareSecretThumbnailData.swift index 3596734267..0df5c16081 100644 --- a/submodules/TelegramUI/TelegramUI/PrepareSecretThumbnailData.swift +++ b/submodules/TelegramUI/TelegramUI/PrepareSecretThumbnailData.swift @@ -11,7 +11,7 @@ func prepareSecretThumbnailData(_ data: MediaResourceData) -> (CGSize, Data)? { } } let scaledSize = image.size.fitted(CGSize(width: 90.0, height: 90.0)) - if let scaledImage = generateScaledImage(image: image, size: scaledSize, scale: 1.0), let scaledData = UIImageJPEGRepresentation(scaledImage, 0.4) { + if let scaledImage = generateScaledImage(image: image, size: scaledSize, scale: 1.0), let scaledData = scaledImage.jpegData(compressionQuality: 0.4) { return (scaledSize, scaledData) } } diff --git a/submodules/TelegramUI/TelegramUI/PreparedChatHistoryViewTransition.swift b/submodules/TelegramUI/TelegramUI/PreparedChatHistoryViewTransition.swift index 236554cb66..d3b7c1d8f8 100644 --- a/submodules/TelegramUI/TelegramUI/PreparedChatHistoryViewTransition.swift +++ b/submodules/TelegramUI/TelegramUI/PreparedChatHistoryViewTransition.swift @@ -3,6 +3,7 @@ import SwiftSignalKit import Postbox import TelegramCore import Display +import MergeLists func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toView: ChatHistoryView, reason: ChatHistoryViewTransitionReason, reverse: Bool, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, scrollPosition: ChatHistoryViewScrollPosition?, initialData: InitialMessageHistoryData?, keyboardButtonsMessage: Message?, cachedData: CachedPeerData?, cachedDataMessages: [MessageId: Message]?, readStateData: [PeerId: ChatHistoryCombinedInitialReadStateData]?, flashIndicators: Bool) -> ChatHistoryViewTransition { let mergeResult: (deleteIndices: [Int], indicesAndItems: [(Int, ChatHistoryEntry, Int?)], updateIndices: [(Int, ChatHistoryEntry, Int)]) diff --git a/submodules/TelegramUI/TelegramUI/PrivacyAndSecurityController.swift b/submodules/TelegramUI/TelegramUI/PrivacyAndSecurityController.swift index 62a5ad1217..890c38fcdb 100644 --- a/submodules/TelegramUI/TelegramUI/PrivacyAndSecurityController.swift +++ b/submodules/TelegramUI/TelegramUI/PrivacyAndSecurityController.swift @@ -7,6 +7,7 @@ import TelegramCore import TelegramPresentationData import TelegramUIPreferences import TelegramCallsUI +import ItemListUI private final class PrivacyAndSecurityControllerArguments { let account: Account @@ -50,7 +51,7 @@ private enum PrivacyAndSecuritySection: Int32 { public enum PrivacyAndSecurityEntryTag: ItemListItemTag { case accountTimeout - func isEqual(to other: ItemListItemTag) -> Bool { + public func isEqual(to other: ItemListItemTag) -> Bool { if let other = other as? PrivacyAndSecurityEntryTag, self == other { return true } else { @@ -418,7 +419,7 @@ private func privacyAndSecurityControllerEntries(presentationData: PresentationD return entries } -public func privacyAndSecurityController(context: AccountContext, initialSettings: AccountPrivacySettings? = nil, updatedSettings: ((AccountPrivacySettings?) -> Void)? = nil, focusOnItemTag: PrivacyAndSecurityEntryTag? = nil) -> ViewController { +public func privacyAndSecurityController(context: AccountContextImpl, initialSettings: AccountPrivacySettings? = nil, updatedSettings: ((AccountPrivacySettings?) -> Void)? = nil, focusOnItemTag: PrivacyAndSecurityEntryTag? = nil) -> ViewController { let statePromise = ValuePromise(PrivacyAndSecurityControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: PrivacyAndSecurityControllerState()) let updateState: ((PrivacyAndSecurityControllerState) -> PrivacyAndSecurityControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/PrivacyIntroController.swift b/submodules/TelegramUI/TelegramUI/PrivacyIntroController.swift index ffefbd43fa..d235d43b96 100644 --- a/submodules/TelegramUI/TelegramUI/PrivacyIntroController.swift +++ b/submodules/TelegramUI/TelegramUI/PrivacyIntroController.swift @@ -77,7 +77,7 @@ final public class PrivacyIntroControllerPresentationArguments { } final class PrivacyIntroController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private let mode: PrivacyIntroControllerMode private let arguments: PrivacyIntroControllerPresentationArguments private let proceedAction: () -> Void @@ -91,7 +91,7 @@ final class PrivacyIntroController: ViewController { private var isDismissed: Bool = false - init(context: AccountContext, mode: PrivacyIntroControllerMode, arguments: PrivacyIntroControllerPresentationArguments = PrivacyIntroControllerPresentationArguments(), proceedAction: @escaping () -> Void) { + init(context: AccountContextImpl, mode: PrivacyIntroControllerMode, arguments: PrivacyIntroControllerPresentationArguments = PrivacyIntroControllerPresentationArguments(), proceedAction: @escaping () -> Void) { self.context = context self.mode = mode self.arguments = arguments diff --git a/submodules/TelegramUI/TelegramUI/PrivacyIntroControllerNode.swift b/submodules/TelegramUI/TelegramUI/PrivacyIntroControllerNode.swift index eb6bb149c3..5c06bff1bf 100644 --- a/submodules/TelegramUI/TelegramUI/PrivacyIntroControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/PrivacyIntroControllerNode.swift @@ -30,7 +30,7 @@ private let textFont = Font.regular(14.0) private let buttonFont = Font.regular(17.0) final class PrivacyIntroControllerNode: ViewControllerTracingNode { - private let context: AccountContext + private let context: AccountContextImpl private let mode: PrivacyIntroControllerMode private var presentationData: PresentationData? private let proceedAction: () -> Void @@ -46,7 +46,7 @@ final class PrivacyIntroControllerNode: ViewControllerTracingNode { private var validLayout: (ContainerViewLayout, CGFloat)? - init(context: AccountContext, mode: PrivacyIntroControllerMode, proceedAction: @escaping () -> Void) { + init(context: AccountContextImpl, mode: PrivacyIntroControllerMode, proceedAction: @escaping () -> Void) { self.context = context self.mode = mode self.proceedAction = proceedAction @@ -164,7 +164,7 @@ final class PrivacyIntroControllerNode: ViewControllerTracingNode { } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/ProxyListSettingsController.swift b/submodules/TelegramUI/TelegramUI/ProxyListSettingsController.swift index 8b7ede46c9..52f32d6924 100644 --- a/submodules/TelegramUI/TelegramUI/ProxyListSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/ProxyListSettingsController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import MtProtoKitDynamic +import ItemListUI private final class ProxySettingsControllerArguments { let toggleEnabled: (Bool) -> Void @@ -299,7 +300,7 @@ public enum ProxySettingsControllerMode { case modal } -public func proxySettingsController(context: AccountContext, mode: ProxySettingsControllerMode = .default) -> ViewController { +public func proxySettingsController(context: AccountContextImpl, mode: ProxySettingsControllerMode = .default) -> ViewController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } return proxySettingsController(accountManager: context.sharedContext.accountManager, postbox: context.account.postbox, network: context.account.network, mode: mode, theme: presentationData.theme, strings: presentationData.strings, updatedPresentationData: context.sharedContext.presentationData |> map { ($0.theme, $0.strings) }) } diff --git a/submodules/TelegramUI/TelegramUI/ProxyServerActionSheetController.swift b/submodules/TelegramUI/TelegramUI/ProxyServerActionSheetController.swift index 947a09a56d..edf90d4ecd 100644 --- a/submodules/TelegramUI/TelegramUI/ProxyServerActionSheetController.swift +++ b/submodules/TelegramUI/TelegramUI/ProxyServerActionSheetController.swift @@ -7,6 +7,7 @@ import AsyncDisplayKit import UIKit import SwiftSignalKit import TelegramPresentationData +import ActivityIndicator public final class ProxyServerActionSheetController: ActionSheetController { private var presentationDisposable: Disposable? @@ -18,7 +19,7 @@ public final class ProxyServerActionSheetController: ActionSheetController { private var isDismissed: Bool = false - convenience init(context: AccountContext, server: ProxyServerSettings) { + convenience init(context: AccountContextImpl, server: ProxyServerSettings) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } self.init(theme: presentationData.theme, strings: presentationData.strings, accountManager: context.sharedContext.accountManager, postbox: context.account.postbox, network: context.account.network, server: server, presentationData: context.sharedContext.presentationData) } diff --git a/submodules/TelegramUI/TelegramUI/ProxyServerSettingsController.swift b/submodules/TelegramUI/TelegramUI/ProxyServerSettingsController.swift index 077d36b72e..d808debbeb 100644 --- a/submodules/TelegramUI/TelegramUI/ProxyServerSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/ProxyServerSettingsController.swift @@ -10,6 +10,7 @@ import MtProtoKit import MtProtoKitDynamic #endif import TelegramPresentationData +import ItemListUI private func shareLink(for server: ProxyServerSettings) -> String { var link: String @@ -261,7 +262,7 @@ private func proxyServerSettings(with state: ProxyServerSettingsControllerState) return nil } -public func proxyServerSettingsController(context: AccountContext, currentSettings: ProxyServerSettings? = nil) -> ViewController { +public func proxyServerSettingsController(context: AccountContextImpl, currentSettings: ProxyServerSettings? = nil) -> ViewController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } return proxyServerSettingsController(theme: presentationData.theme, strings: presentationData.strings, updatedPresentationData: context.sharedContext.presentationData |> map { ($0.theme, $0.strings) }, accountManager: context.sharedContext.accountManager, postbox: context.account.postbox, network: context.account.network, currentSettings: currentSettings) } diff --git a/submodules/TelegramUI/TelegramUI/ProxySettingsActionItem.swift b/submodules/TelegramUI/TelegramUI/ProxySettingsActionItem.swift index b5bfbf37ed..73bd7b65d8 100644 --- a/submodules/TelegramUI/TelegramUI/ProxySettingsActionItem.swift +++ b/submodules/TelegramUI/TelegramUI/ProxySettingsActionItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI enum ProxySettingsActionIcon { case none diff --git a/submodules/TelegramUI/TelegramUI/ProxySettingsServerItem.swift b/submodules/TelegramUI/TelegramUI/ProxySettingsServerItem.swift index cedc48ed63..fd94da327a 100644 --- a/submodules/TelegramUI/TelegramUI/ProxySettingsServerItem.swift +++ b/submodules/TelegramUI/TelegramUI/ProxySettingsServerItem.swift @@ -6,6 +6,8 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI +import ActivityIndicator private let activitySize = CGSize(width: 24.0, height: 24.0) diff --git a/submodules/TelegramUI/TelegramUI/RadialCheckContentNode.swift b/submodules/TelegramUI/TelegramUI/RadialCheckContentNode.swift index c5bc6da069..96ea438ff5 100644 --- a/submodules/TelegramUI/TelegramUI/RadialCheckContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/RadialCheckContentNode.swift @@ -63,7 +63,7 @@ final class RadialCheckContentNode: RadialStatusContentNode { }) as! POPAnimatableProperty) animation.fromValue = 0.0 as NSNumber animation.toValue = 1.0 as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 0.25 animation.beginTime = delay animation.completionBlock = { [weak self] _, _ in diff --git a/submodules/TelegramUI/TelegramUI/RadialCloudProgressContentNode.swift b/submodules/TelegramUI/TelegramUI/RadialCloudProgressContentNode.swift index d196e8fd0f..90ef14544b 100644 --- a/submodules/TelegramUI/TelegramUI/RadialCloudProgressContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/RadialCloudProgressContentNode.swift @@ -65,7 +65,7 @@ private final class RadialCloudProgressContentSpinnerNode: ASDisplayNode { }) as! POPAnimatableProperty) animation.fromValue = CGFloat(self.effectiveProgress) as NSNumber animation.toValue = CGFloat(progress) as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 0.2 animation.completionBlock = { [weak self] _, _ in self?.progressAnimationCompleted?() @@ -84,7 +84,7 @@ private final class RadialCloudProgressContentSpinnerNode: ASDisplayNode { }) as! POPAnimatableProperty) animation.fromValue = CGFloat(0.0) as NSNumber animation.toValue = CGFloat(2.0) as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 2.5 animation.repeatForever = true self.pop_add(animation, forKey: "indefiniteProgress") @@ -164,12 +164,12 @@ private final class RadialCloudProgressContentSpinnerNode: ASDisplayNode { super.willEnterHierarchy() let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = 2.0 basicAnimation.fromValue = NSNumber(value: Float(0.0)) basicAnimation.toValue = NSNumber(value: Float.pi * 2.0) basicAnimation.repeatCount = Float.infinity - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) basicAnimation.beginTime = 1.0 self.layer.add(basicAnimation, forKey: "progressRotation") diff --git a/submodules/TelegramUI/TelegramUI/RadialDownloadContentNode.swift b/submodules/TelegramUI/TelegramUI/RadialDownloadContentNode.swift index 2078518ed9..d8f4fc0ecf 100644 --- a/submodules/TelegramUI/TelegramUI/RadialDownloadContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/RadialDownloadContentNode.swift @@ -6,11 +6,11 @@ import LegacyComponents import SwiftSignalKit private extension CAShapeLayer { - func animateStrokeStart(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: Bool = true, completion: ((Bool) -> ())? = nil) { + func animateStrokeStart(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: Bool = true, completion: ((Bool) -> ())? = nil) { self.animate(from: NSNumber(value: Float(from)), to: NSNumber(value: Float(to)), keyPath: "strokeStart", timingFunction: timingFunction, duration: duration, delay: delay, removeOnCompletion: removeOnCompletion, completion: completion) } - func animateStrokeEnd(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: Bool = true, completion: ((Bool) -> ())? = nil) { + func animateStrokeEnd(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: Bool = true, completion: ((Bool) -> ())? = nil) { self.animate(from: NSNumber(value: Float(from)), to: NSNumber(value: Float(to)), keyPath: "strokeEnd", timingFunction: timingFunction, duration: duration, delay: delay, removeOnCompletion: removeOnCompletion, completion: completion) } } @@ -45,16 +45,16 @@ final class RadialDownloadContentNode: RadialStatusContentNode { self.leftLine.fillColor = UIColor.clear.cgColor self.leftLine.strokeColor = self.color.cgColor - self.leftLine.lineCap = kCALineCapRound - self.leftLine.lineJoin = kCALineCapRound + self.leftLine.lineCap = .round + self.leftLine.lineJoin = .round self.rightLine.fillColor = UIColor.clear.cgColor self.rightLine.strokeColor = self.color.cgColor - self.rightLine.lineCap = kCALineCapRound - self.rightLine.lineJoin = kCALineCapRound + self.rightLine.lineCap = .round + self.rightLine.lineJoin = .round self.arrowBody.fillColor = UIColor.clear.cgColor self.arrowBody.strokeColor = self.color.cgColor - self.arrowBody.lineCap = kCALineCapRound - self.arrowBody.lineJoin = kCALineCapRound + self.arrowBody.lineCap = .round + self.arrowBody.lineJoin = .round self.isLayerBacked = true self.isOpaque = false diff --git a/submodules/TelegramUI/TelegramUI/RadialProgressContentNode.swift b/submodules/TelegramUI/TelegramUI/RadialProgressContentNode.swift index ca16685e31..2816bb4725 100644 --- a/submodules/TelegramUI/TelegramUI/RadialProgressContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/RadialProgressContentNode.swift @@ -66,7 +66,7 @@ private final class RadialProgressContentSpinnerNode: ASDisplayNode { animation.fromValue = CGFloat(self.effectiveProgress) as NSNumber animation.toValue = CGFloat(progress) as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = duration animation.completionBlock = { [weak self] _, _ in self?.progressAnimationCompleted?() @@ -85,7 +85,7 @@ private final class RadialProgressContentSpinnerNode: ASDisplayNode { }) as! POPAnimatableProperty) animation.fromValue = CGFloat(0.0) as NSNumber animation.toValue = CGFloat(2.0) as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 2.5 animation.repeatForever = true self.pop_add(animation, forKey: "indefiniteProgress") @@ -168,7 +168,7 @@ private final class RadialProgressContentSpinnerNode: ASDisplayNode { basicAnimation.fromValue = NSNumber(value: fromValue) basicAnimation.toValue = NSNumber(value: fromValue + Float.pi * 2.0) basicAnimation.repeatCount = Float.infinity - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) basicAnimation.beginTime = 0.0 self.layer.add(basicAnimation, forKey: "progressRotation") diff --git a/submodules/TelegramUI/TelegramUI/RadialProgressNode.swift b/submodules/TelegramUI/TelegramUI/RadialProgressNode.swift index b23c86cc65..e25af6c9c9 100644 --- a/submodules/TelegramUI/TelegramUI/RadialProgressNode.swift +++ b/submodules/TelegramUI/TelegramUI/RadialProgressNode.swift @@ -62,7 +62,7 @@ private class RadialProgressOverlayNode: ASDisplayNode { }) as! POPAnimatableProperty) animation.fromValue = CGFloat(effectiveProgress) as NSNumber animation.toValue = CGFloat(progress) as NSNumber - animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 0.2 animation.completionBlock = { [weak self] _, _ in self?.progressAnimationCompleted?() @@ -131,12 +131,12 @@ private class RadialProgressOverlayNode: ASDisplayNode { super.willEnterHierarchy() let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) basicAnimation.duration = 2.0 basicAnimation.fromValue = NSNumber(value: Float(0.0)) basicAnimation.toValue = NSNumber(value: Float.pi * 2.0) basicAnimation.repeatCount = Float.infinity - basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) self.layer.add(basicAnimation, forKey: "progressRotation") } diff --git a/submodules/TelegramUI/TelegramUI/RadialStatusSecretTimeoutContentNode.swift b/submodules/TelegramUI/TelegramUI/RadialStatusSecretTimeoutContentNode.swift index e5111863cf..f1c4ecefe6 100644 --- a/submodules/TelegramUI/TelegramUI/RadialStatusSecretTimeoutContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/RadialStatusSecretTimeoutContentNode.swift @@ -80,7 +80,7 @@ final class RadialStatusSecretTimeoutContentNode: RadialStatusContentNode { self.displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent)) self.displayLink?.isPaused = true - self.displayLink?.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink?.add(to: RunLoop.main, forMode: .common) } deinit { diff --git a/submodules/TelegramUI/TelegramUI/RadialTimeoutNode.swift b/submodules/TelegramUI/TelegramUI/RadialTimeoutNode.swift index fb036c5bd7..fb1d2b8bb2 100644 --- a/submodules/TelegramUI/TelegramUI/RadialTimeoutNode.swift +++ b/submodules/TelegramUI/TelegramUI/RadialTimeoutNode.swift @@ -67,7 +67,7 @@ public final class RadialTimeoutNode: ASDisplayNode { self?.setNeedsDisplay() }), selector: #selector(RadialTimeoutNodeTimer.event), userInfo: nil, repeats: true) self.animationTimer = animationTimer - RunLoop.main.add(animationTimer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(animationTimer, forMode: .common) } } diff --git a/submodules/TelegramUI/TelegramUI/RecentSessionsController.swift b/submodules/TelegramUI/TelegramUI/RecentSessionsController.swift index 05eec2b812..2ed03d29a5 100644 --- a/submodules/TelegramUI/TelegramUI/RecentSessionsController.swift +++ b/submodules/TelegramUI/TelegramUI/RecentSessionsController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class RecentSessionsControllerArguments { let account: Account @@ -409,7 +410,7 @@ private func recentSessionsControllerEntries(presentationData: PresentationData, return entries } -public func recentSessionsController(context: AccountContext, activeSessionsContext: ActiveSessionsContext) -> ViewController { +public func recentSessionsController(context: AccountContextImpl, activeSessionsContext: ActiveSessionsContext) -> ViewController { let statePromise = ValuePromise(RecentSessionsControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: RecentSessionsControllerState()) let updateState: ((RecentSessionsControllerState) -> RecentSessionsControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/RecentSessionsEmptyStateItem.swift b/submodules/TelegramUI/TelegramUI/RecentSessionsEmptyStateItem.swift index 38773b5250..6498ea6b3a 100644 --- a/submodules/TelegramUI/TelegramUI/RecentSessionsEmptyStateItem.swift +++ b/submodules/TelegramUI/TelegramUI/RecentSessionsEmptyStateItem.swift @@ -3,6 +3,7 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import ItemListUI final class RecentSessionsEmptyStateItem: ItemListControllerEmptyStateItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/ReplyAccessoryPanelNode.swift b/submodules/TelegramUI/TelegramUI/ReplyAccessoryPanelNode.swift index 5871b80bb0..6f960f21b8 100644 --- a/submodules/TelegramUI/TelegramUI/ReplyAccessoryPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ReplyAccessoryPanelNode.swift @@ -24,14 +24,14 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode { var theme: PresentationTheme - init(context: AccountContext, messageId: MessageId, theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder) { + init(context: AccountContextImpl, messageId: MessageId, theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder) { self.messageId = messageId self.theme = theme self.closeButton = ASButtonNode() self.closeButton.accessibilityLabel = "Discard" - self.closeButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0) + self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0) self.closeButton.setImage(PresentationResourcesChat.chatInputPanelCloseIconImage(theme), for: []) self.closeButton.displaysAsynchronously = false diff --git a/submodules/TelegramUI/TelegramUI/ResetPasswordController.swift b/submodules/TelegramUI/TelegramUI/ResetPasswordController.swift index 76d8d3a94e..a2fdd6eaab 100644 --- a/submodules/TelegramUI/TelegramUI/ResetPasswordController.swift +++ b/submodules/TelegramUI/TelegramUI/ResetPasswordController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private final class ResetPasswordControllerArguments { let updateCodeText: (String) -> Void @@ -108,7 +109,7 @@ enum ResetPasswordState: Equatable { case pendingVerification(emailPattern: String) } -func resetPasswordController(context: AccountContext, emailPattern: String, completion: @escaping () -> Void) -> ViewController { +func resetPasswordController(context: AccountContextImpl, emailPattern: String, completion: @escaping () -> Void) -> ViewController { let statePromise = ValuePromise(ResetPasswordControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: ResetPasswordControllerState()) let updateState: ((ResetPasswordControllerState) -> ResetPasswordControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/SaveIncomingMediaController.swift b/submodules/TelegramUI/TelegramUI/SaveIncomingMediaController.swift index cd8cd71021..0ec98a7996 100644 --- a/submodules/TelegramUI/TelegramUI/SaveIncomingMediaController.swift +++ b/submodules/TelegramUI/TelegramUI/SaveIncomingMediaController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private enum PeerType { case contact @@ -92,7 +93,7 @@ private func saveIncomingMediaControllerEntries(presentationData: PresentationDa return entries } -func saveIncomingMediaController(context: AccountContext) -> ViewController { +func saveIncomingMediaController(context: AccountContextImpl) -> ViewController { let arguments = SaveIncomingMediaControllerArguments(toggle: { type in let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in var settings = settings diff --git a/submodules/TelegramUI/TelegramUI/SaveToCameraRoll.swift b/submodules/TelegramUI/TelegramUI/SaveToCameraRoll.swift index f22e48de05..4f546940cc 100644 --- a/submodules/TelegramUI/TelegramUI/SaveToCameraRoll.swift +++ b/submodules/TelegramUI/TelegramUI/SaveToCameraRoll.swift @@ -13,7 +13,7 @@ private enum SaveToCameraRollState { case data(MediaResourceData) } -private func fetchMediaData(context: AccountContext, postbox: Postbox, mediaReference: AnyMediaReference) -> Signal<(SaveToCameraRollState, Bool), NoError> { +private func fetchMediaData(context: AccountContextImpl, postbox: Postbox, mediaReference: AnyMediaReference) -> Signal<(SaveToCameraRollState, Bool), NoError> { var resource: MediaResource? var isImage = true var fileExtension: String? @@ -76,7 +76,7 @@ private func fetchMediaData(context: AccountContext, postbox: Postbox, mediaRefe } } -func saveToCameraRoll(context: AccountContext, postbox: Postbox, mediaReference: AnyMediaReference) -> Signal { +func saveToCameraRoll(context: AccountContextImpl, postbox: Postbox, mediaReference: AnyMediaReference) -> Signal { return fetchMediaData(context: context, postbox: postbox, mediaReference: mediaReference) |> mapToSignal { state, isImage -> Signal in switch state { @@ -130,7 +130,7 @@ func saveToCameraRoll(context: AccountContext, postbox: Postbox, mediaReference: } } -func copyToPasteboard(context: AccountContext, postbox: Postbox, mediaReference: AnyMediaReference) -> Signal { +func copyToPasteboard(context: AccountContextImpl, postbox: Postbox, mediaReference: AnyMediaReference) -> Signal { return fetchMediaData(context: context, postbox: postbox, mediaReference: mediaReference) |> mapToSignal { state, isImage -> Signal in if case let .data(data) = state, data.complete { diff --git a/submodules/TelegramUI/TelegramUI/ScreenCaptureDetection.swift b/submodules/TelegramUI/TelegramUI/ScreenCaptureDetection.swift index 08958ad0c9..1ec8d833be 100644 --- a/submodules/TelegramUI/TelegramUI/ScreenCaptureDetection.swift +++ b/submodules/TelegramUI/TelegramUI/ScreenCaptureDetection.swift @@ -52,7 +52,7 @@ private func screenRecordingActive() -> Signal { func screenCaptureEvents() -> Signal { return Signal { subscriber in - let observer = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationUserDidTakeScreenshot, object: nil, queue: .main, using: { _ in + let observer = NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: .main, using: { _ in subscriber.putNext(.still) }) diff --git a/submodules/TelegramUI/TelegramUI/SearchBarNode.swift b/submodules/TelegramUI/TelegramUI/SearchBarNode.swift index 890656c155..b58aee1e36 100644 --- a/submodules/TelegramUI/TelegramUI/SearchBarNode.swift +++ b/submodules/TelegramUI/TelegramUI/SearchBarNode.swift @@ -4,6 +4,7 @@ import SwiftSignalKit import AsyncDisplayKit import Display import TelegramPresentationData +import ActivityIndicator private func generateLoupeIcon(color: UIColor) -> UIImage? { return generateTintedImage(image: UIImage(bundleImageName: "Components/Search Bar/Loupe"), color: color) @@ -463,7 +464,7 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate { let initialBackgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: self.bounds.size.width, height: max(0.0, initialTextBackgroundFrame.maxY + 8.0))) if let fromBackgroundColor = node.backgroundColor, let toBackgroundColor = self.backgroundNode.backgroundColor { - self.backgroundNode.layer.animate(from: fromBackgroundColor.cgColor, to: toBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: duration * 0.7) + self.backgroundNode.layer.animate(from: fromBackgroundColor.cgColor, to: toBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: duration * 0.7) } else { self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration) } @@ -525,7 +526,7 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate { let targetBackgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: self.bounds.size.width, height: max(0.0, targetTextBackgroundFrame.maxY + 8.0))) if let toBackgroundColor = node.backgroundColor, let fromBackgroundColor = self.backgroundNode.backgroundColor { - self.backgroundNode.layer.animate(from: fromBackgroundColor.cgColor, to: toBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: duration * 0.5, removeOnCompletion: false) + self.backgroundNode.layer.animate(from: fromBackgroundColor.cgColor, to: toBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: duration * 0.5, removeOnCompletion: false) } else { self.backgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration / 2.0, removeOnCompletion: false) } @@ -562,8 +563,8 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate { if let snapshot = node.labelNode.layer.snapshotContentTree() { snapshot.frame = CGRect(origin: self.textField.placeholderLabel.frame.origin.offsetBy(dx: 0.0, dy: UIScreenPixel), size: node.labelNode.frame.size) self.textField.layer.addSublayer(snapshot) - snapshot.animateAlpha(from: 0.0, to: 1.0, duration: duration * 2.0 / 3.0, timingFunction: kCAMediaTimingFunctionLinear) - self.textField.placeholderLabel.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false) + snapshot.animateAlpha(from: 0.0, to: 1.0, duration: duration * 2.0 / 3.0, timingFunction: CAMediaTimingFunctionName.linear.rawValue) + self.textField.placeholderLabel.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false) } } else if let cachedLayout = node.labelNode.cachedLayout { let labelNode = TextNode() @@ -574,9 +575,9 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate { let _ = labelApply() self.textField.addSubnode(labelNode) - labelNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration * 2.0 / 3.0, timingFunction: kCAMediaTimingFunctionLinear) + labelNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration * 2.0 / 3.0, timingFunction: CAMediaTimingFunctionName.linear.rawValue) labelNode.frame = CGRect(origin: self.textField.placeholderLabel.frame.origin.offsetBy(dx: 0.0, dy: UIScreenPixel), size: labelLayoutResult.size) - self.textField.placeholderLabel.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false, completion: { _ in + self.textField.placeholderLabel.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { _ in labelNode.removeFromSupernode() }) } diff --git a/submodules/TelegramUI/TelegramUI/SearchBarPlaceholderNode.swift b/submodules/TelegramUI/TelegramUI/SearchBarPlaceholderNode.swift index af97b8fde2..9201ae03b3 100644 --- a/submodules/TelegramUI/TelegramUI/SearchBarPlaceholderNode.swift +++ b/submodules/TelegramUI/TelegramUI/SearchBarPlaceholderNode.swift @@ -77,10 +77,10 @@ class SearchBarPlaceholderNode: ASDisplayNode { return } if let _ = point { - strongSelf.backgroundNode.layer.animate(from: (strongSelf.backgroundNode.backgroundColor ?? strongSelf.foregroundColor).cgColor, to: strongSelf.foregroundColor.withMultipliedBrightnessBy(0.9).cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.2) + strongSelf.backgroundNode.layer.animate(from: (strongSelf.backgroundNode.backgroundColor ?? strongSelf.foregroundColor).cgColor, to: strongSelf.foregroundColor.withMultipliedBrightnessBy(0.9).cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.2) strongSelf.backgroundNode.backgroundColor = strongSelf.foregroundColor.withMultipliedBrightnessBy(0.9) } else { - strongSelf.backgroundNode.layer.animate(from: (strongSelf.backgroundNode.backgroundColor ?? strongSelf.foregroundColor).cgColor, to: strongSelf.foregroundColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.4) + strongSelf.backgroundNode.layer.animate(from: (strongSelf.backgroundNode.backgroundColor ?? strongSelf.foregroundColor).cgColor, to: strongSelf.foregroundColor.cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.4) strongSelf.backgroundNode.backgroundColor = strongSelf.foregroundColor } } diff --git a/submodules/TelegramUI/TelegramUI/SearchDisplayController.swift b/submodules/TelegramUI/TelegramUI/SearchDisplayController.swift index b7951012ee..47650157b9 100644 --- a/submodules/TelegramUI/TelegramUI/SearchDisplayController.swift +++ b/submodules/TelegramUI/TelegramUI/SearchDisplayController.swift @@ -112,7 +112,7 @@ final class SearchDisplayController { let contentNodePosition = self.contentNode.layer.position self.contentNode.layer.animatePosition(from: CGPoint(x: contentNodePosition.x, y: contentNodePosition.y + (initialTextBackgroundFrame.maxY + 8.0 - navigationBarHeight)), to: contentNodePosition, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring) - self.contentNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionEaseOut) + self.contentNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue) self.searchBar.placeholderString = placeholder.placeholderString diff --git a/submodules/TelegramUI/TelegramUI/SearchPeerMembers.swift b/submodules/TelegramUI/TelegramUI/SearchPeerMembers.swift index 48cb1bcc65..c8cdc41528 100644 --- a/submodules/TelegramUI/TelegramUI/SearchPeerMembers.swift +++ b/submodules/TelegramUI/TelegramUI/SearchPeerMembers.swift @@ -3,7 +3,7 @@ import Postbox import TelegramCore import SwiftSignalKit -func searchPeerMembers(context: AccountContext, peerId: PeerId, query: String) -> Signal<[Peer], NoError> { +func searchPeerMembers(context: AccountContextImpl, peerId: PeerId, query: String) -> Signal<[Peer], NoError> { if peerId.namespace == Namespaces.Peer.CloudChannel { return context.account.postbox.transaction { transaction -> CachedChannelData? in return transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData diff --git a/submodules/TelegramUI/TelegramUI/SecretChatKeyController.swift b/submodules/TelegramUI/TelegramUI/SecretChatKeyController.swift index 53d5c75721..3c589fbf57 100644 --- a/submodules/TelegramUI/TelegramUI/SecretChatKeyController.swift +++ b/submodules/TelegramUI/TelegramUI/SecretChatKeyController.swift @@ -11,13 +11,13 @@ final class SecretChatKeyController: ViewController { return self.displayNode as! SecretChatKeyControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let fingerprint: SecretChatKeyFingerprint private let peer: Peer private var presentationData: PresentationData - init(context: AccountContext, fingerprint: SecretChatKeyFingerprint, peer: Peer) { + init(context: AccountContextImpl, fingerprint: SecretChatKeyFingerprint, peer: Peer) { self.context = context self.fingerprint = fingerprint self.peer = peer diff --git a/submodules/TelegramUI/TelegramUI/SecretChatKeyControllerNode.swift b/submodules/TelegramUI/TelegramUI/SecretChatKeyControllerNode.swift index 352e6ae560..f35949967c 100644 --- a/submodules/TelegramUI/TelegramUI/SecretChatKeyControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/SecretChatKeyControllerNode.swift @@ -5,6 +5,7 @@ import AsyncDisplayKit import TelegramCore import Postbox import TelegramPresentationData +import TextFormat private func processHexString(_ string: String) -> String { var result = "" @@ -23,7 +24,7 @@ private func processHexString(_ string: String) -> String { } final class SecretChatKeyControllerNode: ViewControllerTracingNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let fingerprint: SecretChatKeyFingerprint private let peer: Peer @@ -36,7 +37,7 @@ final class SecretChatKeyControllerNode: ViewControllerTracingNode { private var validImageSize: CGSize? - init(context: AccountContext, presentationData: PresentationData, fingerprint: SecretChatKeyFingerprint, peer: Peer, getNavigationController: @escaping () -> NavigationController?) { + init(context: AccountContextImpl, presentationData: PresentationData, fingerprint: SecretChatKeyFingerprint, peer: Peer, getNavigationController: @escaping () -> NavigationController?) { self.context = context self.presentationData = presentationData self.fingerprint = fingerprint @@ -123,7 +124,7 @@ final class SecretChatKeyControllerNode: ViewControllerTracingNode { let linkRange = (infoRaw as NSString).range(of: "telegram.org") if linkRange.location != NSNotFound { - infoText.addAttributes([.foregroundColor: self.presentationData.theme.list.itemAccentColor, NSAttributedStringKey(rawValue: TelegramTextAttributes.URL): "https://telegram.org/faq#secret-chats"], range: linkRange) + infoText.addAttributes([.foregroundColor: self.presentationData.theme.list.itemAccentColor, NSAttributedString.Key(rawValue: TelegramTextAttributes.URL): "https://telegram.org/faq#secret-chats"], range: linkRange) } let (infoLayout, infoApply) = makeInfoLayout(TextNodeLayoutArguments(attributedString: infoText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: layout.size.width - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets())) @@ -153,7 +154,7 @@ final class SecretChatKeyControllerNode: ViewControllerTracingNode { if case .ended = recognizer.state { let point = recognizer.location(in: recognizer.view) if let attributes = self.infoNode.attributesAtPoint(point)?.1 { - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { openExternalUrl(context: self.context, url: url, presentationData: self.presentationData, navigationController: self.getNavigationController(), dismissInput: { [weak self] in self?.view.endEditing(true) }) diff --git a/submodules/TelegramUI/TelegramUI/SecretMediaPreviewController.swift b/submodules/TelegramUI/TelegramUI/SecretMediaPreviewController.swift index 2b97ef40c4..58d68b634c 100644 --- a/submodules/TelegramUI/TelegramUI/SecretMediaPreviewController.swift +++ b/submodules/TelegramUI/TelegramUI/SecretMediaPreviewController.swift @@ -115,7 +115,7 @@ private final class SecretMediaPreviewControllerNode: GalleryControllerNode { } public final class SecretMediaPreviewController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private let _ready = Promise() override public var ready: Promise { @@ -142,7 +142,7 @@ public final class SecretMediaPreviewController: ViewController { private var screenCaptureEventsDisposable: Disposable? - public init(context: AccountContext, messageId: MessageId) { + public init(context: AccountContextImpl, messageId: MessageId) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/SecureIdAuthController.swift b/submodules/TelegramUI/TelegramUI/SecureIdAuthController.swift index 1065262179..58795615a0 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdAuthController.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdAuthController.swift @@ -6,6 +6,8 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import TextFormat +import ProgressNavigationButtonNode public enum SecureIdRequestResult: String { case success = "success" @@ -65,7 +67,7 @@ final class SecureIdAuthController: ViewController { return self.displayNode as! SecureIdAuthControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let mode: SecureIdAuthControllerMode @@ -81,7 +83,7 @@ final class SecureIdAuthController: ViewController { private let hapticFeedback = HapticFeedback() - init(context: AccountContext, mode: SecureIdAuthControllerMode) { + init(context: AccountContextImpl, mode: SecureIdAuthControllerMode) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/SecureIdAuthControllerNode.swift b/submodules/TelegramUI/TelegramUI/SecureIdAuthControllerNode.swift index 5429355591..ef6f523ea1 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdAuthControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdAuthControllerNode.swift @@ -6,9 +6,10 @@ import AsyncDisplayKit import Postbox import TelegramCore import TelegramPresentationData +import ActivityIndicator final class SecureIdAuthControllerNode: ViewControllerTracingNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let requestLayout: (ContainedViewLayoutTransition) -> Void private let interaction: SecureIdAuthControllerInteraction @@ -31,7 +32,7 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode { private let deleteValueDisposable = MetaDisposable() - init(context: AccountContext, presentationData: PresentationData, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, interaction: SecureIdAuthControllerInteraction) { + init(context: AccountContextImpl, presentationData: PresentationData, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, interaction: SecureIdAuthControllerInteraction) { self.context = context self.presentationData = presentationData self.requestLayout = requestLayout @@ -89,7 +90,7 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode { func animateOut(completion: (() -> Void)? = nil) { self.isDisappearing = true self.view.endEditing(true) - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/SecureIdAuthFormContentNode.swift b/submodules/TelegramUI/TelegramUI/SecureIdAuthFormContentNode.swift index bc1593e62a..2555e374f7 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdAuthFormContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdAuthFormContentNode.swift @@ -5,6 +5,7 @@ import Display import Postbox import TelegramCore import TelegramPresentationData +import TextFormat private let infoFont = Font.regular(14.0) private let passwordFont = Font.regular(16.0) @@ -52,7 +53,7 @@ final class SecureIdAuthFormContentNode: ASDisplayNode, SecureIdAuthContentNode, let text: NSAttributedString if let privacyPolicyUrl = privacyPolicyUrl { let privacyPolicyAttributes = MarkdownAttributeSet(font: infoFont, textColor: theme.list.freeTextColor) - let privacyPolicyLinkAttributes = MarkdownAttributeSet(font: infoFont, textColor: theme.list.itemAccentColor, additionalAttributes: [NSAttributedStringKey.underlineStyle.rawValue: NSUnderlineStyle.styleSingle.rawValue as NSNumber, TelegramTextAttributes.URL: privacyPolicyUrl]) + let privacyPolicyLinkAttributes = MarkdownAttributeSet(font: infoFont, textColor: theme.list.itemAccentColor, additionalAttributes: [NSAttributedString.Key.underlineStyle.rawValue: NSUnderlineStyle.single.rawValue as NSNumber, TelegramTextAttributes.URL: privacyPolicyUrl]) text = parseMarkdownIntoAttributedString(strings.Passport_PrivacyPolicy(peer.displayTitle, (peer.addressName ?? "")).0.replacingOccurrences(of: "]", with: "]()"), attributes: MarkdownAttributes(body: privacyPolicyAttributes, bold: privacyPolicyAttributes, link: privacyPolicyLinkAttributes, linkAttribute: { _ in return nil @@ -68,18 +69,18 @@ final class SecureIdAuthFormContentNode: ASDisplayNode, SecureIdAuthContentNode, self.textNode.linkHighlightColor = theme.list.itemAccentColor.withAlphaComponent(0.5) self.textNode.highlightAttributeAction = { attributes in - if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] { - return NSAttributedStringKey(rawValue: TelegramTextAttributes.URL) - } else if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] { - return NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention) + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) + } else if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention) } else { return nil } } self.textNode.tapAttributeAction = { attributes in - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { openURL(url) - } else if let mention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { + } else if let mention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { openMention(mention) } } diff --git a/submodules/TelegramUI/TelegramUI/SecureIdAuthFormFieldNode.swift b/submodules/TelegramUI/TelegramUI/SecureIdAuthFormFieldNode.swift index 7c3a9f0968..e7bfd8ba2e 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdAuthFormFieldNode.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdAuthFormFieldNode.swift @@ -826,7 +826,7 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode { if highlighted { strongSelf.highlightedBackgroundNode.layer.removeAnimation(forKey: "opacity") strongSelf.highlightedBackgroundNode.alpha = 1.0 - strongSelf.view.superview?.bringSubview(toFront: strongSelf.view) + strongSelf.view.superview?.bringSubviewToFront(strongSelf.view) } else { strongSelf.highlightedBackgroundNode.alpha = 0.0 strongSelf.highlightedBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2) @@ -1020,7 +1020,7 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode { func highlight() { self.highlightedBackgroundNode.layer.removeAnimation(forKey: "opacity") self.highlightedBackgroundNode.alpha = 1.0 - self.view.superview?.bringSubview(toFront: self.view) + self.view.superview?.bringSubviewToFront(self.view) Queue.mainQueue().after(1.0, { self.highlightedBackgroundNode.alpha = 0.0 diff --git a/submodules/TelegramUI/TelegramUI/SecureIdAuthListFieldNode.swift b/submodules/TelegramUI/TelegramUI/SecureIdAuthListFieldNode.swift index 97d33b13ff..5e7005e5c9 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdAuthListFieldNode.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdAuthListFieldNode.swift @@ -190,7 +190,7 @@ final class SecureIdAuthListFieldNode: ASDisplayNode { if highlighted { strongSelf.highlightedBackgroundNode.layer.removeAnimation(forKey: "opacity") strongSelf.highlightedBackgroundNode.alpha = 1.0 - strongSelf.view.superview?.bringSubview(toFront: strongSelf.view) + strongSelf.view.superview?.bringSubviewToFront(strongSelf.view) } else { strongSelf.highlightedBackgroundNode.alpha = 0.0 strongSelf.highlightedBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2) diff --git a/submodules/TelegramUI/TelegramUI/SecureIdAuthPasswordOptionContentNode.swift b/submodules/TelegramUI/TelegramUI/SecureIdAuthPasswordOptionContentNode.swift index 4566301b88..82d7d57159 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdAuthPasswordOptionContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdAuthPasswordOptionContentNode.swift @@ -3,6 +3,7 @@ import UIKit import AsyncDisplayKit import Display import TelegramPresentationData +import ActivityIndicator private let passwordFont = Font.regular(16.0) private let buttonFont = Font.regular(17.0) diff --git a/submodules/TelegramUI/TelegramUI/SecureIdDocumentFormController.swift b/submodules/TelegramUI/TelegramUI/SecureIdDocumentFormController.swift index 1a9232d203..a04644f33a 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdDocumentFormController.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdDocumentFormController.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ProgressNavigationButtonNode enum SecureIdDocumentFormScrollToSubject { case selfie @@ -18,7 +19,7 @@ enum SecureIdDocumentFormRequestedData { } final class SecureIdDocumentFormController: FormController { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let updatedValues: ([SecureIdValueWithContext]) -> Void @@ -31,7 +32,7 @@ final class SecureIdDocumentFormController: FormController Void) { + init(context: AccountContextImpl, secureIdContext: SecureIdAccessContext, requestedData: SecureIdDocumentFormRequestedData, requestOptionalData: Bool = false, scrollTo: SecureIdDocumentFormScrollToSubject? = nil, primaryLanguageByCountry: [String: String], values: [SecureIdValueWithContext], updatedValues: @escaping ([SecureIdValueWithContext]) -> Void) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.secureIdContext = secureIdContext diff --git a/submodules/TelegramUI/TelegramUI/SecureIdDocumentFormControllerNode.swift b/submodules/TelegramUI/TelegramUI/SecureIdDocumentFormControllerNode.swift index f38e967a3c..164494e4e5 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdDocumentFormControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdDocumentFormControllerNode.swift @@ -2126,7 +2126,7 @@ enum SecureIdDocumentFormEntry: FormControllerEntry { } struct SecureIdDocumentFormControllerNodeInitParams { - let context: AccountContext + let context: AccountContextImpl let secureIdContext: SecureIdAccessContext } @@ -2139,7 +2139,7 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode Void) -> GalleryItem { + func item(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings, secureIdContext: SecureIdAccessContext, delete: @escaping (TelegramMediaResource) -> Void) -> GalleryItem { return SecureIdDocumentGalleryItem(context: context, theme: theme, strings: strings, secureIdContext: secureIdContext, resource: self.resource, caption: self.error, location: self.location, delete: { delete(self.resource) }) @@ -47,7 +47,7 @@ class SecureIdDocumentGalleryController: ViewController { return self.displayNode as! GalleryControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let secureIdContext: SecureIdAccessContext private var presentationData: PresentationData @@ -77,7 +77,7 @@ class SecureIdDocumentGalleryController: ViewController { var deleteResource: ((TelegramMediaResource) -> Void)? - init(context: AccountContext, secureIdContext: SecureIdAccessContext, entries: [SecureIdDocumentGalleryEntry], centralIndex: Int, replaceRootController: @escaping (ViewController, ValuePromise?) -> Void) { + init(context: AccountContextImpl, secureIdContext: SecureIdAccessContext, entries: [SecureIdDocumentGalleryEntry], centralIndex: Int, replaceRootController: @escaping (ViewController, ValuePromise?) -> Void) { self.context = context self.secureIdContext = secureIdContext self.replaceRootController = replaceRootController diff --git a/submodules/TelegramUI/TelegramUI/SecureIdDocumentGalleryFooterContentNode.swift b/submodules/TelegramUI/TelegramUI/SecureIdDocumentGalleryFooterContentNode.swift index 1bb75bda6e..65f8b78b32 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdDocumentGalleryFooterContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdDocumentGalleryFooterContentNode.swift @@ -15,7 +15,7 @@ private let titleFont = Font.medium(15.0) private let dateFont = Font.regular(14.0) final class SecureIdDocumentGalleryFooterContentNode: GalleryFooterContentNode { - private let context: AccountContext + private let context: AccountContextImpl private var theme: PresentationTheme private var strings: PresentationStrings @@ -30,7 +30,7 @@ final class SecureIdDocumentGalleryFooterContentNode: GalleryFooterContentNode { var delete: (() -> Void)? - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.context = context self.theme = theme self.strings = strings diff --git a/submodules/TelegramUI/TelegramUI/SecureIdDocumentImageGalleryItem.swift b/submodules/TelegramUI/TelegramUI/SecureIdDocumentImageGalleryItem.swift index 8be75a8dff..3a9faaed8b 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdDocumentImageGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdDocumentImageGalleryItem.swift @@ -8,7 +8,7 @@ import TelegramCore import TelegramPresentationData class SecureIdDocumentGalleryItem: GalleryItem { - let context: AccountContext + let context: AccountContextImpl let theme: PresentationTheme let strings: PresentationStrings let secureIdContext: SecureIdAccessContext @@ -17,7 +17,7 @@ class SecureIdDocumentGalleryItem: GalleryItem { let location: SecureIdDocumentGalleryEntryLocation let delete: () -> Void - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, secureIdContext: SecureIdAccessContext, resource: TelegramMediaResource, caption: String, location: SecureIdDocumentGalleryEntryLocation, delete: @escaping () -> Void) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings, secureIdContext: SecureIdAccessContext, resource: TelegramMediaResource, caption: String, location: SecureIdDocumentGalleryEntryLocation, delete: @escaping () -> Void) { self.context = context self.theme = theme self.strings = strings @@ -56,14 +56,14 @@ class SecureIdDocumentGalleryItem: GalleryItem { } final class SecureIdDocumentGalleryItemNode: ZoomableContentGalleryItemNode { - private let context: AccountContext + private let context: AccountContextImpl private let imageNode: TransformImageNode fileprivate let _ready = Promise() fileprivate let _title = Promise() private let footerContentNode: SecureIdDocumentGalleryFooterContentNode - private var contextAndMedia: (AccountContext, SecureIdAccessContext, TelegramMediaResource)? + private var contextAndMedia: (AccountContextImpl, SecureIdAccessContext, TelegramMediaResource)? private var fetchDisposable = MetaDisposable() @@ -73,7 +73,7 @@ final class SecureIdDocumentGalleryItemNode: ZoomableContentGalleryItemNode { } } - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.context = context self.imageNode = TransformImageNode() diff --git a/submodules/TelegramUI/TelegramUI/SecureIdDocumentTypeSelectionController.swift b/submodules/TelegramUI/TelegramUI/SecureIdDocumentTypeSelectionController.swift index fa25f2ba24..e0108f2922 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdDocumentTypeSelectionController.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdDocumentTypeSelectionController.swift @@ -80,7 +80,7 @@ final class SecureIdDocumentTypeSelectionController: ActionSheetController { return self._ready } - init(context: AccountContext, field: SecureIdParsedRequestedFormField, currentValues: [SecureIdValueWithContext], completion: @escaping (SecureIdDocumentFormRequestedData) -> Void) { + init(context: AccountContextImpl, field: SecureIdParsedRequestedFormField, currentValues: [SecureIdValueWithContext], completion: @escaping (SecureIdDocumentFormRequestedData) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/SecureIdLocalResource.swift b/submodules/TelegramUI/TelegramUI/SecureIdLocalResource.swift index aaeb98d409..50ea04d9de 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdLocalResource.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdLocalResource.swift @@ -132,7 +132,7 @@ func fetchSecureIdLocalImageResource(postbox: Postbox, resource: SecureIdLocalIm if let scaledImage = generateImage(image.size.fitted(CGSize(width: 2048.0, height: 2048.0)), contextGenerator: { size, context in context.setBlendMode(.copy) context.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: size)) - }, scale: 1.0), let scaledData = UIImageJPEGRepresentation(scaledImage, 0.6) { + }, scale: 1.0), let scaledData = scaledImage.jpegData(compressionQuality: 0.6) { subscriber.putNext(.dataPart(resourceOffset: 0, data: scaledData, range: 0 ..< scaledData.count, complete: true)) subscriber.putCompletion() } diff --git a/submodules/TelegramUI/TelegramUI/SecureIdPlaintextFormController.swift b/submodules/TelegramUI/TelegramUI/SecureIdPlaintextFormController.swift index 58dd22a98b..ab136c467a 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdPlaintextFormController.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdPlaintextFormController.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ProgressNavigationButtonNode enum SecureIdPlaintextFormType { case phone @@ -13,7 +14,7 @@ enum SecureIdPlaintextFormType { } final class SecureIdPlaintextFormController: FormController { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let updatedValue: (SecureIdValueWithContext?) -> Void @@ -24,7 +25,7 @@ final class SecureIdPlaintextFormController: FormController Void) { + init(context: AccountContextImpl, secureIdContext: SecureIdAccessContext, type: SecureIdPlaintextFormType, immediatelyAvailableValue: SecureIdValue?, updatedValue: @escaping (SecureIdValueWithContext?) -> Void) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.secureIdContext = secureIdContext diff --git a/submodules/TelegramUI/TelegramUI/SecureIdPlaintextFormControllerNode.swift b/submodules/TelegramUI/TelegramUI/SecureIdPlaintextFormControllerNode.swift index 223b59784e..76370cf70a 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdPlaintextFormControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdPlaintextFormControllerNode.swift @@ -625,7 +625,7 @@ enum SecureIdPlaintextFormEntry: FormControllerEntry { } struct SecureIdPlaintextFormControllerNodeInitParams { - let context: AccountContext + let context: AccountContextImpl let secureIdContext: SecureIdAccessContext } @@ -643,7 +643,7 @@ final class SecureIdPlaintextFormControllerNode: FormControllerNode Void)? diff --git a/submodules/TelegramUI/TelegramUI/SecureIdValueFormFileItem.swift b/submodules/TelegramUI/TelegramUI/SecureIdValueFormFileItem.swift index c3bfc12b60..2151c83402 100644 --- a/submodules/TelegramUI/TelegramUI/SecureIdValueFormFileItem.swift +++ b/submodules/TelegramUI/TelegramUI/SecureIdValueFormFileItem.swift @@ -4,6 +4,7 @@ import AsyncDisplayKit import Display import TelegramCore import TelegramPresentationData +import ItemListUI private let textFont = Font.regular(16.0) private let labelFont = Font.regular(13.0) diff --git a/submodules/TelegramUI/TelegramUI/SelectivePrivacySettingsController.swift b/submodules/TelegramUI/TelegramUI/SelectivePrivacySettingsController.swift index 4a049fae3d..2810895775 100644 --- a/submodules/TelegramUI/TelegramUI/SelectivePrivacySettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/SelectivePrivacySettingsController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI enum SelectivePrivacySettingsKind { case presence @@ -39,7 +40,7 @@ enum SelectivePrivacySettingsPeerTarget { } private final class SelectivePrivacySettingsControllerArguments { - let context: AccountContext + let context: AccountContextImpl let updateType: (SelectivePrivacySettingType) -> Void let openSelective: (SelectivePrivacySettingsPeerTarget, Bool) -> Void @@ -47,7 +48,7 @@ private final class SelectivePrivacySettingsControllerArguments { let updateCallP2PMode: ((SelectivePrivacySettingType) -> Void)? let updateCallIntegrationEnabled: ((Bool) -> Void)? - init(context: AccountContext, updateType: @escaping (SelectivePrivacySettingType) -> Void, openSelective: @escaping (SelectivePrivacySettingsPeerTarget, Bool) -> Void, updateCallP2PMode: ((SelectivePrivacySettingType) -> Void)?, updateCallIntegrationEnabled: ((Bool) -> Void)?) { + init(context: AccountContextImpl, updateType: @escaping (SelectivePrivacySettingType) -> Void, openSelective: @escaping (SelectivePrivacySettingsPeerTarget, Bool) -> Void, updateCallP2PMode: ((SelectivePrivacySettingType) -> Void)?, updateCallIntegrationEnabled: ((Bool) -> Void)?) { self.context = context self.updateType = updateType self.openSelective = openSelective @@ -578,7 +579,7 @@ private func selectivePrivacySettingsControllerEntries(presentationData: Present return entries } -func selectivePrivacySettingsController(context: AccountContext, kind: SelectivePrivacySettingsKind, current: SelectivePrivacySettings, callSettings: (SelectivePrivacySettings, VoiceCallSettings)? = nil, voipConfiguration: VoipConfiguration? = nil, callIntegrationAvailable: Bool? = nil, updated: @escaping (SelectivePrivacySettings, (SelectivePrivacySettings, VoiceCallSettings)?) -> Void) -> ViewController { +func selectivePrivacySettingsController(context: AccountContextImpl, kind: SelectivePrivacySettingsKind, current: SelectivePrivacySettings, callSettings: (SelectivePrivacySettings, VoiceCallSettings)? = nil, voipConfiguration: VoipConfiguration? = nil, callIntegrationAvailable: Bool? = nil, updated: @escaping (SelectivePrivacySettings, (SelectivePrivacySettings, VoiceCallSettings)?) -> Void) -> ViewController { let strings = context.sharedContext.currentPresentationData.with { $0 }.strings var initialEnableFor: [PeerId: SelectivePrivacyPeer] = [:] diff --git a/submodules/TelegramUI/TelegramUI/SelectivePrivacySettingsPeersController.swift b/submodules/TelegramUI/TelegramUI/SelectivePrivacySettingsPeersController.swift index 51cb25224a..ea0c92a7c2 100644 --- a/submodules/TelegramUI/TelegramUI/SelectivePrivacySettingsPeersController.swift +++ b/submodules/TelegramUI/TelegramUI/SelectivePrivacySettingsPeersController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class SelectivePrivacyPeersControllerArguments { let account: Account @@ -222,7 +223,7 @@ private func selectivePrivacyPeersControllerEntries(presentationData: Presentati return entries } -public func selectivePrivacyPeersController(context: AccountContext, title: String, initialPeers: [PeerId: SelectivePrivacyPeer], updated: @escaping ([PeerId: SelectivePrivacyPeer]) -> Void) -> ViewController { +public func selectivePrivacyPeersController(context: AccountContextImpl, title: String, initialPeers: [PeerId: SelectivePrivacyPeer], updated: @escaping ([PeerId: SelectivePrivacyPeer]) -> Void) -> ViewController { let statePromise = ValuePromise(SelectivePrivacyPeersControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: SelectivePrivacyPeersControllerState()) let updateState: ((SelectivePrivacyPeersControllerState) -> SelectivePrivacyPeersControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/SettingsController.swift b/submodules/TelegramUI/TelegramUI/SettingsController.swift index ace72d9478..7f19bfffea 100644 --- a/submodules/TelegramUI/TelegramUI/SettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/SettingsController.swift @@ -14,6 +14,7 @@ import MtProtoKitDynamic import TelegramPresentationData import TelegramUIPreferences import DeviceAccess +import ItemListUI private let maximumNumberOfAccounts = 3 @@ -530,12 +531,12 @@ private func settingsEntries(account: Account, presentationData: PresentationDat } public protocol SettingsController: class { - func updateContext(context: AccountContext) + func updateContext(context: AccountContextImpl) } private final class SettingsControllerImpl: ItemListController, SettingsController, TabBarContainedController { - let sharedContext: SharedAccountContext - let contextValue: Promise + let sharedContext: SharedAccountContextImpl + let contextValue: Promise var accountsAndPeersValue: ((Account, Peer)?, [(Account, Peer, Int32)])? var accountsAndPeersDisposable: Disposable? @@ -548,7 +549,7 @@ private final class SettingsControllerImpl: ItemListController, S return false } - init(currentContext: AccountContext, contextValue: Promise, state: Signal<(ItemListControllerState, (ItemListNodeState, SettingsEntry.ItemGenerationArguments)), NoError>, tabBarItem: Signal?, accountsAndPeers: Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError>) { + init(currentContext: AccountContextImpl, contextValue: Promise, state: Signal<(ItemListControllerState, (ItemListNodeState, SettingsEntry.ItemGenerationArguments)), NoError>, tabBarItem: Signal?, accountsAndPeers: Signal<((Account, Peer)?, [(Account, Peer, Int32)]), NoError>) { self.sharedContext = currentContext.sharedContext self.contextValue = contextValue let presentationData = currentContext.sharedContext.currentPresentationData.with { $0 } @@ -577,7 +578,7 @@ private final class SettingsControllerImpl: ItemListController, S self.accountsAndPeersDisposable?.dispose() } - func updateContext(context: AccountContext) { + func updateContext(context: AccountContextImpl) { //self.contextValue.set(.single(context)) } @@ -598,7 +599,7 @@ private final class SettingsControllerImpl: ItemListController, S } } -public func settingsController(context: AccountContext, accountManager: AccountManager) -> SettingsController & ViewController { +public func settingsController(context: AccountContextImpl, accountManager: AccountManager) -> SettingsController & ViewController { let initialState = SettingsState(updatingAvatar: nil, accountIdWithRevealedOptions: nil, isSearching: false) let statePromise = ValuePromise(initialState, ignoreRepeated: true) let stateValue = Atomic(value: initialState) @@ -640,7 +641,7 @@ public func settingsController(context: AccountContext, accountManager: AccountM let archivedPacks = Promise<[ArchivedStickerPackItem]?>() - let contextValue = Promise() + let contextValue = Promise() let accountsAndPeers = Promise<((Account, Peer)?, [(Account, Peer, Int32)])>() accountsAndPeers.set(activeAccountsAndPeers(context: context)) @@ -920,7 +921,7 @@ public func settingsController(context: AccountContext, accountManager: AccountM } let completedImpl: (UIImage) -> Void = { image in - if let data = UIImageJPEGRepresentation(image, 0.6) { + if let data = image.jpegData(compressionQuality: 0.6) { let resource = LocalFileMediaResource(fileId: arc4random64()) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) let representation = TelegramMediaImageRepresentation(dimensions: CGSize(width: 640.0, height: 640.0), resource: resource) @@ -1368,14 +1369,14 @@ public func settingsController(context: AccountContext, accountManager: AccountM } } }) - var sharedContext: SharedAccountContext? + var sharedContext: SharedAccountContextImpl? let _ = (contextValue.get() |> deliverOnMainQueue |> take(1)).start(next: { context in sharedContext = context.sharedContext }) if let selectedAccount = selectedAccount, let sharedContext = sharedContext { - let accountContext = AccountContext(sharedContext: sharedContext, account: selectedAccount, limitsConfiguration: LimitsConfiguration.defaultValue) + let accountContext = AccountContextImpl(sharedContext: sharedContext, account: selectedAccount, limitsConfiguration: LimitsConfiguration.defaultValue) let chatListController = ChatListController(context: accountContext, groupId: .root, controlsHistoryPreload: false, hideNetworkActivityStatus: true) return chatListController } diff --git a/submodules/TelegramUI/TelegramUI/SettingsSearchItem.swift b/submodules/TelegramUI/TelegramUI/SettingsSearchItem.swift index 3717833e9d..93e9893424 100644 --- a/submodules/TelegramUI/TelegramUI/SettingsSearchItem.swift +++ b/submodules/TelegramUI/TelegramUI/SettingsSearchItem.swift @@ -6,6 +6,8 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import MergeLists +import ItemListUI extension NavigationBarSearchContentNode: ItemListControllerSearchNavigationContentNode { func activate() { @@ -54,7 +56,7 @@ extension SettingsSearchableItemIcon { } final class SettingsSearchItem: ItemListControllerSearch { - let context: AccountContext + let context: AccountContextImpl let theme: PresentationTheme let placeholder: String let activated: Bool @@ -70,7 +72,7 @@ final class SettingsSearchItem: ItemListControllerSearch { private var activity: ValuePromise = ValuePromise(ignoreRepeated: false) private let activityDisposable = MetaDisposable() - init(context: AccountContext, theme: PresentationTheme, placeholder: String, activated: Bool, updateActivated: @escaping (Bool) -> Void, presentController: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, getNavigationController: (() -> NavigationController?)?, exceptionsList: Signal, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal) { + init(context: AccountContextImpl, theme: PresentationTheme, placeholder: String, activated: Bool, updateActivated: @escaping (Bool) -> Void, presentController: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, getNavigationController: (() -> NavigationController?)?, exceptionsList: Signal, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal) { self.context = context self.theme = theme self.placeholder = placeholder @@ -319,7 +321,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN private var presentationDataDisposable: Disposable? private let presentationDataPromise: Promise - init(context: AccountContext, openResult: @escaping (SettingsSearchableItem) -> Void, exceptionsList: Signal, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal) { + init(context: AccountContextImpl, openResult: @escaping (SettingsSearchableItem) -> Void, exceptionsList: Signal, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal) { self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.presentationDataPromise = Promise(self.presentationData) @@ -615,7 +617,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN } private final class SettingsSearchItemNode: ItemListControllerSearchNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private var containerLayout: (ContainerViewLayout, CGFloat)? private var searchDisplayController: SearchDisplayController? @@ -629,7 +631,7 @@ private final class SettingsSearchItemNode: ItemListControllerSearchNode { var cancel: () -> Void - init(context: AccountContext, cancel: @escaping () -> Void, updateActivity: @escaping(Bool) -> Void, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, Any?) -> Void, getNavigationController: (() -> NavigationController?)?, exceptionsList: Signal, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal) { + init(context: AccountContextImpl, cancel: @escaping () -> Void, updateActivity: @escaping(Bool) -> Void, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, Any?) -> Void, getNavigationController: (() -> NavigationController?)?, exceptionsList: Signal, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.cancel = cancel diff --git a/submodules/TelegramUI/TelegramUI/SettingsSearchRecentItem.swift b/submodules/TelegramUI/TelegramUI/SettingsSearchRecentItem.swift index 10a0728ff9..4186991bfc 100644 --- a/submodules/TelegramUI/TelegramUI/SettingsSearchRecentItem.swift +++ b/submodules/TelegramUI/TelegramUI/SettingsSearchRecentItem.swift @@ -6,6 +6,7 @@ import Display import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ItemListUI private enum RevealOptionKey: Int32 { case delete diff --git a/submodules/TelegramUI/TelegramUI/SettingsSearchResultItem.swift b/submodules/TelegramUI/TelegramUI/SettingsSearchResultItem.swift index 8cfecb6174..565a2c0279 100644 --- a/submodules/TelegramUI/TelegramUI/SettingsSearchResultItem.swift +++ b/submodules/TelegramUI/TelegramUI/SettingsSearchResultItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI class SettingsSearchResultItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/SettingsSearchableItems.swift b/submodules/TelegramUI/TelegramUI/SettingsSearchableItems.swift index 4475fd34e5..ffc7f55141 100644 --- a/submodules/TelegramUI/TelegramUI/SettingsSearchableItems.swift +++ b/submodules/TelegramUI/TelegramUI/SettingsSearchableItems.swift @@ -150,7 +150,7 @@ struct SettingsSearchableItem { let alternate: [String] let icon: SettingsSearchableItemIcon let breadcrumbs: [String] - let present: (AccountContext, NavigationController?, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void + let present: (AccountContextImpl, NavigationController?, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void } private func synonyms(_ string: String?) -> [String] { @@ -161,11 +161,11 @@ private func synonyms(_ string: String?) -> [String] { } } -private func profileSearchableItems(context: AccountContext, canAddAccount: Bool) -> [SettingsSearchableItem] { +private func profileSearchableItems(context: AccountContextImpl, canAddAccount: Bool) -> [SettingsSearchableItem] { let icon: SettingsSearchableItemIcon = .profile let strings = context.sharedContext.currentPresentationData.with { $0 }.strings - let presentProfileSettings: (AccountContext, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void, EditSettingsEntryTag?) -> Void = { context, present, itemTag in + let presentProfileSettings: (AccountContextImpl, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void, EditSettingsEntryTag?) -> Void = { context, present, itemTag in let _ = openEditSettings(context: context, accountsAndPeers: activeAccountsAndPeers(context: context), focusOnItemTag: itemTag, presentController: { controller, _ in present(.immediate, controller) }, pushController: { controller in @@ -211,11 +211,11 @@ private func profileSearchableItems(context: AccountContext, canAddAccount: Bool return items } -private func callSearchableItems(context: AccountContext) -> [SettingsSearchableItem] { +private func callSearchableItems(context: AccountContextImpl) -> [SettingsSearchableItem] { let icon: SettingsSearchableItemIcon = .calls let strings = context.sharedContext.currentPresentationData.with { $0 }.strings - let presentCallSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { context, present in + let presentCallSettings: (AccountContextImpl, (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { context, present in present(.push, CallListController(context: context, mode: .navigation)) } @@ -229,11 +229,11 @@ private func callSearchableItems(context: AccountContext) -> [SettingsSearchable ] } -private func stickerSearchableItems(context: AccountContext, archivedStickerPacks: [ArchivedStickerPackItem]?) -> [SettingsSearchableItem] { +private func stickerSearchableItems(context: AccountContextImpl, archivedStickerPacks: [ArchivedStickerPackItem]?) -> [SettingsSearchableItem] { let icon: SettingsSearchableItemIcon = .stickers let strings = context.sharedContext.currentPresentationData.with { $0 }.strings - let presentStickerSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, InstalledStickerPacksEntryTag?) -> Void = { context, present, itemTag in + let presentStickerSettings: (AccountContextImpl, (SettingsSearchableItemPresentation, ViewController?) -> Void, InstalledStickerPacksEntryTag?) -> Void = { context, present, itemTag in present(.push, installedStickerPacksController(context: context, mode: .general, archivedPacks: archivedStickerPacks, updatedPacks: { _ in }, focusOnItemTag: itemTag)) } @@ -259,11 +259,11 @@ private func stickerSearchableItems(context: AccountContext, archivedStickerPack return items } -private func notificationSearchableItems(context: AccountContext, settings: GlobalNotificationSettingsSet, exceptionsList: NotificationExceptionsList?) -> [SettingsSearchableItem] { +private func notificationSearchableItems(context: AccountContextImpl, settings: GlobalNotificationSettingsSet, exceptionsList: NotificationExceptionsList?) -> [SettingsSearchableItem] { let icon: SettingsSearchableItemIcon = .notifications let strings = context.sharedContext.currentPresentationData.with { $0 }.strings - let presentNotificationSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, NotificationsAndSoundsEntryTag?) -> Void = { context, present, itemTag in + let presentNotificationSettings: (AccountContextImpl, (SettingsSearchableItemPresentation, ViewController?) -> Void, NotificationsAndSoundsEntryTag?) -> Void = { context, present, itemTag in present(.push, notificationsAndSoundsController(context: context, exceptionsList: exceptionsList, focusOnItemTag: itemTag)) } @@ -412,15 +412,15 @@ private func notificationSearchableItems(context: AccountContext, settings: Glob ] } -private func privacySearchableItems(context: AccountContext, privacySettings: AccountPrivacySettings?) -> [SettingsSearchableItem] { +private func privacySearchableItems(context: AccountContextImpl, privacySettings: AccountPrivacySettings?) -> [SettingsSearchableItem] { let icon: SettingsSearchableItemIcon = .privacy let strings = context.sharedContext.currentPresentationData.with { $0 }.strings - let presentPrivacySettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, PrivacyAndSecurityEntryTag?) -> Void = { context, present, itemTag in + let presentPrivacySettings: (AccountContextImpl, (SettingsSearchableItemPresentation, ViewController?) -> Void, PrivacyAndSecurityEntryTag?) -> Void = { context, present, itemTag in present(.push, privacyAndSecurityController(context: context, focusOnItemTag: itemTag)) } - let presentSelectivePrivacySettings: (AccountContext, SelectivePrivacySettingsKind, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { context, kind, present in + let presentSelectivePrivacySettings: (AccountContextImpl, SelectivePrivacySettingsKind, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { context, kind, present in let privacySignal: Signal if let privacySettings = privacySettings { privacySignal = .single(privacySettings) @@ -468,7 +468,7 @@ private func privacySearchableItems(context: AccountContext, privacySettings: Ac }) } - let presentDataPrivacySettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { context, present in + let presentDataPrivacySettings: (AccountContextImpl, (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { context, present in present(.push, dataPrivacyController(context: context)) } @@ -560,11 +560,11 @@ private func privacySearchableItems(context: AccountContext, privacySettings: Ac ] } -private func dataSearchableItems(context: AccountContext) -> [SettingsSearchableItem] { +private func dataSearchableItems(context: AccountContextImpl) -> [SettingsSearchableItem] { let icon: SettingsSearchableItemIcon = .data let strings = context.sharedContext.currentPresentationData.with { $0 }.strings - let presentDataSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, DataAndStorageEntryTag?) -> Void = { context, present, itemTag in + let presentDataSettings: (AccountContextImpl, (SettingsSearchableItemPresentation, ViewController?) -> Void, DataAndStorageEntryTag?) -> Void = { context, present, itemTag in present(.push, dataAndStorageController(context: context, focusOnItemTag: itemTag)) } @@ -614,11 +614,11 @@ private func dataSearchableItems(context: AccountContext) -> [SettingsSearchable ] } -private func proxySearchableItems(context: AccountContext, servers: [ProxyServerSettings]) -> [SettingsSearchableItem] { +private func proxySearchableItems(context: AccountContextImpl, servers: [ProxyServerSettings]) -> [SettingsSearchableItem] { let icon: SettingsSearchableItemIcon = .proxy let strings = context.sharedContext.currentPresentationData.with { $0 }.strings - let presentProxySettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { context, present in + let presentProxySettings: (AccountContextImpl, (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { context, present in present(.push, proxySettingsController(context: context)) } @@ -645,11 +645,11 @@ private func proxySearchableItems(context: AccountContext, servers: [ProxyServer return items } -private func appearanceSearchableItems(context: AccountContext) -> [SettingsSearchableItem] { +private func appearanceSearchableItems(context: AccountContextImpl) -> [SettingsSearchableItem] { let icon: SettingsSearchableItemIcon = .appearance let strings = context.sharedContext.currentPresentationData.with { $0 }.strings - let presentAppearanceSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, ThemeSettingsEntryTag?) -> Void = { context, present, itemTag in + let presentAppearanceSettings: (AccountContextImpl, (SettingsSearchableItemPresentation, ViewController?) -> Void, ThemeSettingsEntryTag?) -> Void = { context, present, itemTag in present(.push, themeSettingsController(context: context, focusOnItemTag: itemTag)) } @@ -686,11 +686,11 @@ private func appearanceSearchableItems(context: AccountContext) -> [SettingsSear ] } -private func languageSearchableItems(context: AccountContext, localizations: [LocalizationInfo]) -> [SettingsSearchableItem] { +private func languageSearchableItems(context: AccountContextImpl, localizations: [LocalizationInfo]) -> [SettingsSearchableItem] { let icon: SettingsSearchableItemIcon = .language let strings = context.sharedContext.currentPresentationData.with { $0 }.strings - let applyLocalization: (AccountContext, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void, String) -> Void = { context, present, languageCode in + let applyLocalization: (AccountContextImpl, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void, String) -> Void = { context, present, languageCode in let presentationData = context.sharedContext.currentPresentationData.with { $0 } let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: nil)) present(.immediate, controller) @@ -716,7 +716,7 @@ private func languageSearchableItems(context: AccountContext, localizations: [Lo return items } -func settingsSearchableItems(context: AccountContext, notificationExceptionsList: Signal, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal) -> Signal<[SettingsSearchableItem], NoError> { +func settingsSearchableItems(context: AccountContextImpl, notificationExceptionsList: Signal, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, privacySettings: Signal) -> Signal<[SettingsSearchableItem], NoError> { let watchAppInstalled = (context.watchManager?.watchAppInstalled ?? .single(false)) |> take(1) diff --git a/submodules/TelegramUI/TelegramUI/SettingsThemeWallpaperNode.swift b/submodules/TelegramUI/TelegramUI/SettingsThemeWallpaperNode.swift index 41eedf98fb..749f634fe5 100644 --- a/submodules/TelegramUI/TelegramUI/SettingsThemeWallpaperNode.swift +++ b/submodules/TelegramUI/TelegramUI/SettingsThemeWallpaperNode.swift @@ -59,7 +59,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { self.statusNode.transitionToState(state, animated: animated, completion: {}) } - func setWallpaper(context: AccountContext, wallpaper: TelegramWallpaper, selected: Bool, size: CGSize, cornerRadius: CGFloat = 0.0, synchronousLoad: Bool = false) { + func setWallpaper(context: AccountContextImpl, wallpaper: TelegramWallpaper, selected: Bool, size: CGSize, cornerRadius: CGFloat = 0.0, synchronousLoad: Bool = false) { self.buttonNode.frame = CGRect(origin: CGPoint(), size: size) self.backgroundNode.frame = CGRect(origin: CGPoint(), size: size) self.imageNode.frame = CGRect(origin: CGPoint(), size: size) diff --git a/submodules/TelegramUI/TelegramUI/SetupTwoStepVerificationController.swift b/submodules/TelegramUI/TelegramUI/SetupTwoStepVerificationController.swift index 0bf264afdb..7447f027dc 100644 --- a/submodules/TelegramUI/TelegramUI/SetupTwoStepVerificationController.swift +++ b/submodules/TelegramUI/TelegramUI/SetupTwoStepVerificationController.swift @@ -6,9 +6,10 @@ import Postbox import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ProgressNavigationButtonNode class SetupTwoStepVerificationController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private let initialState: SetupTwoStepVerificationInitialState private let stateUpdated: (SetupTwoStepVerificationStateUpdate, Bool, SetupTwoStepVerificationController) -> Void @@ -29,7 +30,7 @@ class SetupTwoStepVerificationController: ViewController { private var presentationData: PresentationData private var presentationDataDisposable: Disposable? - init(context: AccountContext, initialState: SetupTwoStepVerificationInitialState, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate, Bool, SetupTwoStepVerificationController) -> Void) { + init(context: AccountContextImpl, initialState: SetupTwoStepVerificationInitialState, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate, Bool, SetupTwoStepVerificationController) -> Void) { self.context = context self.initialState = initialState self.stateUpdated = stateUpdated diff --git a/submodules/TelegramUI/TelegramUI/SetupTwoStepVerificationControllerNode.swift b/submodules/TelegramUI/TelegramUI/SetupTwoStepVerificationControllerNode.swift index 25c114647b..f8d90dc440 100644 --- a/submodules/TelegramUI/TelegramUI/SetupTwoStepVerificationControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/SetupTwoStepVerificationControllerNode.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import ActivityIndicator enum SetupTwoStepVerificationInitialState { case automatic @@ -136,7 +137,7 @@ enum SetupTwoStepVerificationStateUpdate { } final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let updateBackAction: (Bool) -> Void private let updateNextAction: (SetupTwoStepVerificationNextAction) -> Void @@ -149,7 +150,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { private var contentNode: SetupTwoStepVerificationContentNode? private let actionDisposable = MetaDisposable() - init(context: AccountContext, updateBackAction: @escaping (Bool) -> Void, updateNextAction: @escaping (SetupTwoStepVerificationNextAction) -> Void, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate, Bool) -> Void, present: @escaping (ViewController, Any?) -> Void, dismiss: @escaping () -> Void, initialState: SetupTwoStepVerificationInitialState) { + init(context: AccountContextImpl, updateBackAction: @escaping (Bool) -> Void, updateNextAction: @escaping (SetupTwoStepVerificationNextAction) -> Void, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate, Bool) -> Void, present: @escaping (ViewController, Any?) -> Void, dismiss: @escaping () -> Void, initialState: SetupTwoStepVerificationInitialState) { self.context = context self.updateBackAction = updateBackAction self.updateNextAction = updateNextAction @@ -205,7 +206,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/ShareController.swift b/submodules/TelegramUI/TelegramUI/ShareController.swift index 55c526dee1..e04b150f5a 100644 --- a/submodules/TelegramUI/TelegramUI/ShareController.swift +++ b/submodules/TelegramUI/TelegramUI/ShareController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import TextFormat public struct ShareControllerAction { let title: String @@ -191,8 +192,8 @@ public final class ShareController: ViewController { private var animatedIn = false - private let sharedContext: SharedAccountContext - private let currentContext: AccountContext + private let sharedContext: SharedAccountContextImpl + private let currentContext: AccountContextImpl private var currentAccount: Account private var presentationData: PresentationData private var presentationDataDisposable: Disposable? @@ -211,11 +212,11 @@ public final class ShareController: ViewController { public var dismissed: ((Bool) -> Void)? - public convenience init(context: AccountContext, subject: ShareControllerSubject, preferredAction: ShareControllerPreferredAction = .default, showInChat: ((Message) -> Void)? = nil, externalShare: Bool = true, immediateExternalShare: Bool = false, switchableAccounts: [AccountWithInfo] = []) { + public convenience init(context: AccountContextImpl, subject: ShareControllerSubject, preferredAction: ShareControllerPreferredAction = .default, showInChat: ((Message) -> Void)? = nil, externalShare: Bool = true, immediateExternalShare: Bool = false, switchableAccounts: [AccountWithInfo] = []) { self.init(sharedContext: context.sharedContext, currentContext: context, subject: subject, preferredAction: preferredAction, showInChat: showInChat, externalShare: externalShare, immediateExternalShare: immediateExternalShare, switchableAccounts: switchableAccounts) } - public init(sharedContext: SharedAccountContext, currentContext: AccountContext, subject: ShareControllerSubject, preferredAction: ShareControllerPreferredAction = .default, showInChat: ((Message) -> Void)? = nil, externalShare: Bool = true, immediateExternalShare: Bool = false, switchableAccounts: [AccountWithInfo] = []) { + public init(sharedContext: SharedAccountContextImpl, currentContext: AccountContextImpl, subject: ShareControllerSubject, preferredAction: ShareControllerPreferredAction = .default, showInChat: ((Message) -> Void)? = nil, externalShare: Bool = true, immediateExternalShare: Bool = false, switchableAccounts: [AccountWithInfo] = []) { self.sharedContext = sharedContext self.currentContext = currentContext self.currentAccount = currentContext.account @@ -655,11 +656,11 @@ public final class ShareController: ViewController { let postbox = self.currentAccount.postbox let signals: [Signal] = messages.compactMap { message -> Signal? in if let media = message.media.first { - let context: AccountContext + let context: AccountContextImpl if self.currentContext.account.id == self.currentAccount.id { context = self.currentContext } else { - context = AccountContext(sharedContext: self.sharedContext, account: self.currentAccount, limitsConfiguration: .defaultValue) + context = AccountContextImpl(sharedContext: self.sharedContext, account: self.currentAccount, limitsConfiguration: .defaultValue) } return TelegramUI.saveToCameraRoll(context: context, postbox: postbox, mediaReference: .message(message: MessageReference(message), media: media)) } else { @@ -682,21 +683,21 @@ public final class ShareController: ViewController { private func saveToCameraRoll(representations: [ImageRepresentationWithReference]) { let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil) - let context: AccountContext + let context: AccountContextImpl if self.currentContext.account.id == self.currentAccount.id { context = self.currentContext } else { - context = AccountContext(sharedContext: self.sharedContext, account: self.currentAccount, limitsConfiguration: .defaultValue) + context = AccountContextImpl(sharedContext: self.sharedContext, account: self.currentAccount, limitsConfiguration: .defaultValue) } self.controllerNode.transitionToProgressWithValue(signal: TelegramUI.saveToCameraRoll(context: context, postbox: context.account.postbox, mediaReference: .standalone(media: media)) |> map(Optional.init)) } private func saveToCameraRoll(mediaReference: AnyMediaReference) { - let context: AccountContext + let context: AccountContextImpl if self.currentContext.account.id == self.currentAccount.id { context = self.currentContext } else { - context = AccountContext(sharedContext: self.sharedContext, account: self.currentAccount, limitsConfiguration: .defaultValue) + context = AccountContextImpl(sharedContext: self.sharedContext, account: self.currentAccount, limitsConfiguration: .defaultValue) } self.controllerNode.transitionToProgressWithValue(signal: TelegramUI.saveToCameraRoll(context: context, postbox: context.account.postbox, mediaReference: mediaReference) |> map(Optional.init)) } diff --git a/submodules/TelegramUI/TelegramUI/ShareControllerNode.swift b/submodules/TelegramUI/TelegramUI/ShareControllerNode.swift index 2c513d1eff..6445b5e5ab 100644 --- a/submodules/TelegramUI/TelegramUI/ShareControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ShareControllerNode.swift @@ -23,7 +23,7 @@ func openExternalShare(state: () -> Signal) { } final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate { - private let sharedContext: SharedAccountContext + private let sharedContext: SharedAccountContextImpl private var presentationData: PresentationData private let externalShare: Bool private let immediateExternalShare: Bool @@ -71,7 +71,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate private var hapticFeedback: HapticFeedback? - init(sharedContext: SharedAccountContext, defaultAction: ShareControllerAction?, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, presentError: @escaping (String?, String) -> Void, externalShare: Bool, immediateExternalShare: Bool) { + init(sharedContext: SharedAccountContextImpl, defaultAction: ShareControllerAction?, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, presentError: @escaping (String?, String) -> Void, externalShare: Bool, immediateExternalShare: Bool) { self.sharedContext = sharedContext self.presentationData = sharedContext.currentPresentationData.with { $0 } self.externalShare = externalShare @@ -339,8 +339,8 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate contentNode.alpha = 1.0 if animated { - let animation = contentNode.layer.makeAnimation(from: 0.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "opacity", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.35) - animation.fillMode = kCAFillModeBoth + let animation = contentNode.layer.makeAnimation(from: 0.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "opacity", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.35) + animation.fillMode = .both if !fastOut { animation.beginTime = CACurrentMediaTime() + 0.1 } diff --git a/submodules/TelegramUI/TelegramUI/ShareExtensionContext.swift b/submodules/TelegramUI/TelegramUI/ShareExtensionContext.swift index 6ed084b7dc..b4b023f845 100644 --- a/submodules/TelegramUI/TelegramUI/ShareExtensionContext.swift +++ b/submodules/TelegramUI/TelegramUI/ShareExtensionContext.swift @@ -6,14 +6,15 @@ import Postbox import TelegramPresentationData import TelegramUIPreferences import TelegramUIPrivateModule +import AccountContext private let inForeground = ValuePromise(false, ignoreRepeated: true) private final class InternalContext { - let sharedContext: SharedAccountContext + let sharedContext: SharedAccountContextImpl let wakeupManager: SharedWakeupManager - init(sharedContext: SharedAccountContext) { + init(sharedContext: SharedAccountContextImpl) { self.sharedContext = sharedContext self.wakeupManager = SharedWakeupManager(beginBackgroundTask: { _, _ in nil }, endBackgroundTask: { _ in }, backgroundTimeRemaining: { 0.0 }, activeAccounts: sharedContext.activeAccounts |> map { ($0.0, $0.1.map { ($0.0, $0.1) }) }, liveLocationPolling: .single(nil), watchTasks: .single(nil), inForeground: inForeground.get(), hasActiveAudioSession: .single(false), notificationManager: nil, mediaManager: sharedContext.mediaManager, callManager: sharedContext.callManager, accountUserInterfaceInUse: { id in return sharedContext.accountUserInterfaceInUse(id) @@ -166,16 +167,16 @@ public class ShareRootControllerImpl { }) semaphore.wait() - let sharedContext = SharedAccountContext(mainWindow: nil, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, appData: .single(self.initializationData.bundleData)), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }) + let sharedContext = SharedAccountContextImpl(mainWindow: nil, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, appData: .single(self.initializationData.bundleData)), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }) internalContext = InternalContext(sharedContext: sharedContext) globalInternalContext = internalContext } - let account: Signal<(SharedAccountContext, Account, [AccountWithInfo]), ShareAuthorizationError> = internalContext.sharedContext.accountManager.transaction { transaction -> (SharedAccountContext, LoggingSettings) in + let account: Signal<(SharedAccountContextImpl, Account, [AccountWithInfo]), ShareAuthorizationError> = internalContext.sharedContext.accountManager.transaction { transaction -> (SharedAccountContextImpl, LoggingSettings) in return (internalContext.sharedContext, transaction.getSharedData(SharedDataKeys.loggingSettings) as? LoggingSettings ?? LoggingSettings.defaultSettings) } |> introduceError(ShareAuthorizationError.self) - |> mapToSignal { sharedContext, loggingSettings -> Signal<(SharedAccountContext, Account, [AccountWithInfo]), ShareAuthorizationError> in + |> mapToSignal { sharedContext, loggingSettings -> Signal<(SharedAccountContextImpl, Account, [AccountWithInfo]), ShareAuthorizationError> in Logger.shared.logToFile = loggingSettings.logToFile Logger.shared.logToConsole = loggingSettings.logToConsole @@ -184,7 +185,7 @@ public class ShareRootControllerImpl { return sharedContext.activeAccountsWithInfo |> introduceError(ShareAuthorizationError.self) |> take(1) - |> mapToSignal { primary, accounts -> Signal<(SharedAccountContext, Account, [AccountWithInfo]), ShareAuthorizationError> in + |> mapToSignal { primary, accounts -> Signal<(SharedAccountContextImpl, Account, [AccountWithInfo]), ShareAuthorizationError> in guard let primary = primary else { return .fail(.unauthorized) } @@ -197,7 +198,7 @@ public class ShareRootControllerImpl { |> take(1) let applicationInterface = account - |> mapToSignal { sharedContext, account, otherAccounts -> Signal<(AccountContext, PostboxAccessChallengeData, [AccountWithInfo]), ShareAuthorizationError> in + |> mapToSignal { sharedContext, account, otherAccounts -> Signal<(AccountContextImpl, PostboxAccessChallengeData, [AccountWithInfo]), ShareAuthorizationError> in let limitsConfiguration = account.postbox.transaction { transaction -> LimitsConfiguration in return transaction.getPreferencesEntry(key: PreferencesKeys.limitsConfiguration) as? LimitsConfiguration ?? LimitsConfiguration.defaultValue } @@ -205,9 +206,9 @@ public class ShareRootControllerImpl { |> take(1) |> deliverOnMainQueue |> introduceError(ShareAuthorizationError.self) - |> map { sharedData, limitsConfiguration, data -> (AccountContext, PostboxAccessChallengeData, [AccountWithInfo]) in + |> map { sharedData, limitsConfiguration, data -> (AccountContextImpl, PostboxAccessChallengeData, [AccountWithInfo]) in updateLegacyLocalization(strings: sharedContext.currentPresentationData.with({ $0 }).strings) - let context = AccountContext(sharedContext: sharedContext, account: account, limitsConfiguration: limitsConfiguration) + let context = AccountContextImpl(sharedContext: sharedContext, account: account, limitsConfiguration: limitsConfiguration) return (context, data.data, otherAccounts) } } diff --git a/submodules/TelegramUI/TelegramUI/ShareInputFieldNode.swift b/submodules/TelegramUI/TelegramUI/ShareInputFieldNode.swift index 11fc4ef4b2..9fe17aea07 100644 --- a/submodules/TelegramUI/TelegramUI/ShareInputFieldNode.swift +++ b/submodules/TelegramUI/TelegramUI/ShareInputFieldNode.swift @@ -90,7 +90,7 @@ final class ShareInputFieldNode: ASDisplayNode, ASEditableTextNodeDelegate { self.textInputNode = EditableTextNode() let textColor: UIColor = theme.textColor - self.textInputNode.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(17.0), NSAttributedStringKey.foregroundColor.rawValue: textColor] + self.textInputNode.typingAttributes = [NSAttributedString.Key.font.rawValue: Font.regular(17.0), NSAttributedString.Key.foregroundColor.rawValue: textColor] self.textInputNode.clipsToBounds = true self.textInputNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0) self.textInputNode.textContainerInset = UIEdgeInsets(top: self.inputInsets.top, left: 0.0, bottom: self.inputInsets.bottom, right: 0.0) diff --git a/submodules/TelegramUI/TelegramUI/ShareItems.swift b/submodules/TelegramUI/TelegramUI/ShareItems.swift index da2c87cf6f..3f987e080d 100644 --- a/submodules/TelegramUI/TelegramUI/ShareItems.swift +++ b/submodules/TelegramUI/TelegramUI/ShareItems.swift @@ -68,7 +68,7 @@ private func preparedShareItem(account: Account, to peerId: PeerId, value: [Stri } else if let image = value["image"] as? UIImage { let nativeImageSize = CGSize(width: image.size.width * image.scale, height: image.size.height * image.scale) let dimensions = nativeImageSize.fitted(CGSize(width: 1280.0, height: 1280.0)) - if let scaledImage = scalePhotoImage(image, dimensions: dimensions), let imageData = UIImageJPEGRepresentation(scaledImage, 0.52) { + if let scaledImage = scalePhotoImage(image, dimensions: dimensions), let imageData = scaledImage.jpegData(compressionQuality: 0.52) { return .single(.preparing) |> then(standaloneUploadedImage(account: account, peerId: peerId, text: "", data: imageData, dimensions: dimensions) |> mapError { _ -> Void in @@ -165,7 +165,7 @@ private func preparedShareItem(account: Account, to peerId: PeerId, value: [Stri } } else { let scaledImage = TGScaleImageToPixelSize(image, CGSize(width: image.size.width * image.scale, height: image.size.height * image.scale).fitted(CGSize(width: 1280.0, height: 1280.0)))! - let imageData = UIImageJPEGRepresentation(scaledImage, 0.54)! + let imageData = scaledImage.jpegData(compressionQuality: 0.54)! return standaloneUploadedImage(account: account, peerId: peerId, text: "", data: imageData, dimensions: scaledImage.size) |> mapError { _ -> Void in return Void() } |> mapToSignal { event -> Signal in @@ -179,7 +179,7 @@ private func preparedShareItem(account: Account, to peerId: PeerId, value: [Stri } } else { var thumbnailData: Data? - if mimeType == "application/pdf", let image = generatePdfPreviewImage(data: data, size: CGSize(width: 256.0, height: 256.0)), let jpegData = UIImageJPEGRepresentation(image, 0.5) { + if mimeType == "application/pdf", let image = generatePdfPreviewImage(data: data, size: CGSize(width: 256.0, height: 256.0)), let jpegData = image.jpegData(compressionQuality: 0.5) { thumbnailData = jpegData } diff --git a/submodules/TelegramUI/TelegramUI/ShareLoadingContainerNode.swift b/submodules/TelegramUI/TelegramUI/ShareLoadingContainerNode.swift index 33896988a7..9b2f0fb320 100644 --- a/submodules/TelegramUI/TelegramUI/ShareLoadingContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ShareLoadingContainerNode.swift @@ -4,6 +4,7 @@ import AsyncDisplayKit import Display import Postbox import TelegramPresentationData +import ActivityIndicator enum ShareLoadingState { case preparing diff --git a/submodules/TelegramUI/TelegramUI/SharePeersContainerNode.swift b/submodules/TelegramUI/TelegramUI/SharePeersContainerNode.swift index e453ff654b..688b2010cc 100644 --- a/submodules/TelegramUI/TelegramUI/SharePeersContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/SharePeersContainerNode.swift @@ -6,6 +6,7 @@ import TelegramCore import SwiftSignalKit import Display import TelegramPresentationData +import MergeLists private let subtitleFont = Font.regular(12.0) @@ -66,7 +67,7 @@ private func preparedGridEntryTransition(account: Account, from fromEntries: [Sh } final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode { - private let sharedContext: SharedAccountContext + private let sharedContext: SharedAccountContextImpl private let account: Account private let theme: PresentationTheme private let strings: PresentationStrings @@ -99,7 +100,7 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode { let peersValue = Promise<[(RenderedPeer, PeerPresence?)]>() - init(sharedContext: SharedAccountContext, account: Account, switchableAccounts: [AccountWithInfo], theme: PresentationTheme, strings: PresentationStrings, peers: [(RenderedPeer, PeerPresence?)], accountPeer: Peer, controllerInteraction: ShareControllerInteraction, externalShare: Bool, switchToAnotherAccount: @escaping () -> Void) { + init(sharedContext: SharedAccountContextImpl, account: Account, switchableAccounts: [AccountWithInfo], theme: PresentationTheme, strings: PresentationStrings, peers: [(RenderedPeer, PeerPresence?)], accountPeer: Peer, controllerInteraction: ShareControllerInteraction, externalShare: Bool, switchToAnotherAccount: @escaping () -> Void) { self.sharedContext = sharedContext self.account = account self.theme = theme diff --git a/submodules/TelegramUI/TelegramUI/ShareSearchBarNode.swift b/submodules/TelegramUI/TelegramUI/ShareSearchBarNode.swift index 183e3457d2..0101c5b2c1 100644 --- a/submodules/TelegramUI/TelegramUI/ShareSearchBarNode.swift +++ b/submodules/TelegramUI/TelegramUI/ShareSearchBarNode.swift @@ -44,7 +44,7 @@ final class ShareSearchBarNode: ASDisplayNode, UITextFieldDelegate { let keyboardAppearance: UIKeyboardAppearance = UIKeyboardAppearance.default textInputNode.textField.font = Font.regular(16.0) textInputNode.textField.textColor = textColor - textInputNode.textField.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(16.0), NSAttributedStringKey.foregroundColor.rawValue: textColor] + textInputNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(16.0), NSAttributedString.Key.foregroundColor: textColor] textInputNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0) textInputNode.textField.keyboardAppearance = keyboardAppearance textInputNode.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: Font.regular(16.0), textColor: theme.actionSheet.inputPlaceholderColor) diff --git a/submodules/TelegramUI/TelegramUI/ShareSearchContainerNode.swift b/submodules/TelegramUI/TelegramUI/ShareSearchContainerNode.swift index b13837cc34..4c0a3007fc 100644 --- a/submodules/TelegramUI/TelegramUI/ShareSearchContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ShareSearchContainerNode.swift @@ -6,6 +6,7 @@ import TelegramCore import SwiftSignalKit import Display import TelegramPresentationData +import MergeLists private let cancelFont = Font.regular(17.0) private let subtitleFont = Font.regular(12.0) @@ -164,7 +165,7 @@ private func preparedRecentEntryTransition(account: Account, from fromEntries: [ } final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode { - private let sharedContext: SharedAccountContext + private let sharedContext: SharedAccountContextImpl private let account: Account private let strings: PresentationStrings private let controllerInteraction: ShareControllerInteraction @@ -195,7 +196,7 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode { private let searchQuery = ValuePromise("", ignoreRepeated: true) private let searchDisposable = MetaDisposable() - init(sharedContext: SharedAccountContext, account: Account, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ShareControllerInteraction, recentPeers recentPeerList: [RenderedPeer]) { + init(sharedContext: SharedAccountContextImpl, account: Account, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ShareControllerInteraction, recentPeers recentPeerList: [RenderedPeer]) { self.sharedContext = sharedContext self.account = account self.strings = strings diff --git a/submodules/TelegramUI/TelegramUI/SharedAccountContext.swift b/submodules/TelegramUI/TelegramUI/SharedAccountContext.swift index f01eaa905d..642e48f847 100644 --- a/submodules/TelegramUI/TelegramUI/SharedAccountContext.swift +++ b/submodules/TelegramUI/TelegramUI/SharedAccountContext.swift @@ -6,6 +6,7 @@ import Display import TelegramPresentationData import TelegramCallsUI import TelegramUIPreferences +import AccountContext private enum CallStatusText: Equatable { case none @@ -73,7 +74,7 @@ private enum AddedAccountsResult { private var testHasInstance = false -public final class SharedAccountContext { +public final class SharedAccountContextImpl: SharedAccountContext { let mainWindow: Window1? public let applicationBindings: TelegramApplicationBindings public let basePath: String @@ -127,7 +128,10 @@ public final class SharedAccountContext { var switchingData: (settingsController: (SettingsController & ViewController)?, chatListController: ChatListController?, chatListBadge: String?) = (nil, nil, nil) - public let currentPresentationData: Atomic + private let _currentPresentationData: Atomic + public var currentPresentationData: Atomic { + return self._currentPresentationData + } private let _presentationData = Promise() public var presentationData: Signal { return self._presentationData.get() @@ -189,7 +193,7 @@ public final class SharedAccountContext { self.contactDataManager = nil } - self.currentPresentationData = Atomic(value: initialPresentationDataAndSettings.presentationData) + self._currentPresentationData = Atomic(value: initialPresentationDataAndSettings.presentationData) self.currentAutomaticMediaDownloadSettings = Atomic(value: initialPresentationDataAndSettings.automaticMediaDownloadSettings) self.currentMediaInputSettings = Atomic(value: initialPresentationDataAndSettings.mediaInputSettings) self.currentInAppNotificationSettings = Atomic(value: initialPresentationDataAndSettings.inAppNotificationSettings) @@ -283,7 +287,7 @@ public final class SharedAccountContext { let differenceDisposable = MetaDisposable() let _ = (accountManager.accountRecords() |> map { view -> (AccountRecordId?, [AccountRecordId: AccountAttributes], (AccountRecordId, Bool)?) in - print("SharedAccountContext: records appeared in \(CFAbsoluteTimeGetCurrent() - startTime)") + print("SharedAccountContextImpl: records appeared in \(CFAbsoluteTimeGetCurrent() - startTime)") var result: [AccountRecordId: AccountAttributes] = [:] for record in view.records { @@ -401,7 +405,7 @@ public final class SharedAccountContext { differenceDisposable.set((combineLatest(queue: .mainQueue(), mappedAddedAccounts, addedAuthSignal) |> deliverOnMainQueue).start(next: { mappedAddedAccounts, authAccount in - print("SharedAccountContext: accounts processed in \(CFAbsoluteTimeGetCurrent() - startTime)") + print("SharedAccountContextImpl: accounts processed in \(CFAbsoluteTimeGetCurrent() - startTime)") var addedAccounts: [(AccountRecordId, Account?, Int32)] = [] switch mappedAddedAccounts { @@ -632,7 +636,7 @@ public final class SharedAccountContext { } deinit { - assertionFailure("SharedAccountContext is not supposed to be deallocated") + assertionFailure("SharedAccountContextImpl is not supposed to be deallocated") self.registeredNotificationTokensDisposable.dispose() self.presentationDataDisposable.dispose() self.automaticMediaDownloadSettingsDisposable.dispose() @@ -912,4 +916,8 @@ public final class SharedAccountContext { } } } + + public func handleTextLinkAction(context: AccountContext, peerId: PeerId?, navigateDisposable: MetaDisposable, controller: ViewController, action: TextLinkItemActionType, itemLink: TextLinkItem) { + handleTextLinkActionImpl(context: context as! AccountContextImpl, peerId: peerId, navigateDisposable: navigateDisposable, controller: controller, action: action, itemLink: itemLink) + } } diff --git a/submodules/TelegramUI/TelegramUI/SharedNotificationManager.swift b/submodules/TelegramUI/TelegramUI/SharedNotificationManager.swift index e6f2c5506a..a87fbc7318 100644 --- a/submodules/TelegramUI/TelegramUI/SharedNotificationManager.swift +++ b/submodules/TelegramUI/TelegramUI/SharedNotificationManager.swift @@ -460,7 +460,7 @@ public final class SharedNotificationManager { content.title = title } content.body = body - content.sound = UNNotificationSound(named: "0.m4a") + content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "0.m4a")) content.categoryIdentifier = "incomingCall" content.userInfo = [:] diff --git a/submodules/TelegramUI/TelegramUI/SoftwareVideoThumbnailLayer.swift b/submodules/TelegramUI/TelegramUI/SoftwareVideoThumbnailLayer.swift index cd9e2de493..8c0322021c 100644 --- a/submodules/TelegramUI/TelegramUI/SoftwareVideoThumbnailLayer.swift +++ b/submodules/TelegramUI/TelegramUI/SoftwareVideoThumbnailLayer.swift @@ -25,7 +25,7 @@ final class SoftwareVideoThumbnailLayer: CALayer { super.init() self.backgroundColor = UIColor.clear.cgColor - self.contentsGravity = "resizeAspectFill" + self.contentsGravity = .resizeAspectFill self.masksToBounds = true if let dimensions = fileReference.media.dimensions { diff --git a/submodules/TelegramUI/TelegramUI/SolidRoundedButtonNode.swift b/submodules/TelegramUI/TelegramUI/SolidRoundedButtonNode.swift index eceb8094e9..0c5f953a35 100644 --- a/submodules/TelegramUI/TelegramUI/SolidRoundedButtonNode.swift +++ b/submodules/TelegramUI/TelegramUI/SolidRoundedButtonNode.swift @@ -148,7 +148,7 @@ final class SolidRoundedButtonGlossNode : ASDisplayNode { self.displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent)) self.displayLink?.isPaused = true - self.displayLink?.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink?.add(to: RunLoop.main, forMode: .common) self.updateGradientColors() } diff --git a/submodules/TelegramUI/TelegramUI/StickerPackPreviewController.swift b/submodules/TelegramUI/TelegramUI/StickerPackPreviewController.swift index b2715d323c..575d6b7e15 100644 --- a/submodules/TelegramUI/TelegramUI/StickerPackPreviewController.swift +++ b/submodules/TelegramUI/TelegramUI/StickerPackPreviewController.swift @@ -20,7 +20,7 @@ final class StickerPackPreviewController: ViewController { private var animatedIn = false private var dismissed = false - private let context: AccountContext + private let context: AccountContextImpl private let mode: StickerPackPreviewControllerMode private weak var parentNavigationController: NavigationController? @@ -57,7 +57,7 @@ final class StickerPackPreviewController: ViewController { } } - init(context: AccountContext, stickerPack: StickerPackReference, mode: StickerPackPreviewControllerMode = .default, parentNavigationController: NavigationController?) { + init(context: AccountContextImpl, stickerPack: StickerPackReference, mode: StickerPackPreviewControllerMode = .default, parentNavigationController: NavigationController?) { self.context = context self.mode = mode self.parentNavigationController = parentNavigationController diff --git a/submodules/TelegramUI/TelegramUI/StickerPackPreviewControllerNode.swift b/submodules/TelegramUI/TelegramUI/StickerPackPreviewControllerNode.swift index be9605c115..2209c7fad9 100644 --- a/submodules/TelegramUI/TelegramUI/StickerPackPreviewControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/StickerPackPreviewControllerNode.swift @@ -7,6 +7,9 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import MergeLists +import ActivityIndicator +import TextFormat private struct StickerPackPreviewGridEntry: Comparable, Identifiable { let index: Int @@ -40,7 +43,7 @@ private struct StickerPackPreviewGridTransaction { } final class StickerPackPreviewControllerNode: ViewControllerTracingNode, UIScrollViewDelegate { - private let context: AccountContext + private let context: AccountContextImpl private let openShare: (() -> Void)? private var presentationData: PresentationData @@ -82,7 +85,7 @@ final class StickerPackPreviewControllerNode: ViewControllerTracingNode, UIScrol private var hapticFeedback: HapticFeedback? - init(context: AccountContext, openShare: (() -> Void)?, openMention: @escaping (String) -> Void) { + init(context: AccountContextImpl, openShare: (() -> Void)?, openMention: @escaping (String) -> Void) { self.context = context self.openShare = openShare self.presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -168,15 +171,15 @@ final class StickerPackPreviewControllerNode: ViewControllerTracingNode, UIScrol } self.contentTitleNode.highlightAttributeAction = { attributes in - if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] { - return NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention) + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention) } else { return nil } } self.contentTitleNode.tapAttributeAction = { attributes in - if let mention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String, mention.count > 1 { + if let mention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String, mention.count > 1 { openMention(String(mention[mention.index(after: mention.startIndex)...])) } } diff --git a/submodules/TelegramUI/TelegramUI/StickerPaneSearchContentNode.swift b/submodules/TelegramUI/TelegramUI/StickerPaneSearchContentNode.swift index fc0fcd8890..aadb11e0aa 100644 --- a/submodules/TelegramUI/TelegramUI/StickerPaneSearchContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/StickerPaneSearchContentNode.swift @@ -8,6 +8,7 @@ import TelegramCore import TelegramPresentationData import LegacyComponents import TelegramUIPrivateModule +import MergeLists final class StickerPaneSearchInteraction { let open: (StickerPackCollectionInfo) -> Void @@ -135,7 +136,7 @@ private func preparedChatMediaInputGridEntryTransition(account: Account, theme: } final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode { - private let context: AccountContext + private let context: AccountContextImpl private let controllerInteraction: ChatControllerInteraction private let inputNodeInteraction: ChatMediaInputNodeInteraction private var interaction: StickerPaneSearchInteraction? @@ -166,7 +167,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode { var deactivateSearchBar: (() -> Void)? var updateActivity: ((Bool) -> Void)? - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction) { self.context = context self.controllerInteraction = controllerInteraction self.inputNodeInteraction = inputNodeInteraction diff --git a/submodules/TelegramUI/TelegramUI/StickerPreviewController.swift b/submodules/TelegramUI/TelegramUI/StickerPreviewController.swift index 03b0e67b5f..c69016ec52 100644 --- a/submodules/TelegramUI/TelegramUI/StickerPreviewController.swift +++ b/submodules/TelegramUI/TelegramUI/StickerPreviewController.swift @@ -21,10 +21,10 @@ final class StickerPreviewController: ViewController { private var animatedIn = false - private let context: AccountContext + private let context: AccountContextImpl private var item: StickerPackItem - init(context: AccountContext, item: StickerPackItem) { + init(context: AccountContextImpl, item: StickerPackItem) { self.context = context self.item = item diff --git a/submodules/TelegramUI/TelegramUI/StickerPreviewControllerNode.swift b/submodules/TelegramUI/TelegramUI/StickerPreviewControllerNode.swift index d8422acc2a..fb35612860 100644 --- a/submodules/TelegramUI/TelegramUI/StickerPreviewControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/StickerPreviewControllerNode.swift @@ -8,7 +8,7 @@ import TelegramCore import TelegramPresentationData final class StickerPreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { - private let context: AccountContext + private let context: AccountContextImpl private let presentationData: PresentationData private let dimNode: ASDisplayNode @@ -22,7 +22,7 @@ final class StickerPreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { var dismiss: (() -> Void)? var cancel: (() -> Void)? - init(context: AccountContext) { + init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/StickersChatInputContextPanelNode.swift b/submodules/TelegramUI/TelegramUI/StickersChatInputContextPanelNode.swift index 689eb3fff2..e02c48ff4d 100644 --- a/submodules/TelegramUI/TelegramUI/StickersChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/StickersChatInputContextPanelNode.swift @@ -6,25 +6,10 @@ import TelegramCore import Display import SwiftSignalKit import TelegramPresentationData +import MergeLists private struct StickersChatInputContextPanelEntryStableId: Hashable { let ids: [MediaId] - - var hashValue: Int { - var hash: Int = 0 - for i in 0 ..< self.ids.count { - if i == 0 { - hash = self.ids[i].hashValue - } else { - hash = hash &* 31 &+ self.ids[i].hashValue - } - } - return hash - } - - static func ==(lhs: StickersChatInputContextPanelEntryStableId, rhs: StickersChatInputContextPanelEntryStableId) -> Bool { - return lhs.ids == rhs.ids - } } final class StickersChatInputContextPanelInteraction { @@ -92,7 +77,7 @@ final class StickersChatInputContextPanelNode: ChatInputContextPanelNode { private var stickerPreviewController: StickerPreviewController? - override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + override init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.strings = strings self.listView = ListView() diff --git a/submodules/TelegramUI/TelegramUI/StorageUsageController.swift b/submodules/TelegramUI/TelegramUI/StorageUsageController.swift index 6b82984bde..84db54d190 100644 --- a/submodules/TelegramUI/TelegramUI/StorageUsageController.swift +++ b/submodules/TelegramUI/TelegramUI/StorageUsageController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class StorageUsageControllerArguments { let account: Account @@ -264,7 +265,7 @@ private func stringForCategory(strings: PresentationStrings, category: PeerCache } } -func storageUsageController(context: AccountContext, isModal: Bool = false) -> ViewController { +func storageUsageController(context: AccountContextImpl, isModal: Bool = false) -> ViewController { let cacheSettingsPromise = Promise() cacheSettingsPromise.set(context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.cacheStorageSettings]) |> map { sharedData -> CacheStorageSettings in diff --git a/submodules/TelegramUI/TelegramUI/SuppressContactsWarning.swift b/submodules/TelegramUI/TelegramUI/SuppressContactsWarning.swift index 29ad6725c2..29a29fcde2 100644 --- a/submodules/TelegramUI/TelegramUI/SuppressContactsWarning.swift +++ b/submodules/TelegramUI/TelegramUI/SuppressContactsWarning.swift @@ -5,7 +5,7 @@ import SwiftSignalKit import TelegramCore import DeviceAccess -func presentContactsWarningSuppression(context: AccountContext, present: (ViewController, Any?) -> Void) { +func presentContactsWarningSuppression(context: AccountContextImpl, present: (ViewController, Any?) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } present(textAlertController(context: context, title: presentationData.strings.Contacts_PermissionsSuppressWarningTitle, text: presentationData.strings.Contacts_PermissionsSuppressWarningText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Contacts_PermissionsKeepDisabled, action: { ApplicationSpecificNotice.setPermissionWarning(accountManager: context.sharedContext.accountManager, permission: .contacts, value: Int32(Date().timeIntervalSince1970)) diff --git a/submodules/TelegramUI/TelegramUI/SystemVideoContent.swift b/submodules/TelegramUI/TelegramUI/SystemVideoContent.swift index a96d2b6e27..589cf99f61 100644 --- a/submodules/TelegramUI/TelegramUI/SystemVideoContent.swift +++ b/submodules/TelegramUI/TelegramUI/SystemVideoContent.swift @@ -124,7 +124,7 @@ private final class SystemVideoContentNode: ASDisplayNode, UniversalVideoContent self._bufferingStatus.set(.single(nil)) self._status.set(self.statusValue) - self.timeObserver = self.player.addPeriodicTimeObserver(forInterval: CMTimeMake(1, 10), queue: DispatchQueue.main) { [weak self] time in + self.timeObserver = self.player.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 10), queue: DispatchQueue.main) { [weak self] time in guard let strongSelf = self else { return } @@ -253,7 +253,7 @@ private final class SystemVideoContentNode: ASDisplayNode, UniversalVideoContent func seek(_ timestamp: Double) { assert(Queue.mainQueue().isCurrent()) - self.playerItem.seek(to: CMTimeMake(Int64(timestamp) * 1000, 1000)) + self.playerItem.seek(to: CMTimeMake(value: Int64(timestamp) * 1000, timescale: 1000)) } func playOnceWithSound(playAndRecord: Bool, seek: MediaPlayerSeek, actionAtEnd: MediaPlayerPlayOnceWithSoundActionAtEnd) { diff --git a/submodules/TelegramUI/TelegramUI/TabBarAccountSwitchController.swift b/submodules/TelegramUI/TelegramUI/TabBarAccountSwitchController.swift index ab19dc1b29..fa9841d8c7 100644 --- a/submodules/TelegramUI/TelegramUI/TabBarAccountSwitchController.swift +++ b/submodules/TelegramUI/TelegramUI/TabBarAccountSwitchController.swift @@ -17,7 +17,7 @@ public final class TabBarAccountSwitchController: ViewController { return self._ready } - private let sharedContext: SharedAccountContext + private let sharedContext: SharedAccountContextImpl private let accounts: (primary: (Account, Peer), other: [(Account, Peer, Int32)]) private let canAddAccounts: Bool private let switchToAccount: (AccountRecordId) -> Void @@ -30,7 +30,7 @@ public final class TabBarAccountSwitchController: ViewController { private let hapticFeedback = HapticFeedback() - public init(sharedContext: SharedAccountContext, accounts: (primary: (Account, Peer), other: [(Account, Peer, Int32)]), canAddAccounts: Bool, switchToAccount: @escaping (AccountRecordId) -> Void, addAccount: @escaping () -> Void, sourceNodes: [ASDisplayNode]) { + public init(sharedContext: SharedAccountContextImpl, accounts: (primary: (Account, Peer), other: [(Account, Peer, Int32)]), canAddAccounts: Bool, switchToAccount: @escaping (AccountRecordId) -> Void, addAccount: @escaping () -> Void, sourceNodes: [ASDisplayNode]) { self.sharedContext = sharedContext self.accounts = accounts self.canAddAccounts = canAddAccounts diff --git a/submodules/TelegramUI/TelegramUI/TabBarAccountSwitchControllerNode.swift b/submodules/TelegramUI/TelegramUI/TabBarAccountSwitchControllerNode.swift index 92cd7fea67..181d5acd4b 100644 --- a/submodules/TelegramUI/TelegramUI/TabBarAccountSwitchControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/TabBarAccountSwitchControllerNode.swift @@ -223,7 +223,7 @@ final class TabBarAccountSwitchControllerNode: ViewControllerTracingNode { private var validLayout: ContainerViewLayout? - init(sharedContext: SharedAccountContext, accounts: (primary: (Account, Peer), other: [(Account, Peer, Int32)]), presentationData: PresentationData, canAddAccounts: Bool, switchToAccount: @escaping (AccountRecordId) -> Void, addAccount: @escaping () -> Void, cancel: @escaping () -> Void, sourceNodes: [ASDisplayNode]) { + init(sharedContext: SharedAccountContextImpl, accounts: (primary: (Account, Peer), other: [(Account, Peer, Int32)]), presentationData: PresentationData, canAddAccounts: Bool, switchToAccount: @escaping (AccountRecordId) -> Void, addAccount: @escaping () -> Void, cancel: @escaping () -> Void, sourceNodes: [ASDisplayNode]) { self.presentationData = presentationData self.cancel = cancel self.sourceNodes = sourceNodes @@ -372,7 +372,7 @@ final class TabBarAccountSwitchControllerNode: ViewControllerTracingNode { }) if let _ = self.validLayout, let sourceNode = self.sourceNodes.first { let sourceFrame = sourceNode.view.convert(sourceNode.bounds, to: self.view) - self.contentContainerNode.layer.animateFrame(from: self.contentContainerNode.frame, to: sourceFrame, duration: 0.15, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false) + self.contentContainerNode.layer.animateFrame(from: self.contentContainerNode.frame, to: sourceFrame, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, removeOnCompletion: false) } if changedAccount { @@ -433,7 +433,7 @@ final class TabBarAccountSwitchControllerNode: ViewControllerTracingNode { } imageView.image = updatedImage if let previousContents = previousImage?.cgImage, let updatedContents = updatedImage?.cgImage { - imageView.layer.animate(from: previousContents as AnyObject, to: updatedContents as AnyObject, keyPath: "contents", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.15) + imageView.layer.animate(from: previousContents as AnyObject, to: updatedContents as AnyObject, keyPath: "contents", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.15) } imageView.layer.animateSpring(from: 0.6 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.6, completion: { _ in completedSourceNodes = true @@ -450,7 +450,7 @@ final class TabBarAccountSwitchControllerNode: ViewControllerTracingNode { } previousSnapshotViews.forEach { view in - self.view.bringSubview(toFront: view) + self.view.bringSubviewToFront(view) } if !hadBounce { diff --git a/submodules/TelegramUI/TelegramUI/TapLongTapOrDoubleTapGestureRecognizer.swift b/submodules/TelegramUI/TelegramUI/TapLongTapOrDoubleTapGestureRecognizer.swift index 2b48ab1268..616b12b48e 100644 --- a/submodules/TelegramUI/TelegramUI/TapLongTapOrDoubleTapGestureRecognizer.swift +++ b/submodules/TelegramUI/TelegramUI/TapLongTapOrDoubleTapGestureRecognizer.swift @@ -157,14 +157,14 @@ final class TapLongTapOrDoubleTapGestureRecognizer: UIGestureRecognizer, UIGestu self.timer?.invalidate() let timer = Timer(timeInterval: 0.3, target: TapLongTapOrDoubleTapGestureRecognizerTimerTarget(target: self), selector: #selector(TapLongTapOrDoubleTapGestureRecognizerTimerTarget.longTapEvent), userInfo: nil, repeats: false) self.timer = timer - RunLoop.main.add(timer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(timer, forMode: .common) case let .waitForHold(timeout, _): //self.lastRecognizedGestureAndLocation = (.hold, touchLocationAndTimestamp.0) self.hapticFeedback = HapticFeedback() self.hapticFeedback?.prepareTap() let timer = Timer(timeInterval: timeout, target: TapLongTapOrDoubleTapGestureRecognizerTimerTarget(target: self), selector: #selector(TapLongTapOrDoubleTapGestureRecognizerTimerTarget.holdEvent), userInfo: nil, repeats: false) self.timer = timer - RunLoop.main.add(timer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(timer, forMode: .common) case .fail: self.state = .failed } @@ -229,7 +229,7 @@ final class TapLongTapOrDoubleTapGestureRecognizer: UIGestureRecognizer, UIGestu self.state = .began let timer = Timer(timeInterval: 0.2, target: TapLongTapOrDoubleTapGestureRecognizerTimerTarget(target: self), selector: #selector(TapLongTapOrDoubleTapGestureRecognizerTimerTarget.tapEvent), userInfo: nil, repeats: false) self.timer = timer - RunLoop.main.add(timer, forMode: RunLoopMode.commonModes) + RunLoop.main.add(timer, forMode: .common) case let .waitForHold(_, acceptTap): if let (touchLocation, _) = self.touchLocationAndTimestamp, acceptTap { if self.state != .began { diff --git a/submodules/TelegramUI/TelegramUI/TelegramController.swift b/submodules/TelegramUI/TelegramUI/TelegramController.swift index 52f845c2a1..c76842d72c 100644 --- a/submodules/TelegramUI/TelegramUI/TelegramController.swift +++ b/submodules/TelegramUI/TelegramUI/TelegramController.swift @@ -21,7 +21,7 @@ enum LocationBroadcastPanelSource { case peer(PeerId) } -private func presentLiveLocationController(context: AccountContext, peerId: PeerId, controller: ViewController) { +private func presentLiveLocationController(context: AccountContextImpl, peerId: PeerId, controller: ViewController) { let presentImpl: (Message?) -> Void = { [weak controller] message in if let message = message, let strongController = controller { let _ = openChatMessage(context: context, message: message, standalone: false, reverseMessageGalleryOrder: false, navigationController: strongController.navigationController as? NavigationController, modal: true, dismissInput: { @@ -52,7 +52,7 @@ private func presentLiveLocationController(context: AccountContext, peerId: Peer } public class TelegramController: ViewController, KeyShortcutResponder { - private let context: AccountContext + private let context: AccountContextImpl let mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility let locationBroadcastPanelSource: LocationBroadcastPanelSource @@ -105,7 +105,7 @@ public class TelegramController: ViewController, KeyShortcutResponder { return super.navigationHeight } - init(context: AccountContext, navigationBarPresentationData: NavigationBarPresentationData?, mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility, locationBroadcastPanelSource: LocationBroadcastPanelSource) { + init(context: AccountContextImpl, navigationBarPresentationData: NavigationBarPresentationData?, mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility, locationBroadcastPanelSource: LocationBroadcastPanelSource) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.mediaAccessoryPanelVisibility = mediaAccessoryPanelVisibility @@ -598,7 +598,7 @@ public class TelegramController: ViewController, KeyShortcutResponder { return } if let _ = index.0 { - let controller = OverlayPlayerController(context: account.id == strongSelf.context.account.id ? strongSelf.context : AccountContext(sharedContext: strongSelf.context.sharedContext, account: account, limitsConfiguration: .defaultValue), peerId: id.messageId.peerId, type: type, initialMessageId: id.messageId, initialOrder: order, parentNavigationController: strongSelf.navigationController as? NavigationController) + let controller = OverlayPlayerController(context: account.id == strongSelf.context.account.id ? strongSelf.context : AccountContextImpl(sharedContext: strongSelf.context.sharedContext, account: account, limitsConfiguration: .defaultValue), peerId: id.messageId.peerId, type: type, initialMessageId: id.messageId, initialOrder: order, parentNavigationController: strongSelf.navigationController as? NavigationController) strongSelf.displayNode.view.window?.endEditing(true) strongSelf.present(controller, in: .window(.root)) } else if index.1 { @@ -658,7 +658,7 @@ public class TelegramController: ViewController, KeyShortcutResponder { } public var keyShortcuts: [KeyShortcut] { - return [KeyShortcut(input: UIKeyInputEscape, action: { [weak self] in + return [KeyShortcut(input: UIKeyCommand.inputEscape, action: { [weak self] in if !(self?.navigationController?.topViewController is TabBarController) { _ = self?.navigationBar?.executeBack() } diff --git a/submodules/TelegramUI/TelegramUI/TelegramInitializeLegacyComponents.swift b/submodules/TelegramUI/TelegramUI/TelegramInitializeLegacyComponents.swift index 8db76d63bc..d80a0dc54f 100644 --- a/submodules/TelegramUI/TelegramUI/TelegramInitializeLegacyComponents.swift +++ b/submodules/TelegramUI/TelegramUI/TelegramInitializeLegacyComponents.swift @@ -28,16 +28,16 @@ func updateLegacyTheme() { private var legacyDocumentsStorePath: String? private var legacyCanOpenUrl: (URL) -> Bool = { _ in return false } private var legacyOpenUrl: (URL) -> Void = { _ in } -private weak var legacyContext: AccountContext? +private weak var legacyContext: AccountContextImpl? -func legacyContextGet() -> AccountContext? { +func legacyContextGet() -> AccountContextImpl? { return legacyContext } private final class LegacyComponentsAccessCheckerImpl: NSObject, LegacyComponentsAccessChecker { - private weak var context: AccountContext? + private weak var context: AccountContextImpl? - init(context: AccountContext?) { + init(context: AccountContextImpl?) { self.context = context } @@ -357,7 +357,7 @@ private final class LegacyComponentsGlobalsProviderImpl: NSObject, LegacyCompone } } -public func setupLegacyComponents(context: AccountContext) { +public func setupLegacyComponents(context: AccountContextImpl) { legacyContext = context } diff --git a/submodules/TelegramUI/TelegramUI/TelegramRootController.swift b/submodules/TelegramUI/TelegramUI/TelegramRootController.swift index 52d0cb1b3f..fb17fbe56c 100644 --- a/submodules/TelegramUI/TelegramUI/TelegramRootController.swift +++ b/submodules/TelegramUI/TelegramUI/TelegramRootController.swift @@ -8,7 +8,7 @@ import TelegramPresentationData import TelegramUIPrivateModule public final class TelegramRootController: NavigationController { - private let context: AccountContext + private let context: AccountContextImpl public var rootTabController: TabBarController? @@ -21,7 +21,7 @@ public final class TelegramRootController: NavigationController { private var presentationDataDisposable: Disposable? private var presentationData: PresentationData - public init(context: AccountContext) { + public init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/TermsOfServiceController.swift b/submodules/TelegramUI/TelegramUI/TermsOfServiceController.swift index d8785fffac..a2136d2325 100644 --- a/submodules/TelegramUI/TelegramUI/TermsOfServiceController.swift +++ b/submodules/TelegramUI/TelegramUI/TermsOfServiceController.swift @@ -7,6 +7,7 @@ import Display import AsyncDisplayKit import TelegramPresentationData import TelegramUIPreferences +import ProgressNavigationButtonNode public class TermsOfServiceControllerTheme { public let statusBarStyle: StatusBarStyle diff --git a/submodules/TelegramUI/TelegramUI/TermsOfServiceControllerNode.swift b/submodules/TelegramUI/TelegramUI/TermsOfServiceControllerNode.swift index 674458c03c..f1fd8520b8 100644 --- a/submodules/TelegramUI/TelegramUI/TermsOfServiceControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/TermsOfServiceControllerNode.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import Display import AsyncDisplayKit import TelegramPresentationData +import TextFormat final class TermsOfServiceControllerNode: ViewControllerTracingNode { private let theme: TermsOfServiceControllerTheme @@ -119,12 +120,12 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode { self.contentTextNode.linkHighlightColor = self.theme.accent.withAlphaComponent(0.5) self.contentTextNode.highlightAttributeAction = { attributes in - if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] { - return NSAttributedStringKey(rawValue: TelegramTextAttributes.URL) - } else if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] { - return NSAttributedStringKey(rawValue: TelegramTextAttributes.URL) - } else if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] { - return NSAttributedStringKey(rawValue: TelegramTextAttributes.URL) + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) + } else if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) + } else if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) } else { return nil } @@ -153,11 +154,11 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode { guard let strongSelf = self else { return } - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { strongSelf.openUrl(url) - } else if let mention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { + } else if let mention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { showMentionActionSheet(mention.mention) - } else if let mention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let mention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { showMentionActionSheet(mention) } } @@ -165,7 +166,7 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode { guard let strongSelf = self else { return } - if let url = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String { + if let url = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { let theme: PresentationTheme = strongSelf.theme.presentationTheme let actionSheet = ActionSheetController(presentationTheme: theme) actionSheet.setItemGroups([ActionSheetItemGroup(items: [ @@ -184,9 +185,9 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode { }) ])]) strongSelf.present(actionSheet, nil) - } else if let mention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { + } else if let mention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerMention)] as? TelegramPeerMention { showMentionActionSheet(mention.mention) - } else if let mention = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { + } else if let mention = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.PeerTextMention)] as? String { showMentionActionSheet(mention) } } @@ -241,7 +242,7 @@ final class TermsOfServiceControllerNode: ViewControllerTracingNode { } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/TextLinkHandling.swift b/submodules/TelegramUI/TelegramUI/TextLinkHandling.swift index 9cf383f43d..92812ef007 100644 --- a/submodules/TelegramUI/TelegramUI/TextLinkHandling.swift +++ b/submodules/TelegramUI/TelegramUI/TextLinkHandling.swift @@ -5,10 +5,11 @@ import Postbox import Display import SwiftSignalKit import TelegramUIPreferences +import AccountContext import SafariServices -func handleTextLinkAction(context: AccountContext, peerId: PeerId?, navigateDisposable: MetaDisposable, controller: ViewController, action: TextLinkItemActionType, itemLink: TextLinkItem) { +func handleTextLinkActionImpl(context: AccountContextImpl, peerId: PeerId?, navigateDisposable: MetaDisposable, controller: ViewController, action: TextLinkItemActionType, itemLink: TextLinkItem) { let presentImpl: (ViewController, Any?) -> Void = { controllerToPresent, _ in controller.present(controllerToPresent, in: .window(.root)) } diff --git a/submodules/TelegramUI/TelegramUI/TextNode.swift b/submodules/TelegramUI/TelegramUI/TextNode.swift index de69f8ef66..211fc1be84 100644 --- a/submodules/TelegramUI/TelegramUI/TextNode.swift +++ b/submodules/TelegramUI/TelegramUI/TextNode.swift @@ -4,42 +4,3 @@ import AsyncDisplayKit import Display import Postbox -final class TelegramHashtag { - let peerName: String? - let hashtag: String - - init(peerName: String?, hashtag: String) { - self.peerName = peerName - self.hashtag = hashtag - } -} - -final class TelegramPeerMention { - let peerId: PeerId - let mention: String - - init(peerId: PeerId, mention: String) { - self.peerId = peerId - self.mention = mention - } -} - -final class TelegramTimecode { - let time: Double - let text: String - - init(time: Double, text: String) { - self.time = time - self.text = text - } -} - -struct TelegramTextAttributes { - static let URL = "UrlAttributeT" - static let PeerMention = "TelegramPeerMention" - static let PeerTextMention = "TelegramPeerTextMention" - static let BotCommand = "TelegramBotCommand" - static let Hashtag = "TelegramHashtag" - static let Timecode = "TelegramTimecode" - static let BlockQuote = "TelegramBlockQuote" -} diff --git a/submodules/TelegramUI/TelegramUI/ThemeAccentColorActionSheet.swift b/submodules/TelegramUI/TelegramUI/ThemeAccentColorActionSheet.swift index 3800bb1fc8..57483e218b 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeAccentColorActionSheet.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeAccentColorActionSheet.swift @@ -15,7 +15,7 @@ final class ThemeAccentColorActionSheet: ActionSheetController { return self._ready } - init(context: AccountContext, currentValue: Int32, applyValue: @escaping (Int32) -> Void) { + init(context: AccountContextImpl, currentValue: Int32, applyValue: @escaping (Int32) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/ThemeAutoNightSettingsController.swift b/submodules/TelegramUI/TelegramUI/ThemeAutoNightSettingsController.swift index abddfbde77..2e3b77858c 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeAutoNightSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeAutoNightSettingsController.swift @@ -7,6 +7,7 @@ import TelegramCore import TelegramPresentationData import TelegramUIPreferences import TelegramUIPrivateModule +import ItemListUI private enum TriggerMode { case none @@ -327,7 +328,7 @@ private func areSettingsValid(_ settings: AutomaticThemeSwitchSetting) -> Bool { } } -public func themeAutoNightSettingsController(context: AccountContext) -> ViewController { +public func themeAutoNightSettingsController(context: AccountContextImpl) -> ViewController { var presentControllerImpl: ((ViewController) -> Void)? let actionsDisposable = DisposableSet() diff --git a/submodules/TelegramUI/TelegramUI/ThemeAutoNightTimeSelectionActionSheet.swift b/submodules/TelegramUI/TelegramUI/ThemeAutoNightTimeSelectionActionSheet.swift index 569c08ac29..7310b8825a 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeAutoNightTimeSelectionActionSheet.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeAutoNightTimeSelectionActionSheet.swift @@ -14,7 +14,7 @@ final class ThemeAutoNightTimeSelectionActionSheet: ActionSheetController { return self._ready } - init(context: AccountContext, currentValue: Int32, emptyTitle: String? = nil, applyValue: @escaping (Int32?) -> Void) { + init(context: AccountContextImpl, currentValue: Int32, emptyTitle: String? = nil, applyValue: @escaping (Int32?) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = presentationData.theme let strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/ThemeColorsGridController.swift b/submodules/TelegramUI/TelegramUI/ThemeColorsGridController.swift index ea57a366a4..2ba308f52b 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeColorsGridController.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeColorsGridController.swift @@ -61,14 +61,14 @@ final class ThemeColorsGridController: ViewController { return self._ready } - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private var presentationDataDisposable: Disposable? private var validLayout: ContainerViewLayout? - init(context: AccountContext) { + init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/TelegramUI/ThemeColorsGridControllerItem.swift b/submodules/TelegramUI/TelegramUI/ThemeColorsGridControllerItem.swift index 1c42e3435f..b670d0b6e9 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeColorsGridControllerItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeColorsGridControllerItem.swift @@ -7,14 +7,14 @@ import AsyncDisplayKit import Postbox final class ThemeColorsGridControllerItem: GridItem { - let context: AccountContext + let context: AccountContextImpl let wallpaper: TelegramWallpaper let selected: Bool let interaction: ThemeColorsGridControllerInteraction let section: GridSection? = nil - init(context: AccountContext, wallpaper: TelegramWallpaper, selected: Bool, interaction: ThemeColorsGridControllerInteraction) { + init(context: AccountContextImpl, wallpaper: TelegramWallpaper, selected: Bool, interaction: ThemeColorsGridControllerInteraction) { self.context = context self.wallpaper = wallpaper self.selected = selected @@ -40,7 +40,7 @@ final class ThemeColorsGridControllerItemNode: GridItemNode { private let wallpaperNode: SettingsThemeWallpaperNode private var selectionNode: GridMessageSelectionNode? - private var currentState: (AccountContext, TelegramWallpaper, Bool)? + private var currentState: (AccountContextImpl, TelegramWallpaper, Bool)? private var interaction: ThemeColorsGridControllerInteraction? override init() { @@ -57,7 +57,7 @@ final class ThemeColorsGridControllerItemNode: GridItemNode { self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) } - func setup(context: AccountContext, wallpaper: TelegramWallpaper, selected: Bool, interaction: ThemeColorsGridControllerInteraction) { + func setup(context: AccountContextImpl, wallpaper: TelegramWallpaper, selected: Bool, interaction: ThemeColorsGridControllerInteraction) { self.interaction = interaction if self.currentState == nil || self.currentState!.0 !== context || wallpaper != self.currentState!.1 || selected != self.currentState!.2 { diff --git a/submodules/TelegramUI/TelegramUI/ThemeColorsGridControllerNode.swift b/submodules/TelegramUI/TelegramUI/ThemeColorsGridControllerNode.swift index 1c79c0e6a0..a67f997bd7 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeColorsGridControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeColorsGridControllerNode.swift @@ -6,6 +6,8 @@ import Postbox import TelegramCore import SwiftSignalKit import TelegramPresentationData +import MergeLists +import ItemListUI final class ThemeColorsGridControllerInteraction { let openWallpaper: (TelegramWallpaper) -> Void @@ -32,7 +34,7 @@ private struct ThemeColorsGridControllerEntry: Comparable, Identifiable { return self.index } - func item(context: AccountContext, interaction: ThemeColorsGridControllerInteraction) -> ThemeColorsGridControllerItem { + func item(context: AccountContextImpl, interaction: ThemeColorsGridControllerInteraction) -> ThemeColorsGridControllerItem { return ThemeColorsGridControllerItem(context: context, wallpaper: self.wallpaper, selected: self.selected, interaction: interaction) } } @@ -46,7 +48,7 @@ private struct ThemeColorsGridEntryTransition { let scrollToItem: GridNodeScrollToItem? } -private func preparedThemeColorsGridEntryTransition(context: AccountContext, from fromEntries: [ThemeColorsGridControllerEntry], to toEntries: [ThemeColorsGridControllerEntry], interaction: ThemeColorsGridControllerInteraction) -> ThemeColorsGridEntryTransition { +private func preparedThemeColorsGridEntryTransition(context: AccountContextImpl, from fromEntries: [ThemeColorsGridControllerEntry], to toEntries: [ThemeColorsGridControllerEntry], interaction: ThemeColorsGridControllerInteraction) -> ThemeColorsGridEntryTransition { let stationaryItems: GridNodeStationaryItems = .none let scrollToItem: GridNodeScrollToItem? = nil @@ -60,7 +62,7 @@ private func preparedThemeColorsGridEntryTransition(context: AccountContext, fro } final class ThemeColorsGridControllerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private var controllerInteraction: ThemeColorsGridControllerInteraction? private let present: (ViewController, Any?) -> Void @@ -81,7 +83,7 @@ final class ThemeColorsGridControllerNode: ASDisplayNode { private var disposable: Disposable? - init(context: AccountContext, presentationData: PresentationData, colors: [Int32], present: @escaping (ViewController, Any?) -> Void, pop: @escaping () -> Void, presentColorPicker: @escaping () -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, colors: [Int32], present: @escaping (ViewController, Any?) -> Void, pop: @escaping () -> Void, presentColorPicker: @escaping () -> Void) { self.context = context self.presentationData = presentationData self.present = present diff --git a/submodules/TelegramUI/TelegramUI/ThemeGridController.swift b/submodules/TelegramUI/TelegramUI/ThemeGridController.swift index d1b50721f2..993fd6cca5 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeGridController.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeGridController.swift @@ -19,7 +19,7 @@ final class ThemeGridController: ViewController { return self._ready } - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private let presentationDataPromise = Promise() @@ -36,7 +36,7 @@ final class ThemeGridController: ViewController { return false } - init(context: AccountContext) { + init(context: AccountContextImpl) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.presentationDataPromise.set(.single(self.presentationData)) diff --git a/submodules/TelegramUI/TelegramUI/ThemeGridControllerItem.swift b/submodules/TelegramUI/TelegramUI/ThemeGridControllerItem.swift index 03fd2a80ec..8aef96b721 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeGridControllerItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeGridControllerItem.swift @@ -7,7 +7,7 @@ import AsyncDisplayKit import Postbox final class ThemeGridControllerItem: GridItem { - let context: AccountContext + let context: AccountContextImpl let wallpaper: TelegramWallpaper let index: Int let selected: Bool @@ -15,7 +15,7 @@ final class ThemeGridControllerItem: GridItem { let section: GridSection? = nil - init(context: AccountContext, wallpaper: TelegramWallpaper, index: Int, selected: Bool, interaction: ThemeGridControllerInteraction) { + init(context: AccountContextImpl, wallpaper: TelegramWallpaper, index: Int, selected: Bool, interaction: ThemeGridControllerInteraction) { self.context = context self.wallpaper = wallpaper self.index = index @@ -42,7 +42,7 @@ final class ThemeGridControllerItemNode: GridItemNode { private let wallpaperNode: SettingsThemeWallpaperNode private var selectionNode: GridMessageSelectionNode? - private var currentState: (AccountContext, TelegramWallpaper, Bool, Bool)? + private var currentState: (AccountContextImpl, TelegramWallpaper, Bool, Bool)? private var interaction: ThemeGridControllerInteraction? override init() { @@ -59,7 +59,7 @@ final class ThemeGridControllerItemNode: GridItemNode { self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) } - func setup(context: AccountContext, wallpaper: TelegramWallpaper, selected: Bool, interaction: ThemeGridControllerInteraction, synchronousLoad: Bool) { + func setup(context: AccountContextImpl, wallpaper: TelegramWallpaper, selected: Bool, interaction: ThemeGridControllerInteraction, synchronousLoad: Bool) { self.interaction = interaction if self.currentState == nil || self.currentState!.0 !== context || wallpaper != self.currentState!.1 || selected != self.currentState!.2 || synchronousLoad != self.currentState!.3 { diff --git a/submodules/TelegramUI/TelegramUI/ThemeGridControllerNode.swift b/submodules/TelegramUI/TelegramUI/ThemeGridControllerNode.swift index 583c1300d9..3a1e4153ea 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeGridControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeGridControllerNode.swift @@ -8,6 +8,8 @@ import SwiftSignalKit import UniversalMediaPlayer import TelegramPresentationData import TelegramUIPreferences +import MergeLists +import ItemListUI private func areWallpapersEqual(_ lhs: TelegramWallpaper, _ rhs: TelegramWallpaper) -> Bool { switch lhs { @@ -109,7 +111,7 @@ private struct ThemeGridControllerEntry: Comparable, Identifiable { } } - func item(context: AccountContext, interaction: ThemeGridControllerInteraction) -> ThemeGridControllerItem { + func item(context: AccountContextImpl, interaction: ThemeGridControllerInteraction) -> ThemeGridControllerItem { return ThemeGridControllerItem(context: context, wallpaper: self.wallpaper, index: self.index, selected: self.selected, interaction: interaction) } } @@ -125,7 +127,7 @@ private struct ThemeGridEntryTransition { let synchronousLoad: Bool } -private func preparedThemeGridEntryTransition(context: AccountContext, from fromEntries: [ThemeGridControllerEntry], to toEntries: [ThemeGridControllerEntry], interaction: ThemeGridControllerInteraction) -> ThemeGridEntryTransition { +private func preparedThemeGridEntryTransition(context: AccountContextImpl, from fromEntries: [ThemeGridControllerEntry], to toEntries: [ThemeGridControllerEntry], interaction: ThemeGridControllerInteraction) -> ThemeGridEntryTransition { let stationaryItems: GridNodeStationaryItems = .none let scrollToItem: GridNodeScrollToItem? = nil @@ -176,7 +178,7 @@ private func selectedWallpapers(entries: [ThemeGridControllerEntry]?, state: The } final class ThemeGridControllerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private var controllerInteraction: ThemeGridControllerInteraction? @@ -227,7 +229,7 @@ final class ThemeGridControllerNode: ASDisplayNode { private var disposable: Disposable? - init(context: AccountContext, presentationData: PresentationData, presentPreviewController: @escaping (WallpaperListSource) -> Void, presentGallery: @escaping () -> Void, presentColors: @escaping () -> Void, emptyStateUpdated: @escaping (Bool) -> Void, deleteWallpapers: @escaping ([TelegramWallpaper], @escaping () -> Void) -> Void, shareWallpapers: @escaping ([TelegramWallpaper]) -> Void, resetWallpapers: @escaping () -> Void, popViewController: @escaping () -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, presentPreviewController: @escaping (WallpaperListSource) -> Void, presentGallery: @escaping () -> Void, presentColors: @escaping () -> Void, emptyStateUpdated: @escaping (Bool) -> Void, deleteWallpapers: @escaping ([TelegramWallpaper], @escaping () -> Void) -> Void, shareWallpapers: @escaping ([TelegramWallpaper]) -> Void, resetWallpapers: @escaping () -> Void, popViewController: @escaping () -> Void) { self.context = context self.presentationData = presentationData self.presentPreviewController = presentPreviewController diff --git a/submodules/TelegramUI/TelegramUI/ThemeGridSearchContentNode.swift b/submodules/TelegramUI/TelegramUI/ThemeGridSearchContentNode.swift index a5d4d206cf..cf88f27634 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeGridSearchContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeGridSearchContentNode.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import MergeLists enum WallpaperSearchColor: CaseIterable { case blue @@ -308,7 +309,7 @@ private struct ThemeGridSearchContext { } final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode { - private let context: AccountContext + private let context: AccountContextImpl private let recentListNode: ListView private let gridNode: GridNode @@ -336,7 +337,7 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode { return self._isSearching.get() } - init(context: AccountContext, openResult: @escaping (ChatContextResult) -> Void) { + init(context: AccountContextImpl, openResult: @escaping (ChatContextResult) -> Void) { self.context = context self.queryPromise = Promise(self.queryValue) diff --git a/submodules/TelegramUI/TelegramUI/ThemePreviewController.swift b/submodules/TelegramUI/TelegramUI/ThemePreviewController.swift index 1d348832d5..2f89847ab6 100644 --- a/submodules/TelegramUI/TelegramUI/ThemePreviewController.swift +++ b/submodules/TelegramUI/TelegramUI/ThemePreviewController.swift @@ -9,7 +9,7 @@ import TelegramPresentationData import TelegramUIPreferences final class ThemePreviewController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private let previewTheme: PresentationTheme private let media: AnyMediaReference @@ -22,7 +22,7 @@ final class ThemePreviewController: ViewController { private var presentationData: PresentationData private var presentationDataDisposable: Disposable? - init(context: AccountContext, previewTheme: PresentationTheme, media: AnyMediaReference) { + init(context: AccountContextImpl, previewTheme: PresentationTheme, media: AnyMediaReference) { self.context = context self.previewTheme = previewTheme self.media = media diff --git a/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift b/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift index 83c7c2881c..bd134dca16 100644 --- a/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ThemePreviewControllerNode.swift @@ -9,7 +9,7 @@ import TelegramPresentationData import TelegramUIPreferences class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { - private let context: AccountContext + private let context: AccountContextImpl private let previewTheme: PresentationTheme private var presentationData: PresentationData @@ -29,7 +29,7 @@ class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { private var colorDisposable: Disposable? - init(context: AccountContext, previewTheme: PresentationTheme, dismiss: @escaping () -> Void, apply: @escaping () -> Void) { + init(context: AccountContextImpl, previewTheme: PresentationTheme, dismiss: @escaping () -> Void, apply: @escaping () -> Void) { self.context = context self.previewTheme = previewTheme @@ -116,7 +116,7 @@ class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsAccentColorItem.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsAccentColorItem.swift index 17d2bac6d6..b69963356c 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsAccentColorItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsAccentColorItem.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private func generateSwatchImage(color: PresentationThemeAccentColor, selected: Bool) -> UIImage? { return generateImage(CGSize(width: 40.0, height: 40.0), rotatedContext: { size, context in @@ -205,7 +206,7 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode { strongSelf.item = item strongSelf.layoutParams = params - strongSelf.scrollNode.view.contentInset = UIEdgeInsetsMake(0.0, params.leftInset, 0.0, params.rightInset) + strongSelf.scrollNode.view.contentInset = UIEdgeInsets(top: 0.0, left: params.leftInset, bottom: 0.0, right: params.rightInset) strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsAppIconItem.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsAppIconItem.swift index e74272695e..dbd03cc362 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsAppIconItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsAppIconItem.swift @@ -5,6 +5,7 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ItemListUI private func generateBorderImage(theme: PresentationTheme, bordered: Bool, selected: Bool) -> UIImage? { return generateImage(CGSize(width: 30.0, height: 30.0), rotatedContext: { size, context in @@ -218,7 +219,7 @@ class ThemeSettingsAppIconItemNode: ListViewItemNode, ItemListItemNode { strongSelf.item = item strongSelf.layoutParams = params - strongSelf.scrollNode.view.contentInset = UIEdgeInsetsMake(0.0, params.leftInset, 0.0, params.rightInset) + strongSelf.scrollNode.view.contentInset = UIEdgeInsets(top: 0.0, left: params.leftInset, bottom: 0.0, right: params.rightInset) strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsBrightnessItem.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsBrightnessItem.swift index 2f13c1052f..185e9551e8 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsBrightnessItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsBrightnessItem.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import TelegramCore import TelegramPresentationData import LegacyComponents +import ItemListUI class ThemeSettingsBrightnessItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift index 7026fd07d7..2158476426 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsChatPreviewItem.swift @@ -7,9 +7,10 @@ import TelegramCore import Postbox import TelegramPresentationData import TelegramUIPreferences +import ItemListUI class ThemeSettingsChatPreviewItem: ListViewItem, ItemListItem { - let context: AccountContext + let context: AccountContextImpl let theme: PresentationTheme let componentTheme: PresentationTheme let strings: PresentationStrings @@ -19,7 +20,7 @@ class ThemeSettingsChatPreviewItem: ListViewItem, ItemListItem { let dateTimeFormat: PresentationDateTimeFormat let nameDisplayOrder: PresentationPersonNameOrder - init(context: AccountContext, theme: PresentationTheme, componentTheme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, fontSize: PresentationFontSize, wallpaper: TelegramWallpaper, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder) { + init(context: AccountContextImpl, theme: PresentationTheme, componentTheme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, fontSize: PresentationFontSize, wallpaper: TelegramWallpaper, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder) { self.context = context self.theme = theme self.componentTheme = componentTheme diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsColorSliderNode.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsColorSliderNode.swift index 3cbee0c775..ce12256539 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsColorSliderNode.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsColorSliderNode.swift @@ -161,7 +161,7 @@ final class ThemeSettingsColorSliderNode: ASDisplayNode { override init() { self.brightnessNode = ThemeSettingsColorBrightnessNode() - self.brightnessNode.hitTestSlop = UIEdgeInsetsMake(-16.0, -16.0, -16.0, -16.0) + self.brightnessNode.hitTestSlop = UIEdgeInsets(top: -16.0, left: -16.0, bottom: -16.0, right: -16.0) self.brightnessKnobNode = ThemeSettingsColorKnobNode() super.init() diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift index a962138eea..e6aa815880 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift @@ -6,9 +6,10 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class ThemeSettingsControllerArguments { - let context: AccountContext + let context: AccountContextImpl let selectTheme: (PresentationThemeReference) -> Void let selectFontSize: (PresentationFontSize) -> Void let openWallpaperSettings: () -> Void @@ -19,7 +20,7 @@ private final class ThemeSettingsControllerArguments { let disableAnimations: (Bool) -> Void let selectAppIcon: (String) -> Void - init(context: AccountContext, selectTheme: @escaping (PresentationThemeReference) -> Void, selectFontSize: @escaping (PresentationFontSize) -> Void, openWallpaperSettings: @escaping () -> Void, selectAccentColor: @escaping (PresentationThemeAccentColor) -> Void, toggleColorSlider: @escaping (Bool) -> Void, openAutoNightTheme: @escaping () -> Void, toggleLargeEmoji: @escaping (Bool) -> Void, disableAnimations: @escaping (Bool) -> Void, selectAppIcon: @escaping (String) -> Void) { + init(context: AccountContextImpl, selectTheme: @escaping (PresentationThemeReference) -> Void, selectFontSize: @escaping (PresentationFontSize) -> Void, openWallpaperSettings: @escaping () -> Void, selectAccentColor: @escaping (PresentationThemeAccentColor) -> Void, toggleColorSlider: @escaping (Bool) -> Void, openAutoNightTheme: @escaping () -> Void, toggleLargeEmoji: @escaping (Bool) -> Void, disableAnimations: @escaping (Bool) -> Void, selectAppIcon: @escaping (String) -> Void) { self.context = context self.selectTheme = selectTheme self.selectFontSize = selectFontSize @@ -50,7 +51,7 @@ public enum ThemeSettingsEntryTag: ItemListItemTag { case largeEmoji case animations - func isEqual(to other: ItemListItemTag) -> Bool { + public func isEqual(to other: ItemListItemTag) -> Bool { if let other = other as? ThemeSettingsEntryTag, self == other { return true } else { @@ -340,7 +341,7 @@ private func themeSettingsControllerEntries(presentationData: PresentationData, return entries } -public func themeSettingsController(context: AccountContext, focusOnItemTag: ThemeSettingsEntryTag? = nil) -> ViewController { +public func themeSettingsController(context: AccountContextImpl, focusOnItemTag: ThemeSettingsEntryTag? = nil) -> ViewController { let initialState = ThemeSettingsState(displayColorSlider: false) let statePromise = ValuePromise(initialState, ignoreRepeated: true) let stateValue = Atomic(value: initialState) diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsFontSizeItem.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsFontSizeItem.swift index 8410f5b3ec..ae4ed1c593 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsFontSizeItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsFontSizeItem.swift @@ -7,6 +7,7 @@ import TelegramCore import TelegramPresentationData import TelegramUIPreferences import LegacyComponents +import ItemListUI class ThemeSettingsFontSizeItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsThemeItem.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsThemeItem.swift index 4f92609134..cd8aaea70f 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsThemeItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsThemeItem.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private func generateBorderImage(theme: PresentationTheme, bordered: Bool, selected: Bool) -> UIImage? { return generateImage(CGSize(width: 30.0, height: 30.0), rotatedContext: { size, context in @@ -289,7 +290,7 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode { strongSelf.item = item strongSelf.layoutParams = params - strongSelf.scrollNode.view.contentInset = UIEdgeInsetsMake(0.0, params.leftInset, 0.0, params.rightInset) + strongSelf.scrollNode.view.contentInset = UIEdgeInsets(top: 0.0, left: params.leftInset, bottom: 0.0, right: params.rightInset) strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor diff --git a/submodules/TelegramUI/TelegramUI/ThemedTextAlertController.swift b/submodules/TelegramUI/TelegramUI/ThemedTextAlertController.swift index f460394012..4559cc8231 100644 --- a/submodules/TelegramUI/TelegramUI/ThemedTextAlertController.swift +++ b/submodules/TelegramUI/TelegramUI/ThemedTextAlertController.swift @@ -3,7 +3,7 @@ import UIKit import Display import TelegramCore -public func textAlertController(context: AccountContext, title: String?, text: String, actions: [TextAlertAction], actionLayout: TextAlertContentActionLayout = .horizontal) -> AlertController { +public func textAlertController(context: AccountContextImpl, title: String?, text: String, actions: [TextAlertAction], actionLayout: TextAlertContentActionLayout = .horizontal) -> AlertController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let controller = standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: title, text: text, actions: actions) @@ -17,7 +17,7 @@ public func textAlertController(context: AccountContext, title: String?, text: S return controller } -public func richTextAlertController(context: AccountContext, title: NSAttributedString?, text: NSAttributedString, actions: [TextAlertAction], actionLayout: TextAlertContentActionLayout = .horizontal) -> AlertController { +public func richTextAlertController(context: AccountContextImpl, title: NSAttributedString?, text: NSAttributedString, actions: [TextAlertAction], actionLayout: TextAlertContentActionLayout = .horizontal) -> AlertController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let theme = AlertControllerTheme(presentationTheme: presentationData.theme) diff --git a/submodules/TelegramUI/TelegramUI/TransformOutgoingMessageMedia.swift b/submodules/TelegramUI/TelegramUI/TransformOutgoingMessageMedia.swift index 9322cca278..6ad2db7fe3 100644 --- a/submodules/TelegramUI/TelegramUI/TransformOutgoingMessageMedia.swift +++ b/submodules/TelegramUI/TelegramUI/TransformOutgoingMessageMedia.swift @@ -46,7 +46,7 @@ public func transformOutgoingMessageMedia(postbox: Postbox, network: Network, me if let scaledImage = generateImage(image.size.fitted(CGSize(width: 320.0, height: 320.0)), contextGenerator: { size, context in context.setBlendMode(.copy) drawImage(context: context, image: image.cgImage!, orientation: image.imageOrientation, in: CGRect(origin: CGPoint(), size: size)) - }, scale: 1.0), let thumbnailData = UIImageJPEGRepresentation(scaledImage, 0.6) { + }, scale: 1.0), let thumbnailData = scaledImage.jpegData(compressionQuality: 0.6) { /*if #available(iOSApplicationExtension 11.0, iOS 11.0, *) { #if DEBUG if true, let heicData = compressImage(scaledImage, quality: 0.7) { @@ -95,7 +95,7 @@ public func transformOutgoingMessageMedia(postbox: Postbox, network: Network, me } |> runOn(opportunistic ? Queue.mainQueue() : Queue.concurrentDefaultQueue()) } else if file.mimeType.hasPrefix("video/") { return Signal { subscriber in - if let scaledImage = generateVideoFirstFrame(data.path, maxDimensions: CGSize(width: 320.0, height: 320.0)), let thumbnailData = UIImageJPEGRepresentation(scaledImage, 0.6) { + if let scaledImage = generateVideoFirstFrame(data.path, maxDimensions: CGSize(width: 320.0, height: 320.0)), let thumbnailData = scaledImage.jpegData(compressionQuality: 0.6) { let thumbnailResource = LocalFileMediaResource(fileId: arc4random64()) postbox.mediaBox.storeResourceData(thumbnailResource.id, data: thumbnailData) diff --git a/submodules/TelegramUI/TelegramUI/TwoStepVerificationPasswordEntryController.swift b/submodules/TelegramUI/TelegramUI/TwoStepVerificationPasswordEntryController.swift index badff3718c..27aa965e1b 100644 --- a/submodules/TelegramUI/TelegramUI/TwoStepVerificationPasswordEntryController.swift +++ b/submodules/TelegramUI/TelegramUI/TwoStepVerificationPasswordEntryController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private final class TwoStepVerificationPasswordEntryControllerArguments { let updateEntryText: (String) -> Void @@ -255,7 +256,7 @@ struct TwoStepVerificationPasswordEntryResult { let pendingEmail: TwoStepVerificationPendingEmail? } -func twoStepVerificationPasswordEntryController(context: AccountContext, mode: TwoStepVerificationPasswordEntryMode, result: Promise) -> ViewController { +func twoStepVerificationPasswordEntryController(context: AccountContextImpl, mode: TwoStepVerificationPasswordEntryMode, result: Promise) -> ViewController { let initialStage: PasswordEntryStage switch mode { case .setup, .change: diff --git a/submodules/TelegramUI/TelegramUI/TwoStepVerificationResetController.swift b/submodules/TelegramUI/TelegramUI/TwoStepVerificationResetController.swift index 52bfa73eca..7b02106793 100644 --- a/submodules/TelegramUI/TelegramUI/TwoStepVerificationResetController.swift +++ b/submodules/TelegramUI/TelegramUI/TwoStepVerificationResetController.swift @@ -5,6 +5,8 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI +import TextFormat private final class TwoStepVerificationResetControllerArguments { let updateEntryText: (String) -> Void @@ -131,7 +133,7 @@ private func twoStepVerificationResetControllerEntries(presentationData: Present return entries } -func twoStepVerificationResetController(context: AccountContext, emailPattern: String, result: Promise) -> ViewController { +func twoStepVerificationResetController(context: AccountContextImpl, emailPattern: String, result: Promise) -> ViewController { let initialState = TwoStepVerificationResetControllerState(codeText: "", checking: false) let statePromise = ValuePromise(initialState, ignoreRepeated: true) diff --git a/submodules/TelegramUI/TelegramUI/TwoStepVerificationUnlockController.swift b/submodules/TelegramUI/TelegramUI/TwoStepVerificationUnlockController.swift index c02d95a6af..aec5ec594c 100644 --- a/submodules/TelegramUI/TelegramUI/TwoStepVerificationUnlockController.swift +++ b/submodules/TelegramUI/TelegramUI/TwoStepVerificationUnlockController.swift @@ -5,6 +5,8 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI +import TextFormat private final class TwoStepVerificationUnlockSettingsControllerArguments { let updatePasswordText: (String) -> Void @@ -246,7 +248,7 @@ enum TwoStepVerificationUnlockSettingsControllerData: Equatable { case manage(password: String, emailSet: Bool, pendingEmail: TwoStepVerificationPendingEmail?, hasSecureValues: Bool) } -func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: TwoStepVerificationUnlockSettingsControllerMode, openSetupPasswordImmediately: Bool = false) -> ViewController { +func twoStepVerificationUnlockSettingsController(context: AccountContextImpl, mode: TwoStepVerificationUnlockSettingsControllerMode, openSetupPasswordImmediately: Bool = false) -> ViewController { let initialState = TwoStepVerificationUnlockSettingsControllerState() let statePromise = ValuePromise(initialState, ignoreRepeated: true) diff --git a/submodules/TelegramUI/TelegramUI/UndoOverlayController.swift b/submodules/TelegramUI/TelegramUI/UndoOverlayController.swift index 7dbf09ba1b..fc34836691 100644 --- a/submodules/TelegramUI/TelegramUI/UndoOverlayController.swift +++ b/submodules/TelegramUI/TelegramUI/UndoOverlayController.swift @@ -14,7 +14,7 @@ public enum UndoOverlayContent { } public final class UndoOverlayController: ViewController { - private let context: AccountContext + private let context: AccountContextImpl private let presentationData: PresentationData let content: UndoOverlayContent private let elevatedLayout: Bool @@ -23,7 +23,7 @@ public final class UndoOverlayController: ViewController { private var didPlayPresentationAnimation = false - public init(context: AccountContext, content: UndoOverlayContent, elevatedLayout: Bool, animateInAsReplacement: Bool = false, action: @escaping (Bool) -> Void) { + public init(context: AccountContextImpl, content: UndoOverlayContent, elevatedLayout: Bool, animateInAsReplacement: Bool = false, action: @escaping (Bool) -> Void) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.content = content diff --git a/submodules/TelegramUI/TelegramUI/UndoOverlayControllerNode.swift b/submodules/TelegramUI/TelegramUI/UndoOverlayControllerNode.swift index ac70c36eb7..36f116f13e 100644 --- a/submodules/TelegramUI/TelegramUI/UndoOverlayControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/UndoOverlayControllerNode.swift @@ -4,6 +4,8 @@ import AsyncDisplayKit import Display import SwiftSignalKit import TelegramPresentationData +import AnimationUI +import TextFormat final class UndoOverlayControllerNode: ViewControllerTracingNode { private let elevatedLayout: Bool @@ -329,8 +331,8 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode { } func animateOut(completion: @escaping () -> Void) { - self.panelNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, delay: 0.0, timingFunction: kCAMediaTimingFunctionEaseOut, removeOnCompletion: false, completion: { _ in }) - self.panelWrapperNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, delay: 0.0, timingFunction: kCAMediaTimingFunctionEaseOut, removeOnCompletion: false) { _ in + self.panelNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, delay: 0.0, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { _ in }) + self.panelWrapperNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, delay: 0.0, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false) { _ in completion() } } diff --git a/submodules/TelegramUI/TelegramUI/UniversalVideoGalleryItem.swift b/submodules/TelegramUI/TelegramUI/UniversalVideoGalleryItem.swift index c2b1b21df1..cd91bb7d78 100644 --- a/submodules/TelegramUI/TelegramUI/UniversalVideoGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/UniversalVideoGalleryItem.swift @@ -14,7 +14,7 @@ enum UniversalVideoGalleryItemContentInfo { } class UniversalVideoGalleryItem: GalleryItem { - let context: AccountContext + let context: AccountContextImpl let presentationData: PresentationData let content: UniversalVideoContent let originData: GalleryItemOriginData? @@ -30,7 +30,7 @@ class UniversalVideoGalleryItem: GalleryItem { let performAction: (GalleryControllerInteractionTapAction) -> Void let openActionOptions: (GalleryControllerInteractionTapAction) -> Void - init(context: AccountContext, presentationData: PresentationData, content: UniversalVideoContent, originData: GalleryItemOriginData?, indexData: GalleryItemIndexData?, contentInfo: UniversalVideoGalleryItemContentInfo?, caption: NSAttributedString, credit: NSAttributedString? = nil, hideControls: Bool = false, fromPlayingVideo: Bool = false, landscape: Bool = false, timecode: Double? = nil, playbackCompleted: @escaping () -> Void = {}, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void, openActionOptions: @escaping (GalleryControllerInteractionTapAction) -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, content: UniversalVideoContent, originData: GalleryItemOriginData?, indexData: GalleryItemIndexData?, contentInfo: UniversalVideoGalleryItemContentInfo?, caption: NSAttributedString, credit: NSAttributedString? = nil, hideControls: Bool = false, fromPlayingVideo: Bool = false, landscape: Bool = false, timecode: Double? = nil, playbackCompleted: @escaping () -> Void = {}, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void, openActionOptions: @escaping (GalleryControllerInteractionTapAction) -> Void) { self.context = context self.presentationData = presentationData self.content = content @@ -142,7 +142,7 @@ private struct FetchControls { } final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { - private let context: AccountContext + private let context: AccountContextImpl private let presentationData: PresentationData fileprivate let _ready = Promise() @@ -185,7 +185,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { var playbackCompleted: (() -> Void)? - init(context: AccountContext, presentationData: PresentationData, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void, openActionOptions: @escaping (GalleryControllerInteractionTapAction) -> Void) { + init(context: AccountContextImpl, presentationData: PresentationData, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void, openActionOptions: @escaping (GalleryControllerInteractionTapAction) -> Void) { self.context = context self.presentationData = presentationData self.scrubberView = ChatVideoGalleryItemScrubberView() @@ -883,7 +883,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { let previousFrame = videoNode.frame let previousSuperview = videoNode.view.superview addToTransitionSurface(videoNode.view) - videoNode.view.superview?.bringSubview(toFront: videoNode.view) + videoNode.view.superview?.bringSubviewToFront(videoNode.view) if let previousSuperview = previousSuperview { videoNode.frame = previousSuperview.convert(previousFrame, to: videoNode.view.superview) @@ -925,7 +925,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { let previousFrame = videoNode.frame let previousSuperview = videoNode.view.superview addToTransitionSurface(videoNode.view) - videoNode.view.superview?.bringSubview(toFront: videoNode.view) + videoNode.view.superview?.bringSubviewToFront(videoNode.view) if let previousSuperview = previousSuperview { videoNode.frame = previousSuperview.convert(previousFrame, to: videoNode.view.superview) diff --git a/submodules/TelegramUI/TelegramUI/UserInfoController.swift b/submodules/TelegramUI/TelegramUI/UserInfoController.swift index 6b383bff36..d8c3099235 100644 --- a/submodules/TelegramUI/TelegramUI/UserInfoController.swift +++ b/submodules/TelegramUI/TelegramUI/UserInfoController.swift @@ -7,6 +7,9 @@ import Postbox import TelegramCore import LegacyComponents import TelegramPresentationData +import ItemListUI +import AccountContext +import TextFormat private final class UserInfoControllerArguments { let account: Account @@ -757,7 +760,7 @@ public enum UserInfoControllerMode { case calls(messages: [Message]) } -public func userInfoController(context: AccountContext, peerId: PeerId, mode: UserInfoControllerMode = .generic) -> ViewController { +public func userInfoController(context: AccountContextImpl, peerId: PeerId, mode: UserInfoControllerMode = .generic) -> ViewController { let statePromise = ValuePromise(UserInfoState(), ignoreRepeated: true) let stateValue = Atomic(value: UserInfoState()) let updateState: ((UserInfoState) -> UserInfoState) -> Void = { f in @@ -1448,9 +1451,9 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us } } } - aboutLinkActionImpl = { [weak controller] action, itemLink in - if let controller = controller { - handleTextLinkAction(context: context, peerId: peerId, navigateDisposable: navigateDisposable, controller: controller, action: action, itemLink: itemLink) + aboutLinkActionImpl = { [weak context, weak controller] action, itemLink in + if let controller = controller, let context = context { + context.sharedContext.handleTextLinkAction(context: context, peerId: peerId, navigateDisposable: navigateDisposable, controller: controller, action: action, itemLink: itemLink) } } displayAboutContextMenuImpl = { [weak controller] text in diff --git a/submodules/TelegramUI/TelegramUI/UserInfoEditingPhoneActionItem.swift b/submodules/TelegramUI/TelegramUI/UserInfoEditingPhoneActionItem.swift index 1d64d3ace9..e780fb69d0 100644 --- a/submodules/TelegramUI/TelegramUI/UserInfoEditingPhoneActionItem.swift +++ b/submodules/TelegramUI/TelegramUI/UserInfoEditingPhoneActionItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI class UserInfoEditingPhoneActionItem: ListViewItem, ItemListItem { let theme: PresentationTheme diff --git a/submodules/TelegramUI/TelegramUI/UserInfoEditingPhoneItem.swift b/submodules/TelegramUI/TelegramUI/UserInfoEditingPhoneItem.swift index 0e923545a4..c006750808 100644 --- a/submodules/TelegramUI/TelegramUI/UserInfoEditingPhoneItem.swift +++ b/submodules/TelegramUI/TelegramUI/UserInfoEditingPhoneItem.swift @@ -4,6 +4,7 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramPresentationData +import ItemListUI private func generateClearIcon(color: UIColor) -> UIImage? { return generateTintedImage(image: UIImage(bundleImageName: "Components/Search Bar/Clear"), color: color) diff --git a/submodules/TelegramUI/TelegramUI/UsernameSetupController.swift b/submodules/TelegramUI/TelegramUI/UsernameSetupController.swift index 8b31472e18..37381410cd 100644 --- a/submodules/TelegramUI/TelegramUI/UsernameSetupController.swift +++ b/submodules/TelegramUI/TelegramUI/UsernameSetupController.swift @@ -5,6 +5,7 @@ import SwiftSignalKit import Postbox import TelegramCore import TelegramPresentationData +import ItemListUI private final class UsernameSetupControllerArguments { let account: Account @@ -26,7 +27,7 @@ private enum UsernameSetupSection: Int32 { public enum UsernameEntryTag: ItemListItemTag { case username - func isEqual(to other: ItemListItemTag) -> Bool { + public func isEqual(to other: ItemListItemTag) -> Bool { if let other = other as? UsernameEntryTag, self == other { return true } else { @@ -218,7 +219,7 @@ private func usernameSetupControllerEntries(presentationData: PresentationData, return entries } -public func usernameSetupController(context: AccountContext) -> ViewController { +public func usernameSetupController(context: AccountContextImpl) -> ViewController { let statePromise = ValuePromise(UsernameSetupControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: UsernameSetupControllerState()) let updateState: ((UsernameSetupControllerState) -> UsernameSetupControllerState) -> Void = { f in diff --git a/submodules/TelegramUI/TelegramUI/VerticalListContextResultsChatInputContextPanelNode.swift b/submodules/TelegramUI/TelegramUI/VerticalListContextResultsChatInputContextPanelNode.swift index 69a2328b7a..1a8e2da854 100644 --- a/submodules/TelegramUI/TelegramUI/VerticalListContextResultsChatInputContextPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/VerticalListContextResultsChatInputContextPanelNode.swift @@ -5,6 +5,7 @@ import Postbox import TelegramCore import Display import TelegramPresentationData +import MergeLists private enum VerticalChatContextResultsEntryStableId: Hashable { case action @@ -125,7 +126,7 @@ final class VerticalListContextResultsChatInputContextPanelNode: ChatInputContex private var validLayout: (CGSize, CGFloat, CGFloat)? - override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + override init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.listView = ListView() self.listView.isOpaque = false self.listView.stackFromBottom = true diff --git a/submodules/TelegramUI/TelegramUI/VoiceCallDataSavingController.swift b/submodules/TelegramUI/TelegramUI/VoiceCallDataSavingController.swift index 19e3d3b76a..ff9d055d15 100644 --- a/submodules/TelegramUI/TelegramUI/VoiceCallDataSavingController.swift +++ b/submodules/TelegramUI/TelegramUI/VoiceCallDataSavingController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class VoiceCallDataSavingControllerArguments { let updateSelection: (VoiceCallDataSaving) -> Void @@ -117,7 +118,7 @@ private func voiceCallDataSavingControllerEntries(presentationData: Presentation return entries } -func voiceCallDataSavingController(context: AccountContext) -> ViewController { +func voiceCallDataSavingController(context: AccountContextImpl) -> ViewController { let sharedSettings = context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.voiceCallSettings]) |> map { sharedData -> (VoiceCallSettings, AutodownloadSettings) in let voiceCallSettings: VoiceCallSettings diff --git a/submodules/TelegramUI/TelegramUI/WallpaperColorPickerNode.swift b/submodules/TelegramUI/TelegramUI/WallpaperColorPickerNode.swift index acf7a86f1f..c0ebb29a7d 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperColorPickerNode.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperColorPickerNode.swift @@ -226,11 +226,11 @@ final class WallpaperColorPickerNode: ASDisplayNode { init(strings: PresentationStrings) { self.brightnessNode = WallpaperColorBrightnessNode() - self.brightnessNode.hitTestSlop = UIEdgeInsetsMake(-16.0, -16.0, -16.0, -16.0) + self.brightnessNode.hitTestSlop = UIEdgeInsets(top: -16.0, left: -16.0, bottom: -16.0, right: -16.0) self.brightnessKnobNode = ASImageNode() self.brightnessKnobNode.image = pointerImage self.colorNode = WallpaperColorHueSaturationNode() - self.colorNode.hitTestSlop = UIEdgeInsetsMake(-16.0, -16.0, -16.0, -16.0) + self.colorNode.hitTestSlop = UIEdgeInsets(top: -16.0, left: -16.0, bottom: -16.0, right: -16.0) self.colorKnobNode = WallpaperColorKnobNode() super.init() diff --git a/submodules/TelegramUI/TelegramUI/WallpaperCropNode.swift b/submodules/TelegramUI/TelegramUI/WallpaperCropNode.swift index 84b1b9e8b8..d87c423254 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperCropNode.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperCropNode.swift @@ -40,7 +40,7 @@ final class WallpaperCropNode: ASDisplayNode, UIScrollViewDelegate { self.scrollNode.view.clipsToBounds = false self.scrollNode.view.scrollsToTop = false self.scrollNode.view.delaysContentTouches = false - self.scrollNode.view.decelerationRate = UIScrollViewDecelerationRateFast + self.scrollNode.view.decelerationRate = UIScrollView.DecelerationRate.fast self.addSubnode(self.scrollNode) } diff --git a/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift b/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift index b9dbcab722..14b4ddf812 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperGalleryController.swift @@ -118,7 +118,7 @@ class WallpaperGalleryController: ViewController { return self.displayNode as! GalleryControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private let source: WallpaperListSource var apply: ((WallpaperGalleryEntry, WallpaperPresentationOptions, CGRect?) -> Void)? @@ -156,7 +156,7 @@ class WallpaperGalleryController: ViewController { private var colorPanelEnabled = false private var patternPanelEnabled = false - init(context: AccountContext, source: WallpaperListSource) { + init(context: AccountContextImpl, source: WallpaperListSource) { self.context = context self.source = source self.presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -797,7 +797,7 @@ private extension GalleryControllerNode { } func modalAnimateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/WallpaperGalleryItem.swift b/submodules/TelegramUI/TelegramUI/WallpaperGalleryItem.swift index 487551af6b..7565377a21 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperGalleryItem.swift @@ -8,6 +8,7 @@ import TelegramCore import LegacyComponents import TelegramPresentationData import TelegramUIPreferences +import ProgressNavigationButtonNode struct WallpaperGalleryItemArguments { let colorPreview: Bool @@ -22,11 +23,11 @@ struct WallpaperGalleryItemArguments { } class WallpaperGalleryItem: GalleryItem { - let context: AccountContext + let context: AccountContextImpl let entry: WallpaperGalleryEntry let arguments: WallpaperGalleryItemArguments - init(context: AccountContext, entry: WallpaperGalleryEntry, arguments: WallpaperGalleryItemArguments) { + init(context: AccountContextImpl, entry: WallpaperGalleryEntry, arguments: WallpaperGalleryItemArguments) { self.context = context self.entry = entry self.arguments = arguments @@ -60,7 +61,7 @@ private func reference(for resource: MediaResource, media: Media, message: Messa } final class WallpaperGalleryItemNode: GalleryItemNode { - private let context: AccountContext + private let context: AccountContextImpl var entry: WallpaperGalleryEntry? private var colorPreview: Bool = false private var contentSize: CGSize? @@ -90,7 +91,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { private var validLayout: ContainerViewLayout? private var validOffset: CGFloat? - init(context: AccountContext) { + init(context: AccountContextImpl) { self.context = context self.wrapperNode = ASDisplayNode() @@ -555,7 +556,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { if animated { self.blurredNode.blurView.blurRadius = 0.0 - UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions(rawValue: 7 << 16), animations: { + UIView.animate(withDuration: 0.3, delay: 0.0, options: UIView.AnimationOptions(rawValue: 7 << 16), animations: { self.blurredNode.blurView.blurRadius = blurRadius }, completion: nil) } else { @@ -564,7 +565,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { } else { if self.blurredNode.supernode != nil { if animated { - UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions(rawValue: 7 << 16), animations: { + UIView.animate(withDuration: 0.3, delay: 0.0, options: UIView.AnimationOptions(rawValue: 7 << 16), animations: { self.blurredNode.blurView.blurRadius = 0.0 }, completion: { finished in if finished { diff --git a/submodules/TelegramUI/TelegramUI/WallpaperPatternPanelNode.swift b/submodules/TelegramUI/TelegramUI/WallpaperPatternPanelNode.swift index 6abc2dd38c..cb41fab342 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperPatternPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperPatternPanelNode.swift @@ -27,7 +27,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode { var patternChanged: ((TelegramWallpaper, Int32?, Bool) -> Void)? - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings) { self.theme = theme self.backgroundNode = ASDisplayNode() diff --git a/submodules/TelegramUI/TelegramUI/WallpaperResources.swift b/submodules/TelegramUI/TelegramUI/WallpaperResources.swift index 678d6e03b6..1f530a7216 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperResources.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperResources.swift @@ -171,7 +171,7 @@ func wallpaperImage(account: Account, accountManager: AccountManager, fileRefere 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 fullSizeImage: CGImage? - var imageOrientation: UIImageOrientation = .up + var imageOrientation: UIImage.Orientation = .up if let fullSizeData = fullSizeData { if fullSizeComplete { let options = NSMutableDictionary() diff --git a/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift b/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift index 4677124776..390e4badb7 100644 --- a/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift +++ b/submodules/TelegramUI/TelegramUI/WallpaperUploadManager.swift @@ -57,7 +57,7 @@ enum WallpaperUploadManagerStatus { } final class WallpaperUploadManager { - private let sharedContext: SharedAccountContext + private let sharedContext: SharedAccountContextImpl private let account: Account private var context: WallpaperUploadContext? @@ -66,7 +66,7 @@ final class WallpaperUploadManager { private let statePromise = Promise(.none) - init(sharedContext: SharedAccountContext, account: Account, presentationData: Signal) { + init(sharedContext: SharedAccountContextImpl, account: Account, presentationData: Signal) { self.sharedContext = sharedContext self.account = account self.presentationDataDisposable.set(presentationData.start(next: { [weak self] presentationData in diff --git a/submodules/TelegramUI/TelegramUI/WatchCommunicationManager.swift b/submodules/TelegramUI/TelegramUI/WatchCommunicationManager.swift index 0cd2157115..c6425101b2 100644 --- a/submodules/TelegramUI/TelegramUI/WatchCommunicationManager.swift +++ b/submodules/TelegramUI/TelegramUI/WatchCommunicationManager.swift @@ -16,7 +16,7 @@ final class WatchCommunicationManager { private let contextDisposable = MetaDisposable() private let presetsDisposable = MetaDisposable() - let accountContext = Promise(nil) + let accountContext = Promise(nil) private let presets = Promise(nil) private let navigateToMessagePipe = ValuePipe() diff --git a/submodules/TelegramUI/TelegramUI/WatchRequestHandlers.swift b/submodules/TelegramUI/TelegramUI/WatchRequestHandlers.swift index bf16a14cbc..3248352392 100644 --- a/submodules/TelegramUI/TelegramUI/WatchRequestHandlers.swift +++ b/submodules/TelegramUI/TelegramUI/WatchRequestHandlers.swift @@ -420,7 +420,7 @@ final class WatchMediaHandler: WatchRequestHandler { }) let disposable = signal.start(next: { image in - if let image = image, let imageData = UIImageJPEGRepresentation(image, compressionRate) { + if let image = image, let imageData = image.jpegData(compressionQuality: compressionRate) { sendData(manager: manager, data: imageData, key: key, ext: ".jpg", type: TGBridgeIncomingFileTypeImage) } subscriber?.putNext(key) @@ -487,7 +487,7 @@ final class WatchMediaHandler: WatchRequestHandler { }) let disposable = signal.start(next: { image in - if let image = image, let imageData = UIImageJPEGRepresentation(image, 0.2) { + if let image = image, let imageData = image.jpegData(compressionQuality: 0.2) { sendData(manager: manager, data: imageData, key: key, ext: ".jpg", type: TGBridgeIncomingFileTypeImage, forceAsData: args.notification) } subscriber?.putNext(key) @@ -561,7 +561,7 @@ final class WatchMediaHandler: WatchRequestHandler { } |> map{ f -> UIImage? in var insets = UIEdgeInsets() if roundVideo { - insets = UIEdgeInsetsMake(-2, -2, -2, -2) + insets = UIEdgeInsets(top: -2, left: -2, bottom: -2, right: -2) } let context = f(TransformImageArguments(corners: ImageCorners(), imageSize: args.size, boundingSize: args.size, intrinsicInsets: insets, scale: 2.0)) return context?.generateImage() @@ -572,7 +572,7 @@ final class WatchMediaHandler: WatchRequestHandler { }) let disposable = signal.start(next: { image in - if let image = image, let imageData = UIImageJPEGRepresentation(image, 0.5) { + if let image = image, let imageData = image.jpegData(compressionQuality: 0.5) { sendData(manager: manager, data: imageData, key: key, ext: ".jpg", type: TGBridgeIncomingFileTypeImage, forceAsData: args.notification) } subscriber?.putNext(key) diff --git a/submodules/TelegramUI/TelegramUI/WatchSettingsController.swift b/submodules/TelegramUI/TelegramUI/WatchSettingsController.swift index 22db369b0b..97aa98a4c1 100644 --- a/submodules/TelegramUI/TelegramUI/WatchSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/WatchSettingsController.swift @@ -6,6 +6,7 @@ import Postbox import TelegramCore import TelegramPresentationData import TelegramUIPreferences +import ItemListUI private final class WatchSettingsControllerArguments { let updatePreset: (String, String) -> Void @@ -108,7 +109,7 @@ private func watchSettingsControllerEntries(presentationData: PresentationData, return entries } -public func watchSettingsController(context: AccountContext) -> ViewController { +public func watchSettingsController(context: AccountContextImpl) -> ViewController { var pushControllerImpl: ((ViewController) -> Void)? var presentControllerImpl: ((ViewController) -> Void)? diff --git a/submodules/TelegramUI/TelegramUI/WebSearchBadgeNode.swift b/submodules/TelegramUI/TelegramUI/WebSearchBadgeNode.swift index 2971837a33..9487ecd225 100644 --- a/submodules/TelegramUI/TelegramUI/WebSearchBadgeNode.swift +++ b/submodules/TelegramUI/TelegramUI/WebSearchBadgeNode.swift @@ -79,7 +79,7 @@ final class WebSearchBadgeNode: ASDisplayNode { } func animateOut() { - let timingFunction = kCAMediaTimingFunctionEaseInEaseOut + let timingFunction = CAMediaTimingFunctionName.easeInEaseOut.rawValue self.backgroundNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.3, delay: 0.0, timingFunction: timingFunction, removeOnCompletion: true, completion: nil) self.textNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.3, delay: 0.0, timingFunction: timingFunction, removeOnCompletion: true, completion: nil) } diff --git a/submodules/TelegramUI/TelegramUI/WebSearchController.swift b/submodules/TelegramUI/TelegramUI/WebSearchController.swift index 1505a37826..04f542c576 100644 --- a/submodules/TelegramUI/TelegramUI/WebSearchController.swift +++ b/submodules/TelegramUI/TelegramUI/WebSearchController.swift @@ -105,7 +105,7 @@ private func selectionChangedSignal(selectionState: TGMediaSelectionContext) -> final class WebSearchController: ViewController { private var validLayout: ContainerViewLayout? - private let context: AccountContext + private let context: AccountContextImpl private let mode: WebSearchControllerMode private let peer: Peer? private let configuration: SearchBotsConfiguration @@ -131,7 +131,7 @@ final class WebSearchController: ViewController { private var navigationContentNode: WebSearchNavigationContentNode? - init(context: AccountContext, peer: Peer?, configuration: SearchBotsConfiguration, mode: WebSearchControllerMode) { + init(context: AccountContextImpl, peer: Peer?, configuration: SearchBotsConfiguration, mode: WebSearchControllerMode) { self.context = context self.mode = mode self.peer = peer diff --git a/submodules/TelegramUI/TelegramUI/WebSearchControllerNode.swift b/submodules/TelegramUI/TelegramUI/WebSearchControllerNode.swift index efe1482b7d..fcc329fc11 100644 --- a/submodules/TelegramUI/TelegramUI/WebSearchControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/WebSearchControllerNode.swift @@ -8,6 +8,7 @@ import TelegramCore import LegacyComponents import TelegramPresentationData import TelegramUIPreferences +import MergeLists private struct WebSearchContextResultStableId: Hashable { let result: ChatContextResult @@ -119,7 +120,7 @@ private func preparedWebSearchRecentTransition(from fromEntries: [WebSearchRecen } class WebSearchControllerNode: ASDisplayNode { - private let context: AccountContext + private let context: AccountContextImpl private let peer: Peer? private var theme: PresentationTheme private var strings: PresentationStrings @@ -171,7 +172,7 @@ class WebSearchControllerNode: ASDisplayNode { var cancel: (() -> Void)? var dismissInput: (() -> Void)? - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: WebSearchControllerInteraction, peer: Peer?, mode: WebSearchMode) { + init(context: AccountContextImpl, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: WebSearchControllerInteraction, peer: Peer?, mode: WebSearchMode) { self.context = context self.theme = theme self.strings = strings @@ -343,7 +344,7 @@ class WebSearchControllerNode: ASDisplayNode { } func animateOut(completion: (() -> Void)? = nil) { - self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, removeOnCompletion: false, completion: { _ in + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in completion?() }) } diff --git a/submodules/TelegramUI/TelegramUI/WebSearchGalleryController.swift b/submodules/TelegramUI/TelegramUI/WebSearchGalleryController.swift index dcc062e2b9..9df6618da0 100644 --- a/submodules/TelegramUI/TelegramUI/WebSearchGalleryController.swift +++ b/submodules/TelegramUI/TelegramUI/WebSearchGalleryController.swift @@ -30,7 +30,7 @@ struct WebSearchGalleryEntry: Equatable { return lhs.result == rhs.result } - func item(context: AccountContext, presentationData: PresentationData, controllerInteraction: WebSearchGalleryControllerInteraction?) -> GalleryItem { + func item(context: AccountContextImpl, presentationData: PresentationData, controllerInteraction: WebSearchGalleryControllerInteraction?) -> GalleryItem { switch self.result { case let .externalReference(_, _, type, _, _, _, content, thumbnail, _): if let content = content, type == "gif", let thumbnailResource = thumbnail?.resource, let dimensions = content.dimensions { @@ -63,7 +63,7 @@ class WebSearchGalleryController: ViewController { return self.displayNode as! GalleryControllerNode } - private let context: AccountContext + private let context: AccountContextImpl private var presentationData: PresentationData private var controllerInteraction: WebSearchGalleryControllerInteraction? @@ -95,7 +95,7 @@ class WebSearchGalleryController: ViewController { private let replaceRootController: (ViewController, ValuePromise?) -> Void private let baseNavigationController: NavigationController? - init(context: AccountContext, peer: Peer?, selectionState: TGMediaSelectionContext?, editingState: TGMediaEditingContext, entries: [WebSearchGalleryEntry], centralIndex: Int, replaceRootController: @escaping (ViewController, ValuePromise?) -> Void, baseNavigationController: NavigationController?, sendCurrent: @escaping (ChatContextResult) -> Void) { + init(context: AccountContextImpl, peer: Peer?, selectionState: TGMediaSelectionContext?, editingState: TGMediaEditingContext, entries: [WebSearchGalleryEntry], centralIndex: Int, replaceRootController: @escaping (ViewController, ValuePromise?) -> Void, baseNavigationController: NavigationController?, sendCurrent: @escaping (ChatContextResult) -> Void) { self.context = context self.replaceRootController = replaceRootController self.baseNavigationController = baseNavigationController diff --git a/submodules/TelegramUI/TelegramUI/WebSearchGalleryFooterContentNode.swift b/submodules/TelegramUI/TelegramUI/WebSearchGalleryFooterContentNode.swift index 30a495e24d..fa72dff4b9 100644 --- a/submodules/TelegramUI/TelegramUI/WebSearchGalleryFooterContentNode.swift +++ b/submodules/TelegramUI/TelegramUI/WebSearchGalleryFooterContentNode.swift @@ -9,7 +9,7 @@ import LegacyComponents import TelegramPresentationData final class WebSearchGalleryFooterContentNode: GalleryFooterContentNode { - private let context: AccountContext + private let context: AccountContextImpl private var theme: PresentationTheme private var strings: PresentationStrings @@ -19,7 +19,7 @@ final class WebSearchGalleryFooterContentNode: GalleryFooterContentNode { var cancel: (() -> Void)? var send: (() -> Void)? - init(context: AccountContext, presentationData: PresentationData) { + init(context: AccountContextImpl, presentationData: PresentationData) { self.context = context self.theme = presentationData.theme self.strings = presentationData.strings diff --git a/submodules/TelegramUI/TelegramUI/WebSearchItem.swift b/submodules/TelegramUI/TelegramUI/WebSearchItem.swift index 5753330d20..a2a4ebb6fe 100644 --- a/submodules/TelegramUI/TelegramUI/WebSearchItem.swift +++ b/submodules/TelegramUI/TelegramUI/WebSearchItem.swift @@ -6,6 +6,7 @@ import TelegramCore import SwiftSignalKit import Postbox import TelegramPresentationData +import CheckNode final class WebSearchItem: GridItem { var section: GridSection? diff --git a/submodules/TelegramUI/TelegramUI/WebSearchRecentQueryItem.swift b/submodules/TelegramUI/TelegramUI/WebSearchRecentQueryItem.swift index 48f3ff323e..f505c5615e 100644 --- a/submodules/TelegramUI/TelegramUI/WebSearchRecentQueryItem.swift +++ b/submodules/TelegramUI/TelegramUI/WebSearchRecentQueryItem.swift @@ -6,6 +6,7 @@ import Display import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ItemListUI private enum RevealOptionKey: Int32 { case delete diff --git a/submodules/TelegramUI/TelegramUI/WebSearchVideoGalleryItem.swift b/submodules/TelegramUI/TelegramUI/WebSearchVideoGalleryItem.swift index f8f3e586e7..7dc44ab881 100644 --- a/submodules/TelegramUI/TelegramUI/WebSearchVideoGalleryItem.swift +++ b/submodules/TelegramUI/TelegramUI/WebSearchVideoGalleryItem.swift @@ -8,13 +8,13 @@ import Postbox import TelegramPresentationData class WebSearchVideoGalleryItem: GalleryItem { - let context: AccountContext + let context: AccountContextImpl let presentationData: PresentationData let result: ChatContextResult let content: UniversalVideoContent let controllerInteraction: WebSearchGalleryControllerInteraction? - init(context: AccountContext, presentationData: PresentationData, result: ChatContextResult, content: UniversalVideoContent, controllerInteraction: WebSearchGalleryControllerInteraction?) { + init(context: AccountContextImpl, presentationData: PresentationData, result: ChatContextResult, content: UniversalVideoContent, controllerInteraction: WebSearchGalleryControllerInteraction?) { self.context = context self.presentationData = presentationData self.result = result @@ -45,7 +45,7 @@ private struct FetchControls { } final class WebSearchVideoGalleryItemNode: ZoomableContentGalleryItemNode { - private let context: AccountContext + private let context: AccountContextImpl private let strings: PresentationStrings private let controllerInteraction: WebSearchGalleryControllerInteraction? @@ -74,7 +74,7 @@ final class WebSearchVideoGalleryItemNode: ZoomableContentGalleryItemNode { var playbackCompleted: (() -> Void)? - init(context: AccountContext, presentationData: PresentationData, controllerInteraction: WebSearchGalleryControllerInteraction?) { + init(context: AccountContextImpl, presentationData: PresentationData, controllerInteraction: WebSearchGalleryControllerInteraction?) { self.context = context self.strings = presentationData.strings self.controllerInteraction = controllerInteraction diff --git a/submodules/TelegramUI/TelegramUI/WebpagePreviewAccessoryPanelNode.swift b/submodules/TelegramUI/TelegramUI/WebpagePreviewAccessoryPanelNode.swift index ccd4c68e32..adc5064e6c 100644 --- a/submodules/TelegramUI/TelegramUI/WebpagePreviewAccessoryPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/WebpagePreviewAccessoryPanelNode.swift @@ -24,7 +24,7 @@ final class WebpagePreviewAccessoryPanelNode: AccessoryPanelNode { var theme: PresentationTheme var strings: PresentationStrings - init(context: AccountContext, url: String, webpage: TelegramMediaWebpage, theme: PresentationTheme, strings: PresentationStrings) { + init(context: AccountContextImpl, url: String, webpage: TelegramMediaWebpage, theme: PresentationTheme, strings: PresentationStrings) { self.url = url self.webpage = webpage self.theme = theme @@ -32,7 +32,7 @@ final class WebpagePreviewAccessoryPanelNode: AccessoryPanelNode { self.closeButton = ASButtonNode() self.closeButton.setImage(PresentationResourcesChat.chatInputPanelCloseIconImage(theme), for: []) - self.closeButton.hitTestSlop = UIEdgeInsetsMake(-8.0, -8.0, -8.0, -8.0) + self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0) self.closeButton.displaysAsynchronously = false self.lineNode = ASImageNode() diff --git a/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj b/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj index 2588253396..1b1e4795e1 100644 --- a/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj +++ b/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj @@ -122,7 +122,6 @@ 09CE95062236D47F00A7D2C3 /* SettingsSearchItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09CE95052236D47F00A7D2C3 /* SettingsSearchItem.swift */; }; 09CE95082237A53900A7D2C3 /* SettingsSearchableItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09CE95072237A53900A7D2C3 /* SettingsSearchableItems.swift */; }; 09CE950A2237B93500A7D2C3 /* SettingsSearchResultItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09CE95092237B93500A7D2C3 /* SettingsSearchResultItem.swift */; }; - 09CE950C2237D61B00A7D2C3 /* PresentationResourcesSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09CE950B2237D61B00A7D2C3 /* PresentationResourcesSettings.swift */; }; 09CE950E2237E45E00A7D2C3 /* CachedFaqInstantPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09CE950D2237E45E00A7D2C3 /* CachedFaqInstantPage.swift */; }; 09CE95112237F3C100A7D2C3 /* SettingsSearchRecentQueries.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09CE95102237F3C100A7D2C3 /* SettingsSearchRecentQueries.swift */; }; 09CE9513223825B700A7D2C3 /* CustomWallpaperPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09CE9512223825B700A7D2C3 /* CustomWallpaperPicker.swift */; }; @@ -150,14 +149,11 @@ 09DE2F292269D5E30045E975 /* PrivacyIntroControllerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09DE2F282269D5E30045E975 /* PrivacyIntroControllerNode.swift */; }; 09E2D9EF226F1AFA00EA0AA4 /* Emoji.mapping in Resources */ = {isa = PBXBuildFile; fileRef = 09E2D9ED226F1AF300EA0AA4 /* Emoji.mapping */; }; 09E2D9F1226F214000EA0AA4 /* EmojiResources.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E2D9F0226F214000EA0AA4 /* EmojiResources.swift */; }; - 09E2DA112273340E00EA0AA4 /* AnimationNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E2DA102273340E00EA0AA4 /* AnimationNode.swift */; }; 09E2DA132273367900EA0AA4 /* anim_archiveAvatar.json in Resources */ = {isa = PBXBuildFile; fileRef = 09E2DA122273367900EA0AA4 /* anim_archiveAvatar.json */; }; 09E4A801223AE1B30038140F /* PeerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E4A800223AE1B30038140F /* PeerType.swift */; }; 09E4A803223B833B0038140F /* ForwardPrivacyChatPreviewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E4A802223B833B0038140F /* ForwardPrivacyChatPreviewItem.swift */; }; 09E4A805223D4A5A0038140F /* OpenSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E4A804223D4A5A0038140F /* OpenSettings.swift */; }; 09E4A807223D4B860038140F /* AccountUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E4A806223D4B860038140F /* AccountUtils.swift */; }; - 09EC0DE722C67FB100E7185B /* UpdateInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EC0DE622C67FB100E7185B /* UpdateInfoController.swift */; }; - 09EC0DEB22CAFF1400E7185B /* UpdateInfoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EC0DEA22CAFF1400E7185B /* UpdateInfoItem.swift */; }; 09EC0DED22CB583C00E7185B /* TextLinkHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EC0DEC22CB583C00E7185B /* TextLinkHandling.swift */; }; 09EC5CDC22CBD33D00292E42 /* NumberFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EC5CDB22CBD33D00292E42 /* NumberFormat.swift */; }; 09EDAD26220D30980012A50B /* AutodownloadConnectionTypeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EDAD25220D30980012A50B /* AutodownloadConnectionTypeController.swift */; }; @@ -308,14 +304,11 @@ D01BAA1E1ECC931D00295217 /* CallListNodeEntries.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01BAA1D1ECC931D00295217 /* CallListNodeEntries.swift */; }; D01BAA201ECC9A2500295217 /* CallListNodeLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01BAA1F1ECC9A2500295217 /* CallListNodeLocation.swift */; }; D01BAA221ECE076100295217 /* CallListCallItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01BAA211ECE076100295217 /* CallListCallItem.swift */; }; - D01BAA241ECE173200295217 /* PresentationResourcesCallList.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01BAA231ECE173200295217 /* PresentationResourcesCallList.swift */; }; D01BAA581ED3283D00295217 /* AddFormatToStringWithRanges.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01BAA571ED3283D00295217 /* AddFormatToStringWithRanges.swift */; }; D01C06AF1FBB461E001561AB /* JoinLinkPreviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C06AE1FBB461E001561AB /* JoinLinkPreviewController.swift */; }; D01C06B11FBB4643001561AB /* JoinLinkPreviewControllerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C06B01FBB4643001561AB /* JoinLinkPreviewControllerNode.swift */; }; D01C06B31FBB49A5001561AB /* JoinLinkPreviewPeerContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C06B21FBB49A5001561AB /* JoinLinkPreviewPeerContentNode.swift */; }; D01C06B51FBB7720001561AB /* ChatMediaInputSettingsItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C06B41FBB7720001561AB /* ChatMediaInputSettingsItem.swift */; }; - D01C06BA1FBBB076001561AB /* ItemListSelectableControlNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C06B91FBBB076001561AB /* ItemListSelectableControlNode.swift */; }; - D01C06BC1FBBB0D8001561AB /* CheckNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C06BB1FBBB0D8001561AB /* CheckNode.swift */; }; D01C06BE1FBCAF06001561AB /* ChatMessageBubbleMosaicLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C06BD1FBCAF06001561AB /* ChatMessageBubbleMosaicLayout.swift */; }; D01C06C01FBF118A001561AB /* MessageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C06BF1FBF118A001561AB /* MessageUtils.swift */; }; D01C99781F4F382C00DCFAF6 /* InstantPageSettingsItemTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C99771F4F382C00DCFAF6 /* InstantPageSettingsItemTheme.swift */; }; @@ -359,11 +352,9 @@ D039FB1921711B5D00BD1BAD /* PlatformVideoContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D039FB1821711B5D00BD1BAD /* PlatformVideoContent.swift */; }; D03AA4DF202DBF6F0056C405 /* ChatContextResultPeekContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03AA4DE202DBF6F0056C405 /* ChatContextResultPeekContentNode.swift */; }; D03AA4E5202DF8840056C405 /* StickerPreviewPeekContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03AA4E4202DF8840056C405 /* StickerPreviewPeekContent.swift */; }; - D03AA4E7202DFB160056C405 /* ItemListEditableReorderControlNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03AA4E6202DFB160056C405 /* ItemListEditableReorderControlNode.swift */; }; D03AE67322B9459C0078411C /* HockeySDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D03AE67222B9459C0078411C /* HockeySDK.framework */; }; D03AE67522B945D30078411C /* BuildConfig.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D03AE67422B945D30078411C /* BuildConfig.framework */; }; D04203152037162700490EA5 /* MediaInputPaneTrendingItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04203142037162700490EA5 /* MediaInputPaneTrendingItem.swift */; }; - D04281ED200E3B28009DDE36 /* ItemListControllerSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281EC200E3B28009DDE36 /* ItemListControllerSearch.swift */; }; D04281EF200E3D88009DDE36 /* GroupInfoSearchItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281EE200E3D88009DDE36 /* GroupInfoSearchItem.swift */; }; D04281F1200E4084009DDE36 /* GroupInfoSearchNavigationContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281F0200E4084009DDE36 /* GroupInfoSearchNavigationContentNode.swift */; }; D04281F4200E5AB0009DDE36 /* ChatRecentActionsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04281F3200E5AB0009DDE36 /* ChatRecentActionsController.swift */; }; @@ -413,7 +404,6 @@ D050A464229C052A0044F11A /* ChannelDiscussionGroupSetupSearchItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D050A463229C052A0044F11A /* ChannelDiscussionGroupSetupSearchItem.swift */; }; D050A466229C06460044F11A /* ChannelDiscussionGroupSearchContainerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D050A465229C06460044F11A /* ChannelDiscussionGroupSearchContainerNode.swift */; }; D053B4371F1A9CA000E2D58A /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D053B4361F1A9CA000E2D58A /* WebKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - D053DADA201A4C4400993D32 /* ChatTextInputAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D053DAD9201A4C4400993D32 /* ChatTextInputAttributes.swift */; }; D053DADC201AAAB100993D32 /* ChatTextInputMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = D053DADB201AAAB100993D32 /* ChatTextInputMenu.swift */; }; D05677511F4CA0C2001B723E /* InstantPagePeerReferenceItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05677501F4CA0C2001B723E /* InstantPagePeerReferenceItem.swift */; }; D05677531F4CA0D0001B723E /* InstantPagePeerReferenceNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05677521F4CA0D0001B723E /* InstantPagePeerReferenceNode.swift */; }; @@ -430,6 +420,11 @@ D05D8B742195CD890064586F /* SetupTwoStepVerificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05D8B732195CD890064586F /* SetupTwoStepVerificationController.swift */; }; D05D8B762195CD930064586F /* SetupTwoStepVerificationControllerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05D8B752195CD930064586F /* SetupTwoStepVerificationControllerNode.swift */; }; D05D8B782195E0050064586F /* SetupTwoStepVerificationContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05D8B772195E0050064586F /* SetupTwoStepVerificationContentNode.swift */; }; + D060184022F35D1C00796784 /* MergeLists.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060183F22F35D1C00796784 /* MergeLists.framework */; }; + D060184222F35D2000796784 /* ActivityIndicator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060184122F35D2000796784 /* ActivityIndicator.framework */; }; + D060184422F35D2400796784 /* ProgressNavigationButtonNode.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060184322F35D2400796784 /* ProgressNavigationButtonNode.framework */; }; + D060184622F35D2B00796784 /* ItemListUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D060184522F35D2B00796784 /* ItemListUI.framework */; }; + D06018B522F3659900796784 /* ChatTextFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06018B422F3659900796784 /* ChatTextFormat.swift */; }; D06350AE2229A7F800FA2B32 /* InChatPrefetchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06350AD2229A7F800FA2B32 /* InChatPrefetchManager.swift */; }; D0642EFC1F3E1E7B00792790 /* ChatHistoryNavigationButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0642EFB1F3E1E7B00792790 /* ChatHistoryNavigationButtons.swift */; }; D064EF871F69A06F00AC0398 /* MessageContentKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = D064EF861F69A06F00AC0398 /* MessageContentKind.swift */; }; @@ -631,9 +626,7 @@ D0BFAE4620AB04FB00793CF2 /* ChatRestrictedInputPanelNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BFAE4520AB04FB00793CF2 /* ChatRestrictedInputPanelNode.swift */; }; D0BFAE4E20AB1D7B00793CF2 /* DisabledContextResultsChatInputContextPanelNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BFAE4D20AB1D7B00793CF2 /* DisabledContextResultsChatInputContextPanelNode.swift */; }; D0BFAE5020AB2A1300793CF2 /* PeerBanTimeoutController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BFAE4F20AB2A1300793CF2 /* PeerBanTimeoutController.swift */; }; - D0BFAE5B20AB35D200793CF2 /* IconSwitchNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BFAE5A20AB35D200793CF2 /* IconSwitchNode.swift */; }; D0BFAE5D20AB426300793CF2 /* PeerTitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BFAE5C20AB426300793CF2 /* PeerTitle.swift */; }; - D0C0B5901EDB505E000F4D2C /* ActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B58F1EDB505E000F4D2C /* ActivityIndicator.swift */; }; D0C0B59B1EE019E5000F4D2C /* ChatSearchNavigationContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B59A1EE019E5000F4D2C /* ChatSearchNavigationContentNode.swift */; }; D0C0B59F1EE082F5000F4D2C /* ChatSearchInputPanelNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B59E1EE082F5000F4D2C /* ChatSearchInputPanelNode.swift */; }; D0C0B5B11EE1C421000F4D2C /* ChatDateSelectionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5B01EE1C421000F4D2C /* ChatDateSelectionSheet.swift */; }; @@ -662,6 +655,7 @@ D0CFBB911FD881A600B65C0D /* AudioRecordningToneData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CFBB901FD881A600B65C0D /* AudioRecordningToneData.swift */; }; D0CFBB951FD8B05000B65C0D /* OverlayInstantVideoDecoration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CFBB941FD8B05000B65C0D /* OverlayInstantVideoDecoration.swift */; }; D0CFBB971FD8B0F700B65C0D /* ChatBubbleInstantVideoDecoration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CFBB961FD8B0F700B65C0D /* ChatBubbleInstantVideoDecoration.swift */; }; + D0D3281422F31B3000D07EE2 /* TelegramUpdateUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D3281322F31B3000D07EE2 /* TelegramUpdateUI.framework */; }; D0D4345C1F97CEAA00CC1806 /* ProxyServerSettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4345B1F97CEAA00CC1806 /* ProxyServerSettingsController.swift */; }; D0D9DE0D20EFEA2E00F20B06 /* InstantPageMediaPlaylist.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D9DE0C20EFEA2E00F20B06 /* InstantPageMediaPlaylist.swift */; }; D0DE5805205B202500C356A8 /* ScreenCaptureDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DE5804205B202500C356A8 /* ScreenCaptureDetection.swift */; }; @@ -682,7 +676,6 @@ D0E412D5206A842900BEE4A2 /* SecureIdVerificationDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E412D4206A842900BEE4A2 /* SecureIdVerificationDocument.swift */; }; D0E412DA206A894800BEE4A2 /* SecureIdValueFormFileItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E412D9206A894800BEE4A2 /* SecureIdValueFormFileItem.swift */; }; D0E412DF206AA00500BEE4A2 /* SecureIdVerificationDocumentsContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E412DE206AA00500BEE4A2 /* SecureIdVerificationDocumentsContext.swift */; }; - D0E817472010E62F00B82BBB /* MergeLists.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E817462010E62E00B82BBB /* MergeLists.swift */; }; D0E8174C2011F8A300B82BBB /* ChatMessageEventLogPreviousMessageContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E8174B2011F8A300B82BBB /* ChatMessageEventLogPreviousMessageContentNode.swift */; }; D0E8174E2011FC3800B82BBB /* ChatMessageEventLogPreviousDescriptionContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E8174D2011FC3800B82BBB /* ChatMessageEventLogPreviousDescriptionContentNode.swift */; }; D0E817502012027900B82BBB /* ChatMessageEventLogPreviousLinkContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E8174F2012027900B82BBB /* ChatMessageEventLogPreviousLinkContentNode.swift */; }; @@ -837,20 +830,10 @@ D0EC6CCD1EB9F58800EBF1C3 /* DeclareEncodables.swift in Sources */ = {isa = PBXBuildFile; fileRef = D073CE701DCBF23F007511FD /* DeclareEncodables.swift */; }; D0EC6CCE1EB9F58800EBF1C3 /* AccountContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05811931DD5F9380057C769 /* AccountContext.swift */; }; D0EC6CD11EB9F58800EBF1C3 /* UrlHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = D023836F1DDF0462004018B6 /* UrlHandling.swift */; }; - D0EC6CD31EB9F58800EBF1C3 /* GenerateTextEntities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F917B41E0DA396003687E6 /* GenerateTextEntities.swift */; }; - D0EC6CD41EB9F58800EBF1C3 /* StringWithAppliedEntities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D017494D1E1059570057C89A /* StringWithAppliedEntities.swift */; }; D0EC6CD51EB9F58800EBF1C3 /* StoredMessageFromSearchPeer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01749541E1082770057C89A /* StoredMessageFromSearchPeer.swift */; }; D0EC6CD71EB9F58800EBF1C3 /* EmojiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01D6BFB1E42AB3C006151C6 /* EmojiUtils.swift */; }; - D0EC6CD81EB9F58800EBF1C3 /* ShakeAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44551E4E7F43005FDCA7 /* ShakeAnimation.swift */; }; D0EC6CD91EB9F58800EBF1C3 /* ValidateAddressNameInteractive.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E305A41E5B2BFB00D7A3A2 /* ValidateAddressNameInteractive.swift */; }; - D0EC6CDB1EB9F58800EBF1C3 /* Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C2AAC1E768404001F6F9A /* Markdown.swift */; }; D0EC6CDC1EB9F58800EBF1C3 /* TelegramAccountAuxiliaryMethods.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3A8AA1E82D83E00B4C64C /* TelegramAccountAuxiliaryMethods.swift */; }; - D0EC6CDF1EB9F58800EBF1C3 /* PresentationResourceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05BFB5E1EAA22F900909D38 /* PresentationResourceKey.swift */; }; - D0EC6CE01EB9F58800EBF1C3 /* PresentationResourcesRootController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05174BD1EAE161C00A1BF36 /* PresentationResourcesRootController.swift */; }; - D0EC6CE11EB9F58800EBF1C3 /* PresentationResourcesItemList.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05174BB1EAE156500A1BF36 /* PresentationResourcesItemList.swift */; }; - D0EC6CE21EB9F58800EBF1C3 /* PresentationResourcesChatList.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03AADA81EAF931300D23738 /* PresentationResourcesChatList.swift */; }; - D0EC6CE31EB9F58800EBF1C3 /* PresentationResourcesChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06FFBA91EAFAD2500CB53D4 /* PresentationResourcesChat.swift */; }; - D0EC6CEC1EB9F58800EBF1C3 /* PresentationThemeEssentialGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06FFBA71EAFAC4F00CB53D4 /* PresentationThemeEssentialGraphics.swift */; }; D0EC6CF41EB9F58800EBF1C3 /* ManagedMediaId.swift in Sources */ = {isa = PBXBuildFile; fileRef = D099EA261DE765DB001AF5A8 /* ManagedMediaId.swift */; }; D0EC6CF51EB9F58800EBF1C3 /* PeerMessageManagedMediaId.swift in Sources */ = {isa = PBXBuildFile; fileRef = D099EA2C1DE76782001AF5A8 /* PeerMessageManagedMediaId.swift */; }; D0EC6CF61EB9F58800EBF1C3 /* ChatContextResultManagedMediaId.swift in Sources */ = {isa = PBXBuildFile; fileRef = D099EA2E1DE775BB001AF5A8 /* ChatContextResultManagedMediaId.swift */; }; @@ -896,7 +879,6 @@ D0EC6D3A1EB9F58800EBF1C3 /* AudioWaveformNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0568AAC1DF198130022E7DA /* AudioWaveformNode.swift */; }; D0EC6D3B1EB9F58800EBF1C3 /* EditableTokenListNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BC38621E3F9EFA0044D6FE /* EditableTokenListNode.swift */; }; D0EC6D3C1EB9F58800EBF1C3 /* PhoneInputNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D050F2121E48B61500988324 /* PhoneInputNode.swift */; }; - D0EC6D3D1EB9F58800EBF1C3 /* ProgressNavigationButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44531E4E7302005FDCA7 /* ProgressNavigationButtonNode.swift */; }; D0EC6D3E1EB9F58800EBF1C3 /* TelegramController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0736F241DF4D0E500F2C02A /* TelegramController.swift */; }; D0EC6D3F1EB9F58800EBF1C3 /* MediaNavigationAccessoryPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0736F291DF4D5FF00F2C02A /* MediaNavigationAccessoryPanel.swift */; }; D0EC6D401EB9F58800EBF1C3 /* MediaNavigationAccessoryContainerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0736F2B1DF4DC2400F2C02A /* MediaNavigationAccessoryContainerNode.swift */; }; @@ -986,7 +968,6 @@ D0EC6D9F1EB9F58900EBF1C3 /* ChatUnreadItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F69E2C1D6B8B030046BCD6 /* ChatUnreadItem.swift */; }; D0EC6DA01EB9F58900EBF1C3 /* ChatHoleItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F69E191D6B8AE60046BCD6 /* ChatHoleItem.swift */; }; D0EC6DA11EB9F58900EBF1C3 /* ChatMessageSelectionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D2686D1D7898A900C422DA /* ChatMessageSelectionNode.swift */; }; - D0EC6DA21EB9F58900EBF1C3 /* ChatMessageBubbleImages.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB341DCFADCD009AD9A1 /* ChatMessageBubbleImages.swift */; }; D0EC6DA31EB9F58900EBF1C3 /* ChatMessageDateHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB381DCFF87B009AD9A1 /* ChatMessageDateHeader.swift */; }; D0EC6DA41EB9F58900EBF1C3 /* ChatMessageActionButtonsNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC9171DD5033100E8160F /* ChatMessageActionButtonsNode.swift */; }; D0EC6DA51EB9F58900EBF1C3 /* ChatBotInfoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C932371E09E0EA0074F044 /* ChatBotInfoItem.swift */; }; @@ -1118,30 +1099,12 @@ D0EC6E311EB9F58900EBF1C3 /* ContactSelectionControllerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BC38801E40F1D80044D6FE /* ContactSelectionControllerNode.swift */; }; D0EC6E321EB9F58900EBF1C3 /* CreateGroupController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BC38691E3FB94D0044D6FE /* CreateGroupController.swift */; }; D0EC6E331EB9F58900EBF1C3 /* CreateChannelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D018D3341E6489EC00C5E089 /* CreateChannelController.swift */; }; - D0EC6E341EB9F58900EBF1C3 /* ItemListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D003702F1DA43077004308D3 /* ItemListItem.swift */; }; D0EC6E351EB9F58900EBF1C3 /* ItemListAvatarAndNameItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D003702D1DA43052004308D3 /* ItemListAvatarAndNameItem.swift */; }; - D0EC6E361EB9F58900EBF1C3 /* ItemListTextWithLabelItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00370311DA46C06004308D3 /* ItemListTextWithLabelItem.swift */; }; - D0EC6E371EB9F58900EBF1C3 /* ItemListActionItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03120F51DA534C1006A2A60 /* ItemListActionItem.swift */; }; - D0EC6E381EB9F58900EBF1C3 /* ItemListDisclosureItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843911DA7F13E005F29E1 /* ItemListDisclosureItem.swift */; }; - D0EC6E391EB9F58900EBF1C3 /* ItemListCheckboxItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08774F91E3E2A5600A97350 /* ItemListCheckboxItem.swift */; }; - D0EC6E3A1EB9F58900EBF1C3 /* ItemListSwitchItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00B3F9F1E3A76D4003872C3 /* ItemListSwitchItem.swift */; }; D0EC6E3B1EB9F58900EBF1C3 /* ItemListPeerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843D81DAAAA0C005F29E1 /* ItemListPeerItem.swift */; }; D0EC6E3C1EB9F58900EBF1C3 /* ItemListPeerActionItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843DA1DAAB138005F29E1 /* ItemListPeerActionItem.swift */; }; - D0EC6E3D1EB9F58900EBF1C3 /* ItemListMultilineInputItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00C7CD61E3664070080C3D5 /* ItemListMultilineInputItem.swift */; }; D0EC6E3E1EB9F58900EBF1C3 /* ItemListSectionHeaderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00B3F9D1E3A4847003872C3 /* ItemListSectionHeaderItem.swift */; }; - D0EC6E3F1EB9F58900EBF1C3 /* ItemListTextItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00B3FA11E3A983E003872C3 /* ItemListTextItem.swift */; }; - D0EC6E401EB9F58900EBF1C3 /* ItemListActivityTextItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0561DE01E57153000E6B9E9 /* ItemListActivityTextItem.swift */; }; - D0EC6E411EB9F58900EBF1C3 /* ItemListEditableItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D021E0A81E3AACA200AF709C /* ItemListEditableItem.swift */; }; - D0EC6E421EB9F58900EBF1C3 /* ItemListRevealOptionsNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D021E0AA1E3B9E2700AF709C /* ItemListRevealOptionsNode.swift */; }; - D0EC6E431EB9F58900EBF1C3 /* ItemListEditableDeleteControlNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08774F71E3DE7BF00A97350 /* ItemListEditableDeleteControlNode.swift */; }; D0EC6E441EB9F58900EBF1C3 /* ItemListSingleLineInputItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0561DDE1E56FE8200E6B9E9 /* ItemListSingleLineInputItem.swift */; }; - D0EC6E451EB9F58900EBF1C3 /* ItemListMultilineTextItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0561DE51E57424700E6B9E9 /* ItemListMultilineTextItem.swift */; }; - D0EC6E461EB9F58900EBF1C3 /* ItemListLoadingIndicatorEmptyStateItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E305AE1E5BA8E000D7A3A2 /* ItemListLoadingIndicatorEmptyStateItem.swift */; }; D0EC6E471EB9F58900EBF1C3 /* ItemListTextEmptyStateItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09AEFD31E5BAF67005C1A8B /* ItemListTextEmptyStateItem.swift */; }; - D0EC6E481EB9F58900EBF1C3 /* ItemListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01B27981E39144C0022A4C0 /* ItemListController.swift */; }; - D0EC6E491EB9F58900EBF1C3 /* ItemListControllerEmptyStateItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E305AC1E5BA3E700D7A3A2 /* ItemListControllerEmptyStateItem.swift */; }; - D0EC6E4A1EB9F58900EBF1C3 /* ItemListControllerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01B27941E38F3BF0022A4C0 /* ItemListControllerNode.swift */; }; - D0EC6E4B1EB9F58900EBF1C3 /* ItemListControllerSegmentedTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA34FE1EA5834C00E56FFA /* ItemListControllerSegmentedTitleView.swift */; }; D0EC6E4D1EB9F58900EBF1C3 /* PeerInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843CC1DA903BB005F29E1 /* PeerInfoController.swift */; }; D0EC6E4E1EB9F58900EBF1C3 /* GroupInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0486F091E523C8500091F0C /* GroupInfoController.swift */; }; D0EC6E4F1EB9F58900EBF1C3 /* ChannelVisibilityController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03E5E0E1E55F8B90029569A /* ChannelVisibilityController.swift */; }; @@ -1354,7 +1317,6 @@ 09CE95052236D47F00A7D2C3 /* SettingsSearchItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSearchItem.swift; sourceTree = ""; }; 09CE95072237A53900A7D2C3 /* SettingsSearchableItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSearchableItems.swift; sourceTree = ""; }; 09CE95092237B93500A7D2C3 /* SettingsSearchResultItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSearchResultItem.swift; sourceTree = ""; }; - 09CE950B2237D61B00A7D2C3 /* PresentationResourcesSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentationResourcesSettings.swift; sourceTree = ""; }; 09CE950D2237E45E00A7D2C3 /* CachedFaqInstantPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachedFaqInstantPage.swift; sourceTree = ""; }; 09CE95102237F3C100A7D2C3 /* SettingsSearchRecentQueries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSearchRecentQueries.swift; sourceTree = ""; }; 09CE9512223825B700A7D2C3 /* CustomWallpaperPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomWallpaperPicker.swift; sourceTree = ""; }; @@ -1382,14 +1344,11 @@ 09DE2F282269D5E30045E975 /* PrivacyIntroControllerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyIntroControllerNode.swift; sourceTree = ""; }; 09E2D9ED226F1AF300EA0AA4 /* Emoji.mapping */ = {isa = PBXFileReference; lastKnownFileType = file; name = Emoji.mapping; path = TelegramUI/Resources/Emoji.mapping; sourceTree = ""; }; 09E2D9F0226F214000EA0AA4 /* EmojiResources.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiResources.swift; sourceTree = ""; }; - 09E2DA102273340E00EA0AA4 /* AnimationNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationNode.swift; sourceTree = ""; }; 09E2DA122273367900EA0AA4 /* anim_archiveAvatar.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = anim_archiveAvatar.json; sourceTree = ""; }; 09E4A800223AE1B30038140F /* PeerType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerType.swift; sourceTree = ""; }; 09E4A802223B833B0038140F /* ForwardPrivacyChatPreviewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForwardPrivacyChatPreviewItem.swift; sourceTree = ""; }; 09E4A804223D4A5A0038140F /* OpenSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSettings.swift; sourceTree = ""; }; 09E4A806223D4B860038140F /* AccountUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountUtils.swift; sourceTree = ""; }; - 09EC0DE622C67FB100E7185B /* UpdateInfoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateInfoController.swift; sourceTree = ""; }; - 09EC0DEA22CAFF1400E7185B /* UpdateInfoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateInfoItem.swift; sourceTree = ""; }; 09EC0DEC22CB583C00E7185B /* TextLinkHandling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLinkHandling.swift; sourceTree = ""; }; 09EC5CDB22CBD33D00292E42 /* NumberFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberFormat.swift; sourceTree = ""; }; 09EDAD25220D30980012A50B /* AutodownloadConnectionTypeController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutodownloadConnectionTypeController.swift; sourceTree = ""; }; @@ -1444,8 +1403,6 @@ D002A0DA1E9C190700A81812 /* SoftwareVideoThumbnailLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SoftwareVideoThumbnailLayer.swift; sourceTree = ""; }; D002A0DC1E9CD52A00A81812 /* ChatMediaInputRecentGifsItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMediaInputRecentGifsItem.swift; sourceTree = ""; }; D003702D1DA43052004308D3 /* ItemListAvatarAndNameItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListAvatarAndNameItem.swift; sourceTree = ""; }; - D003702F1DA43077004308D3 /* ItemListItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListItem.swift; sourceTree = ""; }; - D00370311DA46C06004308D3 /* ItemListTextWithLabelItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListTextWithLabelItem.swift; sourceTree = ""; }; D00580B221E4B51600CB7CD3 /* DeleteChatPeerActionSheetItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteChatPeerActionSheetItem.swift; sourceTree = ""; }; D00580B521E4C02100CB7CD3 /* UndoOverlayController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UndoOverlayController.swift; sourceTree = ""; }; D00580B721E4C03400CB7CD3 /* UndoOverlayControllerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UndoOverlayControllerNode.swift; sourceTree = ""; }; @@ -1494,12 +1451,9 @@ D00ACA592022897D0045D427 /* ProcessedPeerRestrictionText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessedPeerRestrictionText.swift; sourceTree = ""; }; D00ADFDC1EBB73C200873D2E /* OverlayMediaManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverlayMediaManager.swift; sourceTree = ""; }; D00B3F9D1E3A4847003872C3 /* ItemListSectionHeaderItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListSectionHeaderItem.swift; sourceTree = ""; }; - D00B3F9F1E3A76D4003872C3 /* ItemListSwitchItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListSwitchItem.swift; sourceTree = ""; }; - D00B3FA11E3A983E003872C3 /* ItemListTextItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListTextItem.swift; sourceTree = ""; }; D00BDA1E1EE5B69200C64C5E /* ChannelAdminController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelAdminController.swift; sourceTree = ""; }; D00BED1F1F73F60F00922292 /* ShareSearchContainerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareSearchContainerNode.swift; sourceTree = ""; }; D00BED211F73F82400922292 /* SharePeersContainerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharePeersContainerNode.swift; sourceTree = ""; }; - D00C7CD61E3664070080C3D5 /* ItemListMultilineInputItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListMultilineInputItem.swift; sourceTree = ""; }; D00C7CD81E36B2DB0080C3D5 /* ContactListNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactListNode.swift; sourceTree = ""; }; D00C7CDB1E3776E50080C3D5 /* SecretMediaPreviewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecretMediaPreviewController.swift; sourceTree = ""; }; D00C7CE51E378FD00080C3D5 /* RadialTimeoutNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadialTimeoutNode.swift; sourceTree = ""; }; @@ -1544,7 +1498,6 @@ D01590C522BE61CB0017C33E /* TextureCompression.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = TextureCompression.cpp; path = "../third-party/bc1/TextureCompression.cpp"; sourceTree = ""; }; D01590C822BE62C40017C33E /* TextureCompression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextureCompression.h; path = "third-party/bc1/TextureCompression.h"; sourceTree = SOURCE_ROOT; }; D015E04E225D2E5900CB9E8A /* WebP.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WebP.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D017494D1E1059570057C89A /* StringWithAppliedEntities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringWithAppliedEntities.swift; sourceTree = ""; }; D01749501E1067E40057C89A /* HashtagSearchController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HashtagSearchController.swift; sourceTree = ""; }; D01749521E1068820057C89A /* HashtagSearchControllerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HashtagSearchControllerNode.swift; sourceTree = ""; }; D01749541E1082770057C89A /* StoredMessageFromSearchPeer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoredMessageFromSearchPeer.swift; sourceTree = ""; }; @@ -1573,8 +1526,6 @@ D01A21B01F3A050E00DDA104 /* InstantPageNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstantPageNavigationBar.swift; sourceTree = ""; }; D01AC9171DD5033100E8160F /* ChatMessageActionButtonsNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessageActionButtonsNode.swift; sourceTree = ""; }; D01AC91E1DD5E09000E8160F /* EditAccessoryPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditAccessoryPanelNode.swift; sourceTree = ""; }; - D01B27941E38F3BF0022A4C0 /* ItemListControllerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListControllerNode.swift; sourceTree = ""; }; - D01B27981E39144C0022A4C0 /* ItemListController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListController.swift; sourceTree = ""; }; D01B279A1E39386C0022A4C0 /* SettingsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = ""; }; D01B279C1E394A500022A4C0 /* NotificationsAndSounds.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationsAndSounds.swift; sourceTree = ""; }; D01BAA171ECC8E0000295217 /* CallListController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallListController.swift; sourceTree = ""; }; @@ -1583,19 +1534,15 @@ D01BAA1D1ECC931D00295217 /* CallListNodeEntries.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallListNodeEntries.swift; sourceTree = ""; }; D01BAA1F1ECC9A2500295217 /* CallListNodeLocation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallListNodeLocation.swift; sourceTree = ""; }; D01BAA211ECE076100295217 /* CallListCallItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallListCallItem.swift; sourceTree = ""; }; - D01BAA231ECE173200295217 /* PresentationResourcesCallList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesCallList.swift; sourceTree = ""; }; D01BAA571ED3283D00295217 /* AddFormatToStringWithRanges.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddFormatToStringWithRanges.swift; sourceTree = ""; }; D01C06AE1FBB461E001561AB /* JoinLinkPreviewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinLinkPreviewController.swift; sourceTree = ""; }; D01C06B01FBB4643001561AB /* JoinLinkPreviewControllerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinLinkPreviewControllerNode.swift; sourceTree = ""; }; D01C06B21FBB49A5001561AB /* JoinLinkPreviewPeerContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinLinkPreviewPeerContentNode.swift; sourceTree = ""; }; D01C06B41FBB7720001561AB /* ChatMediaInputSettingsItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMediaInputSettingsItem.swift; sourceTree = ""; }; - D01C06B91FBBB076001561AB /* ItemListSelectableControlNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListSelectableControlNode.swift; sourceTree = ""; }; - D01C06BB1FBBB0D8001561AB /* CheckNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckNode.swift; sourceTree = ""; }; D01C06BD1FBCAF06001561AB /* ChatMessageBubbleMosaicLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageBubbleMosaicLayout.swift; sourceTree = ""; }; D01C06BF1FBF118A001561AB /* MessageUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageUtils.swift; sourceTree = ""; }; D01C2AA01E758F90001F6F9A /* NavigateToChatController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigateToChatController.swift; sourceTree = ""; }; D01C2AAA1E75E010001F6F9A /* TwoStepVerificationUnlockController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoStepVerificationUnlockController.swift; sourceTree = ""; }; - D01C2AAC1E768404001F6F9A /* Markdown.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Markdown.swift; sourceTree = ""; }; D01C99771F4F382C00DCFAF6 /* InstantPageSettingsItemTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstantPageSettingsItemTheme.swift; sourceTree = ""; }; D01D6BFB1E42AB3C006151C6 /* EmojiUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmojiUtils.swift; sourceTree = ""; }; D01DBA9A209CC6AD00C64E64 /* ChatLinkPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatLinkPreview.swift; sourceTree = ""; }; @@ -1626,8 +1573,6 @@ D0215D551E043020001A0B1E /* InstantPageControllerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstantPageControllerNode.swift; sourceTree = ""; }; D0215D571E04302E001A0B1E /* InstantPageTileNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstantPageTileNode.swift; sourceTree = ""; }; D0215D591E04310C001A0B1E /* InstantPageTile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstantPageTile.swift; sourceTree = ""; }; - D021E0A81E3AACA200AF709C /* ItemListEditableItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListEditableItem.swift; sourceTree = ""; }; - D021E0AA1E3B9E2700AF709C /* ItemListRevealOptionsNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListRevealOptionsNode.swift; sourceTree = ""; }; D021E0CD1DB4135500C6B04F /* ChatMediaInputNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMediaInputNode.swift; sourceTree = ""; }; D021E0CF1DB413BC00C6B04F /* ChatInputNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatInputNode.swift; sourceTree = ""; }; D021E0D11DB4147500C6B04F /* ChatInterfaceInputNodes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatInterfaceInputNodes.swift; sourceTree = ""; }; @@ -1669,7 +1614,6 @@ D02DADBE2138D76F00116225 /* Vision.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vision.framework; path = System/Library/Frameworks/Vision.framework; sourceTree = SDKROOT; }; D02F4AE81FCF370B004DFBAE /* ChatMessageInteractiveMediaBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageInteractiveMediaBadge.swift; sourceTree = ""; }; D02F4AEF1FD4C46D004DFBAE /* SystemVideoContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemVideoContent.swift; sourceTree = ""; }; - D03120F51DA534C1006A2A60 /* ItemListActionItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListActionItem.swift; sourceTree = ""; }; D035734A22B5CCCA00F0920D /* LegacyBuffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyBuffer.swift; sourceTree = ""; }; D0380DA8204E9C81000414AB /* SecretMediaPreviewFooterContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretMediaPreviewFooterContentNode.swift; sourceTree = ""; }; D0380DAA204EA72F000414AB /* RadialStatusSecretTimeoutContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadialStatusSecretTimeoutContentNode.swift; sourceTree = ""; }; @@ -1685,8 +1629,6 @@ D039FB1821711B5D00BD1BAD /* PlatformVideoContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformVideoContent.swift; sourceTree = ""; }; D03AA4DE202DBF6F0056C405 /* ChatContextResultPeekContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatContextResultPeekContentNode.swift; sourceTree = ""; }; D03AA4E4202DF8840056C405 /* StickerPreviewPeekContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerPreviewPeekContent.swift; sourceTree = ""; }; - D03AA4E6202DFB160056C405 /* ItemListEditableReorderControlNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListEditableReorderControlNode.swift; sourceTree = ""; }; - D03AADA81EAF931300D23738 /* PresentationResourcesChatList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesChatList.swift; sourceTree = ""; }; D03ADB471D703268005A521C /* ChatInterfaceState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatInterfaceState.swift; sourceTree = ""; }; D03ADB4A1D70443F005A521C /* ReplyAccessoryPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplyAccessoryPanelNode.swift; sourceTree = ""; }; D03ADB4C1D7045C9005A521C /* ChatInterfaceStateAccessoryPanels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatInterfaceStateAccessoryPanels.swift; sourceTree = ""; }; @@ -1696,7 +1638,6 @@ D03E5E081E55C49C0029569A /* DebugAccountsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugAccountsController.swift; sourceTree = ""; }; D03E5E0E1E55F8B90029569A /* ChannelVisibilityController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelVisibilityController.swift; sourceTree = ""; }; D04203142037162700490EA5 /* MediaInputPaneTrendingItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaInputPaneTrendingItem.swift; sourceTree = ""; }; - D04281EC200E3B28009DDE36 /* ItemListControllerSearch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListControllerSearch.swift; sourceTree = ""; }; D04281EE200E3D88009DDE36 /* GroupInfoSearchItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupInfoSearchItem.swift; sourceTree = ""; }; D04281F0200E4084009DDE36 /* GroupInfoSearchNavigationContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupInfoSearchNavigationContentNode.swift; sourceTree = ""; }; D04281F3200E5AB0009DDE36 /* ChatRecentActionsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRecentActionsController.swift; sourceTree = ""; }; @@ -1769,8 +1710,6 @@ D050F2151E48D9E000988324 /* AuthorizationSequenceCountrySelectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthorizationSequenceCountrySelectionController.swift; sourceTree = ""; }; D050F2171E48D9EA00988324 /* AuthorizationSequenceCountrySelectionControllerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthorizationSequenceCountrySelectionControllerNode.swift; sourceTree = ""; }; D05174AA1EAA5B4700A1BF36 /* WallpaperGalleryToolbarNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WallpaperGalleryToolbarNode.swift; sourceTree = ""; }; - D05174BB1EAE156500A1BF36 /* PresentationResourcesItemList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesItemList.swift; sourceTree = ""; }; - D05174BD1EAE161C00A1BF36 /* PresentationResourcesRootController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesRootController.swift; sourceTree = ""; }; D05174C21EAE583800A1BF36 /* TelegramRootController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TelegramRootController.swift; sourceTree = ""; }; D0528E551E65750600E2FEF5 /* SecretChatHandshakeStatusInputPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecretChatHandshakeStatusInputPanelNode.swift; sourceTree = ""; }; D0528E571E65773300E2FEF5 /* DeleteChatInputPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeleteChatInputPanelNode.swift; sourceTree = ""; }; @@ -1778,11 +1717,8 @@ D0528E671E65CB2C00E2FEF5 /* UsernameSetupController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UsernameSetupController.swift; sourceTree = ""; }; D0528E6C1E65DE3B00E2FEF5 /* WebpagePreviewAccessoryPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebpagePreviewAccessoryPanelNode.swift; sourceTree = ""; }; D053B4361F1A9CA000E2D58A /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - D053DAD9201A4C4400993D32 /* ChatTextInputAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTextInputAttributes.swift; sourceTree = ""; }; D053DADB201AAAB100993D32 /* ChatTextInputMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTextInputMenu.swift; sourceTree = ""; }; D0561DDE1E56FE8200E6B9E9 /* ItemListSingleLineInputItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListSingleLineInputItem.swift; sourceTree = ""; }; - D0561DE01E57153000E6B9E9 /* ItemListActivityTextItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListActivityTextItem.swift; sourceTree = ""; }; - D0561DE51E57424700E6B9E9 /* ItemListMultilineTextItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListMultilineTextItem.swift; sourceTree = ""; }; D0561DE71E574C3200E6B9E9 /* ChannelAdminsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelAdminsController.swift; sourceTree = ""; }; D05677501F4CA0C2001B723E /* InstantPagePeerReferenceItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstantPagePeerReferenceItem.swift; sourceTree = ""; }; D05677521F4CA0D0001B723E /* InstantPagePeerReferenceNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstantPagePeerReferenceNode.swift; sourceTree = ""; }; @@ -1807,13 +1743,17 @@ D05B077121BFB9F600B1D27C /* FFMpeg.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = FFMpeg.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D05B077321BFC38600B1D27C /* FFMpeg.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = FFMpeg.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D05B724C1E720393000BD3AD /* SelectivePrivacySettingsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectivePrivacySettingsController.swift; sourceTree = ""; }; - D05BFB5E1EAA22F900909D38 /* PresentationResourceKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourceKey.swift; sourceTree = ""; }; D05D8B392192FC460064586F /* LocalizationListController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationListController.swift; sourceTree = ""; }; D05D8B3E2192FC6E0064586F /* LocalizationListControllerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationListControllerNode.swift; sourceTree = ""; }; D05D8B402192FC8A0064586F /* LocalizationListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationListItem.swift; sourceTree = ""; }; D05D8B732195CD890064586F /* SetupTwoStepVerificationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupTwoStepVerificationController.swift; sourceTree = ""; }; D05D8B752195CD930064586F /* SetupTwoStepVerificationControllerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupTwoStepVerificationControllerNode.swift; sourceTree = ""; }; D05D8B772195E0050064586F /* SetupTwoStepVerificationContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupTwoStepVerificationContentNode.swift; sourceTree = ""; }; + D060183F22F35D1C00796784 /* MergeLists.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MergeLists.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060184122F35D2000796784 /* ActivityIndicator.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = ActivityIndicator.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060184322F35D2400796784 /* ProgressNavigationButtonNode.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = ProgressNavigationButtonNode.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D060184522F35D2B00796784 /* ItemListUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = ItemListUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D06018B422F3659900796784 /* ChatTextFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTextFormat.swift; sourceTree = ""; }; D0613FC71E5F8AB100202CDB /* ChannelInfoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelInfoController.swift; sourceTree = ""; }; D0613FCC1E60482300202CDB /* ChannelMembersController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelMembersController.swift; sourceTree = ""; }; D0613FD41E6064D200202CDB /* ConvertToSupergroupController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConvertToSupergroupController.swift; sourceTree = ""; }; @@ -1840,8 +1780,6 @@ D06F1EA31F6C0A5D00FE8B74 /* ChatHistorySearchContainerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatHistorySearchContainerNode.swift; sourceTree = ""; }; D06F31E3213597FF001A0F12 /* ThemeAutoNightTimeSelectionActionSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeAutoNightTimeSelectionActionSheet.swift; sourceTree = ""; }; D06F31E52135A41C001A0F12 /* ThemeSettingsBrightnessItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeSettingsBrightnessItem.swift; sourceTree = ""; }; - D06FFBA71EAFAC4F00CB53D4 /* PresentationThemeEssentialGraphics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationThemeEssentialGraphics.swift; sourceTree = ""; }; - D06FFBA91EAFAD2500CB53D4 /* PresentationResourcesChat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationResourcesChat.swift; sourceTree = ""; }; D0736F241DF4D0E500F2C02A /* TelegramController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TelegramController.swift; sourceTree = ""; }; D0736F291DF4D5FF00F2C02A /* MediaNavigationAccessoryPanel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaNavigationAccessoryPanel.swift; sourceTree = ""; }; D0736F2B1DF4DC2400F2C02A /* MediaNavigationAccessoryContainerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaNavigationAccessoryContainerNode.swift; sourceTree = ""; }; @@ -1899,8 +1837,6 @@ D083491B209361DC008CFD52 /* AvatarGalleryItemFooterContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarGalleryItemFooterContentNode.swift; sourceTree = ""; }; D084023320E295F000065674 /* GroupStickerPackSetupController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupStickerPackSetupController.swift; sourceTree = ""; }; D08557E622C5FEB90026D6D2 /* AnimatedStickerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedStickerNode.swift; sourceTree = ""; }; - D08774F71E3DE7BF00A97350 /* ItemListEditableDeleteControlNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListEditableDeleteControlNode.swift; sourceTree = ""; }; - D08774F91E3E2A5600A97350 /* ItemListCheckboxItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListCheckboxItem.swift; sourceTree = ""; }; D08775081E3E59DE00A97350 /* PeerNotificationSoundStrings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerNotificationSoundStrings.swift; sourceTree = ""; }; D087750F1E3F46A400A97350 /* ComposeController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComposeController.swift; sourceTree = ""; }; D08775111E3F46AB00A97350 /* ComposeControllerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComposeControllerNode.swift; sourceTree = ""; }; @@ -2066,7 +2002,6 @@ D0B69C3820EBB397003632C7 /* ChatMessageInteractiveInstantVideoNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageInteractiveInstantVideoNode.swift; sourceTree = ""; }; D0B7F8E11D8A18070045D939 /* PeerMediaCollectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerMediaCollectionController.swift; sourceTree = ""; }; D0B7F8E71D8A1F5F0045D939 /* PeerMediaCollectionControllerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerMediaCollectionControllerNode.swift; sourceTree = ""; }; - D0B843911DA7F13E005F29E1 /* ItemListDisclosureItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListDisclosureItem.swift; sourceTree = ""; }; D0B843CC1DA903BB005F29E1 /* PeerInfoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerInfoController.swift; sourceTree = ""; }; D0B843D81DAAAA0C005F29E1 /* ItemListPeerItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListPeerItem.swift; sourceTree = ""; }; D0B843DA1DAAB138005F29E1 /* ItemListPeerActionItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListPeerActionItem.swift; sourceTree = ""; }; @@ -2100,9 +2035,7 @@ D0BFAE4520AB04FB00793CF2 /* ChatRestrictedInputPanelNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRestrictedInputPanelNode.swift; sourceTree = ""; }; D0BFAE4D20AB1D7B00793CF2 /* DisabledContextResultsChatInputContextPanelNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisabledContextResultsChatInputContextPanelNode.swift; sourceTree = ""; }; D0BFAE4F20AB2A1300793CF2 /* PeerBanTimeoutController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerBanTimeoutController.swift; sourceTree = ""; }; - D0BFAE5A20AB35D200793CF2 /* IconSwitchNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconSwitchNode.swift; sourceTree = ""; }; D0BFAE5C20AB426300793CF2 /* PeerTitle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerTitle.swift; sourceTree = ""; }; - D0C0B58F1EDB505E000F4D2C /* ActivityIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityIndicator.swift; sourceTree = ""; }; D0C0B59A1EE019E5000F4D2C /* ChatSearchNavigationContentNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatSearchNavigationContentNode.swift; sourceTree = ""; }; D0C0B59E1EE082F5000F4D2C /* ChatSearchInputPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatSearchInputPanelNode.swift; sourceTree = ""; }; D0C0B5B01EE1C421000F4D2C /* ChatDateSelectionSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatDateSelectionSheet.swift; sourceTree = ""; }; @@ -2177,13 +2110,12 @@ D0D2686B1D788F8200C422DA /* ChatTitleAccessoryPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatTitleAccessoryPanelNode.swift; sourceTree = ""; }; D0D2686D1D7898A900C422DA /* ChatMessageSelectionNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessageSelectionNode.swift; sourceTree = ""; }; D0D268991D79CF9F00C422DA /* ChatPanelInterfaceInteraction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatPanelInterfaceInteraction.swift; sourceTree = ""; }; + D0D3281322F31B3000D07EE2 /* TelegramUpdateUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TelegramUpdateUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0D4345B1F97CEAA00CC1806 /* ProxyServerSettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProxyServerSettingsController.swift; sourceTree = ""; }; D0D748051E7AF63800F4B1F6 /* StickerPackPreviewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerPackPreviewController.swift; sourceTree = ""; }; D0D748071E7AF64400F4B1F6 /* StickerPackPreviewControllerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerPackPreviewControllerNode.swift; sourceTree = ""; }; D0D7480E1E7B1BD600F4B1F6 /* StickerPackPreviewGridItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerPackPreviewGridItem.swift; sourceTree = ""; }; D0D9DE0C20EFEA2E00F20B06 /* InstantPageMediaPlaylist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstantPageMediaPlaylist.swift; sourceTree = ""; }; - D0DA44531E4E7302005FDCA7 /* ProgressNavigationButtonNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressNavigationButtonNode.swift; sourceTree = ""; }; - D0DA44551E4E7F43005FDCA7 /* ShakeAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShakeAnimation.swift; sourceTree = ""; }; D0DC35431DE32230000195EB /* ChatInterfaceStateContextQueries.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatInterfaceStateContextQueries.swift; sourceTree = ""; }; D0DC35451DE35805000195EB /* MentionChatInputPanelItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MentionChatInputPanelItem.swift; sourceTree = ""; }; D0DC35491DE366CD000195EB /* CommandChatInputContextPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandChatInputContextPanelNode.swift; sourceTree = ""; }; @@ -2214,8 +2146,6 @@ D0E266FC1F66706500BFC79F /* ChatBubbleVideoDecoration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatBubbleVideoDecoration.swift; sourceTree = ""; }; D0E2CE6B222930540084E3DD /* PrefetchManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefetchManager.swift; sourceTree = ""; }; D0E305A41E5B2BFB00D7A3A2 /* ValidateAddressNameInteractive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidateAddressNameInteractive.swift; sourceTree = ""; }; - D0E305AC1E5BA3E700D7A3A2 /* ItemListControllerEmptyStateItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListControllerEmptyStateItem.swift; sourceTree = ""; }; - D0E305AE1E5BA8E000D7A3A2 /* ItemListLoadingIndicatorEmptyStateItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListLoadingIndicatorEmptyStateItem.swift; sourceTree = ""; }; D0E35A061DE4803400BC6096 /* VerticalListContextResultsChatInputContextPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticalListContextResultsChatInputContextPanelNode.swift; sourceTree = ""; }; D0E35A081DE4804900BC6096 /* VerticalListContextResultsChatInputPanelItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticalListContextResultsChatInputPanelItem.swift; sourceTree = ""; }; D0E412C52069B60600BEE4A2 /* FormControllerHeaderItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormControllerHeaderItem.swift; sourceTree = ""; }; @@ -2232,7 +2162,6 @@ D0E7A1BE1D8C24B900C37A6F /* ChatHistoryViewForLocation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatHistoryViewForLocation.swift; sourceTree = ""; }; D0E7A1C01D8C258D00C37A6F /* ChatHistoryEntriesForView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatHistoryEntriesForView.swift; sourceTree = ""; }; D0E7A1C21D8C25D600C37A6F /* PreparedChatHistoryViewTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreparedChatHistoryViewTransition.swift; sourceTree = ""; }; - D0E817462010E62E00B82BBB /* MergeLists.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MergeLists.swift; sourceTree = ""; }; D0E8174B2011F8A300B82BBB /* ChatMessageEventLogPreviousMessageContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageEventLogPreviousMessageContentNode.swift; sourceTree = ""; }; D0E8174D2011FC3800B82BBB /* ChatMessageEventLogPreviousDescriptionContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageEventLogPreviousDescriptionContentNode.swift; sourceTree = ""; }; D0E8174F2012027900B82BBB /* ChatMessageEventLogPreviousLinkContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageEventLogPreviousLinkContentNode.swift; sourceTree = ""; }; @@ -2480,9 +2409,7 @@ D0F69EAB1D6B9BCB0046BCD6 /* libswresample.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswresample.a; path = "third-party/FFmpeg-iOS/lib/libswresample.a"; sourceTree = ""; }; D0F760DA222034910074F7E5 /* ChannelStatsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelStatsController.swift; sourceTree = ""; }; D0F760DC222034980074F7E5 /* ChannelStatsControllerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelStatsControllerNode.swift; sourceTree = ""; }; - D0F7AB341DCFADCD009AD9A1 /* ChatMessageBubbleImages.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessageBubbleImages.swift; sourceTree = ""; }; D0F7AB381DCFF87B009AD9A1 /* ChatMessageDateHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessageDateHeader.swift; sourceTree = ""; }; - D0F917B41E0DA396003687E6 /* GenerateTextEntities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateTextEntities.swift; sourceTree = ""; }; D0FA08BD20481EA300DD23FC /* Locale.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Locale.swift; sourceTree = ""; }; D0FA08BF20483F9600DD23FC /* ExtractVideoData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtractVideoData.swift; sourceTree = ""; }; D0FA08C7204982DC00DD23FC /* ChatTextInputActionButtonsNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTextInputActionButtonsNode.swift; sourceTree = ""; }; @@ -2490,7 +2417,6 @@ D0FA0ABE1E76E17F005BB9B7 /* TwoStepVerificationPasswordEntryController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoStepVerificationPasswordEntryController.swift; sourceTree = ""; }; D0FA0AC01E7725AA005BB9B7 /* TwoStepVerificationResetController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoStepVerificationResetController.swift; sourceTree = ""; }; D0FA0AC41E77431A005BB9B7 /* InstalledStickerPacksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstalledStickerPacksController.swift; sourceTree = ""; }; - D0FA34FE1EA5834C00E56FFA /* ItemListControllerSegmentedTitleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListControllerSegmentedTitleView.swift; sourceTree = ""; }; D0FA35001EA6127000E56FFA /* StorageUsageController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorageUsageController.swift; sourceTree = ""; }; D0FB87B11F7C4C19004DE005 /* FetchMediaUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchMediaUtils.swift; sourceTree = ""; }; D0FBE84E2273395C00B33B52 /* ChatListArchiveInfoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListArchiveInfoItem.swift; sourceTree = ""; }; @@ -2513,6 +2439,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D060184622F35D2B00796784 /* ItemListUI.framework in Frameworks */, + D060184422F35D2400796784 /* ProgressNavigationButtonNode.framework in Frameworks */, + D060184222F35D2000796784 /* ActivityIndicator.framework in Frameworks */, + D060184022F35D1C00796784 /* MergeLists.framework in Frameworks */, + D0D3281422F31B3000D07EE2 /* TelegramUpdateUI.framework in Frameworks */, D010E17D22C238BC009324D4 /* RLottie.framework in Frameworks */, D03AE67522B945D30078411C /* BuildConfig.framework in Frameworks */, D03AE67322B9459C0078411C /* HockeySDK.framework in Frameworks */, @@ -2793,20 +2724,10 @@ children = ( D0192D45210F4F940005FA10 /* FixSearchableListNodeScrolling.swift */, D0FE4DDB1F09AD0400E8A0B3 /* PresentationSurfaceLevels.swift */, - D0DA44551E4E7F43005FDCA7 /* ShakeAnimation.swift */, ); name = UI; sourceTree = ""; }; - 09EC0DE522C67F8900E7185B /* Update */ = { - isa = PBXGroup; - children = ( - 09EC0DE622C67FB100E7185B /* UpdateInfoController.swift */, - 09EC0DEA22CAFF1400E7185B /* UpdateInfoItem.swift */, - ); - name = Update; - sourceTree = ""; - }; 09F215982263E61400AEDF6D /* Passcode */ = { isa = PBXGroup; children = ( @@ -2984,12 +2905,10 @@ D0C26D5D1FDF49E7004ABF18 /* DateFormat.swift */, D0BCC3D1203F0A6C008126C2 /* StringForMessageTimestampStatus.swift */, D00ACA592022897D0045D427 /* ProcessedPeerRestrictionText.swift */, - D017494D1E1059570057C89A /* StringWithAppliedEntities.swift */, 09C9EA3721A044B500E90146 /* StringForDuration.swift */, D01D6BFB1E42AB3C006151C6 /* EmojiUtils.swift */, D08775081E3E59DE00A97350 /* PeerNotificationSoundStrings.swift */, D01BAA571ED3283D00295217 /* AddFormatToStringWithRanges.swift */, - D01C2AAC1E768404001F6F9A /* Markdown.swift */, D064EF861F69A06F00AC0398 /* MessageContentKind.swift */, D0471B501EFD872F0074D609 /* CurrencyFormat.swift */, 0900678E21ED8E0E00530762 /* HexColor.swift */, @@ -3011,11 +2930,6 @@ D01B27931E38F3920022A4C0 /* Item List */ = { isa = PBXGroup; children = ( - D01B27981E39144C0022A4C0 /* ItemListController.swift */, - D0E305AC1E5BA3E700D7A3A2 /* ItemListControllerEmptyStateItem.swift */, - D01B27941E38F3BF0022A4C0 /* ItemListControllerNode.swift */, - D0FA34FE1EA5834C00E56FFA /* ItemListControllerSegmentedTitleView.swift */, - D04281EC200E3B28009DDE36 /* ItemListControllerSearch.swift */, D0E6521D1E3A2305004EEA91 /* Items */, ); name = "Item List"; @@ -3403,20 +3317,6 @@ name = Themes; sourceTree = ""; }; - D05BFB5C1EAA22E200909D38 /* Resources */ = { - isa = PBXGroup; - children = ( - D05BFB5E1EAA22F900909D38 /* PresentationResourceKey.swift */, - D05174BD1EAE161C00A1BF36 /* PresentationResourcesRootController.swift */, - D05174BB1EAE156500A1BF36 /* PresentationResourcesItemList.swift */, - D03AADA81EAF931300D23738 /* PresentationResourcesChatList.swift */, - D06FFBA91EAFAD2500CB53D4 /* PresentationResourcesChat.swift */, - D01BAA231ECE173200295217 /* PresentationResourcesCallList.swift */, - 09CE950B2237D61B00A7D2C3 /* PresentationResourcesSettings.swift */, - ); - name = Resources; - sourceTree = ""; - }; D05D8B792195E00C0064586F /* Setup Two Step Verification */ = { isa = PBXGroup; children = ( @@ -3647,6 +3547,11 @@ D08D45281D5E340200A7428A /* Frameworks */ = { isa = PBXGroup; children = ( + D060184522F35D2B00796784 /* ItemListUI.framework */, + D060184322F35D2400796784 /* ProgressNavigationButtonNode.framework */, + D060184122F35D2000796784 /* ActivityIndicator.framework */, + D060183F22F35D1C00796784 /* MergeLists.framework */, + D0D3281322F31B3000D07EE2 /* TelegramUpdateUI.framework */, D010E17C22C238BC009324D4 /* RLottie.framework */, D03AE67422B945D30078411C /* BuildConfig.framework */, D03AE67222B9459C0078411C /* HockeySDK.framework */, @@ -3733,15 +3638,6 @@ name = Form; sourceTree = ""; }; - D096A4601EA681720000A7AE /* Presentation Data */ = { - isa = PBXGroup; - children = ( - D05BFB5C1EAA22E200909D38 /* Resources */, - D06FFBA71EAFAC4F00CB53D4 /* PresentationThemeEssentialGraphics.swift */, - ); - name = "Presentation Data"; - sourceTree = ""; - }; D099D74B1EEFEE0100A3128C /* Game */ = { isa = PBXGroup; children = ( @@ -4246,29 +4142,12 @@ D0E6521D1E3A2305004EEA91 /* Items */ = { isa = PBXGroup; children = ( - D003702F1DA43077004308D3 /* ItemListItem.swift */, D003702D1DA43052004308D3 /* ItemListAvatarAndNameItem.swift */, - D00370311DA46C06004308D3 /* ItemListTextWithLabelItem.swift */, - D03120F51DA534C1006A2A60 /* ItemListActionItem.swift */, - D0B843911DA7F13E005F29E1 /* ItemListDisclosureItem.swift */, - D08774F91E3E2A5600A97350 /* ItemListCheckboxItem.swift */, - D00B3F9F1E3A76D4003872C3 /* ItemListSwitchItem.swift */, D0B843D81DAAAA0C005F29E1 /* ItemListPeerItem.swift */, D0B843DA1DAAB138005F29E1 /* ItemListPeerActionItem.swift */, - D00C7CD61E3664070080C3D5 /* ItemListMultilineInputItem.swift */, D00B3F9D1E3A4847003872C3 /* ItemListSectionHeaderItem.swift */, - D00B3FA11E3A983E003872C3 /* ItemListTextItem.swift */, - D0561DE01E57153000E6B9E9 /* ItemListActivityTextItem.swift */, - D021E0A81E3AACA200AF709C /* ItemListEditableItem.swift */, - D021E0AA1E3B9E2700AF709C /* ItemListRevealOptionsNode.swift */, - D08774F71E3DE7BF00A97350 /* ItemListEditableDeleteControlNode.swift */, - D03AA4E6202DFB160056C405 /* ItemListEditableReorderControlNode.swift */, - D01C06B91FBBB076001561AB /* ItemListSelectableControlNode.swift */, D0561DDE1E56FE8200E6B9E9 /* ItemListSingleLineInputItem.swift */, - D0561DE51E57424700E6B9E9 /* ItemListMultilineTextItem.swift */, - D0E305AE1E5BA8E000D7A3A2 /* ItemListLoadingIndicatorEmptyStateItem.swift */, D09AEFD31E5BAF67005C1A8B /* ItemListTextEmptyStateItem.swift */, - D0BFAE5A20AB35D200793CF2 /* IconSwitchNode.swift */, 09B4EE5521A8149C00847FA6 /* ItemListInfoItem.swift */, ); name = Items; @@ -4565,16 +4444,12 @@ D0BC38621E3F9EFA0044D6FE /* EditableTokenListNode.swift */, D050F2121E48B61500988324 /* PhoneInputNode.swift */, D0B2F76B2052A7D600D3BFB9 /* SinglePhoneInputNode.swift */, - D0DA44531E4E7302005FDCA7 /* ProgressNavigationButtonNode.swift */, - D0C0B58F1EDB505E000F4D2C /* ActivityIndicator.swift */, D0FC4FBA1F751E8900B7443F /* SelectablePeerNode.swift */, - D01C06BB1FBBB0D8001561AB /* CheckNode.swift */, D056CD6F1FF147B000880D28 /* IconButtonNode.swift */, 09F85BA621E7DA5F00D73170 /* BlurredImageNode.swift */, D00580B221E4B51600CB7CD3 /* DeleteChatPeerActionSheetItem.swift */, 09749BCE21F236F2008FDDE9 /* ModernCheckNode.swift */, D0B21B12220D6E8C003F741D /* ActionSheetPeerItem.swift */, - 09E2DA102273340E00EA0AA4 /* AnimationNode.swift */, ); name = Nodes; sourceTree = ""; @@ -4606,7 +4481,6 @@ D0F69DE61D6B8A4E0046BCD6 /* Controllers */ = { isa = PBXGroup; children = ( - 09EC0DE522C67F8900E7185B /* Update */, D0F69DE71D6B8A590046BCD6 /* Authorization */, D05174C11EAE582A00A1BF36 /* Root */, D0F69DF61D6B8A720046BCD6 /* Chat List */, @@ -4730,6 +4604,7 @@ D025402422E1E00100AC0195 /* ChatSlowmodeHintController.swift */, D025402622E1F23000AC0195 /* ChatSendButtonRadialStatusNode.swift */, D025402822E1F7F500AC0195 /* ChatTextInputSlowmodePlaceholderNode.swift */, + D06018B422F3659900796784 /* ChatTextFormat.swift */, ); name = Chat; sourceTree = ""; @@ -4766,7 +4641,6 @@ D0F69E2C1D6B8B030046BCD6 /* ChatUnreadItem.swift */, D0F69E191D6B8AE60046BCD6 /* ChatHoleItem.swift */, D0D2686D1D7898A900C422DA /* ChatMessageSelectionNode.swift */, - D0F7AB341DCFADCD009AD9A1 /* ChatMessageBubbleImages.swift */, D0F7AB381DCFF87B009AD9A1 /* ChatMessageDateHeader.swift */, D01AC9171DD5033100E8160F /* ChatMessageActionButtonsNode.swift */, D0C932371E09E0EA0074F044 /* ChatBotInfoItem.swift */, @@ -4803,7 +4677,6 @@ D039EB091DEC7A8700886EBC /* ChatTextInputAudioRecordingCancelIndicator.swift */, D0CE8CE41F6F354400AA2DB0 /* ChatTextInputAccessoryItem.swift */, D0CE8CE61F6F35A300AA2DB0 /* ChatTextInputPanelState.swift */, - D053DAD9201A4C4400993D32 /* ChatTextInputAttributes.swift */, D053DADB201AAAB100993D32 /* ChatTextInputMenu.swift */, 09FFBCD62281BB2D00C33B4B /* ChatTextLinkEditController.swift */, ); @@ -4952,10 +4825,8 @@ D01848F021A2323D00B6DEBD /* Strings */, 09E4A7FF223AE0440038140F /* UI */, D073CE701DCBF23F007511FD /* DeclareEncodables.swift */, - D0E817462010E62E00B82BBB /* MergeLists.swift */, D0B844571DAC44E8005F29E1 /* PeerPresenceStatusManager.swift */, D073CE641DCBC26B007511FD /* ServiceSoundManager.swift */, - D0F917B41E0DA396003687E6 /* GenerateTextEntities.swift */, D0E305A41E5B2BFB00D7A3A2 /* ValidateAddressNameInteractive.swift */, D0F3A8AA1E82D83E00B4C64C /* TelegramAccountAuxiliaryMethods.swift */, D01DBA9A209CC6AD00C64E64 /* ChatLinkPreview.swift */, @@ -5063,7 +4934,6 @@ D008179822B478FE008A895F /* App */, D07551891DDA4C7C0073E051 /* Legacy Components */, D0F69E911D6B8C8E0046BCD6 /* Utils */, - D096A4601EA681720000A7AE /* Presentation Data */, D0F69DBB1D6B88330046BCD6 /* Media */, D0F69DBD1D6B897A0046BCD6 /* Components */, D0F69DE61D6B8A4E0046BCD6 /* Controllers */, @@ -5447,15 +5317,12 @@ 09F85BA521E7821500D73170 /* ThemeGridSelectionPanelNode.swift in Sources */, D0FC4FBB1F751E8900B7443F /* SelectablePeerNode.swift in Sources */, D0E9BAD21F0573C000F079A4 /* STPToken.m in Sources */, - D0EC6CD31EB9F58800EBF1C3 /* GenerateTextEntities.swift in Sources */, 0913469A218528D200846E49 /* InstantPageTableItem.swift in Sources */, - D0EC6CD41EB9F58800EBF1C3 /* StringWithAppliedEntities.swift in Sources */, D0192D46210F4F950005FA10 /* FixSearchableListNodeScrolling.swift in Sources */, D0EC6CD51EB9F58800EBF1C3 /* StoredMessageFromSearchPeer.swift in Sources */, 09CE950E2237E45E00A7D2C3 /* CachedFaqInstantPage.swift in Sources */, D0471B5E1EFEB5860074D609 /* BotPaymentHeaderItemNode.swift in Sources */, D0EC6CD71EB9F58800EBF1C3 /* EmojiUtils.swift in Sources */, - D0EC6CD81EB9F58800EBF1C3 /* ShakeAnimation.swift in Sources */, D0EC6CD91EB9F58800EBF1C3 /* ValidateAddressNameInteractive.swift in Sources */, D0BE30452061C09000FBE6D8 /* SecureIdAuthContentNode.swift in Sources */, 09B4EE5E21AC626B00847FA6 /* PermissionContentNode.swift in Sources */, @@ -5464,7 +5331,6 @@ 09F664CA21EB4F2700AB7E26 /* ThemeGridSearchColorsItem.swift in Sources */, D093D82220699A7C00BC3599 /* FormControllerNode.swift in Sources */, D025402922E1F7F500AC0195 /* ChatTextInputSlowmodePlaceholderNode.swift in Sources */, - D0EC6CDB1EB9F58800EBF1C3 /* Markdown.swift in Sources */, D0E412D0206A75B200BEE4A2 /* FormControllerDetailActionItem.swift in Sources */, D09F9DCF20768DAF00DB4DE1 /* SecureIdLocalResource.swift in Sources */, D0471B641EFEB5CB0074D609 /* BotPaymentItemNode.swift in Sources */, @@ -5474,16 +5340,9 @@ D0A8BBA11F61EE83000F03FD /* UniversalVideoGalleryItem.swift in Sources */, D0642EFC1F3E1E7B00792790 /* ChatHistoryNavigationButtons.swift in Sources */, D03AA4E5202DF8840056C405 /* StickerPreviewPeekContent.swift in Sources */, - D01C06BC1FBBB0D8001561AB /* CheckNode.swift in Sources */, - D0EC6CDF1EB9F58800EBF1C3 /* PresentationResourceKey.swift in Sources */, - D0EC6CE01EB9F58800EBF1C3 /* PresentationResourcesRootController.swift in Sources */, D025402322E1C92D00AC0195 /* ChatSlowmodeItem.swift in Sources */, - D0EC6CE11EB9F58800EBF1C3 /* PresentationResourcesItemList.swift in Sources */, 09DD88F121BE1090000766BC /* CallRatingController.swift in Sources */, D05D8B3F2192FC6E0064586F /* LocalizationListControllerNode.swift in Sources */, - D0EC6CE21EB9F58800EBF1C3 /* PresentationResourcesChatList.swift in Sources */, - D0EC6CE31EB9F58800EBF1C3 /* PresentationResourcesChat.swift in Sources */, - 09EC0DE722C67FB100E7185B /* UpdateInfoController.swift in Sources */, D0AA840C1FEB2BA3005C6E91 /* OverlayPlayerControlsNode.swift in Sources */, 09DD5D5021ECC3C400D7007A /* SuppressContactsWarning.swift in Sources */, D02B198A21F1DA9E0094A764 /* SharedAccountContext.swift in Sources */, @@ -5491,7 +5350,6 @@ D01776BA1F1D704F0044446D /* RadialStatusIconContentNode.swift in Sources */, D0E8B8BF20447A4600605593 /* SecretChatKeyControllerNode.swift in Sources */, D0C27B3B1F4B453700A4E170 /* InstantPagePlayableVideoItem.swift in Sources */, - D0EC6CEC1EB9F58800EBF1C3 /* PresentationThemeEssentialGraphics.swift in Sources */, D01BAA1E1ECC931D00295217 /* CallListNodeEntries.swift in Sources */, D02B2B9820810DA00062476B /* StickerPaneSearchStickerItem.swift in Sources */, D020A9DC1FEAE6E7008C66F7 /* OverlayPlayerControllerNode.swift in Sources */, @@ -5543,6 +5401,7 @@ 09E4A807223D4B860038140F /* AccountUtils.swift in Sources */, D069F5D0212700B90000565A /* StickerPanePeerSpecificSetupGridItem.swift in Sources */, D01590C022BDAEBC0017C33E /* BC1Compression.cpp in Sources */, + D06018B522F3659900796784 /* ChatTextFormat.swift in Sources */, D0750C8322B2E4EE00BE5F6E /* SharedNotificationManager.swift in Sources */, D0EC6D041EB9F58800EBF1C3 /* opusenc.m in Sources */, D0A8998D217A294100759EE6 /* SaveIncomingMediaController.swift in Sources */, @@ -5558,7 +5417,6 @@ D0EC6D0B1EB9F58800EBF1C3 /* opusfile.c in Sources */, D01847801FFBD12E00075256 /* ChatListPresentationData.swift in Sources */, D0FFF7F61F55B82500BEBC01 /* InstantPageAudioItem.swift in Sources */, - D03AA4E7202DFB160056C405 /* ItemListEditableReorderControlNode.swift in Sources */, 09C500242142BA6400EF253E /* ItemListWebsiteItem.swift in Sources */, D0EC6D0C1EB9F58800EBF1C3 /* stream.c in Sources */, 09FFBCD72281BB2D00C33B4B /* ChatTextLinkEditController.swift in Sources */, @@ -5656,7 +5514,6 @@ D0EC6D371EB9F58800EBF1C3 /* SearchDisplayController.swift in Sources */, D0185E8C208A025A005E1A6C /* ProxySettingsServerItem.swift in Sources */, 090E63EE2196FE3A00E3C035 /* OpenAddContact.swift in Sources */, - D04281ED200E3B28009DDE36 /* ItemListControllerSearch.swift in Sources */, D0EC6D381EB9F58800EBF1C3 /* SearchDisplayControllerContentNode.swift in Sources */, D06F1EA41F6C0A5D00FE8B74 /* ChatHistorySearchContainerNode.swift in Sources */, D0EC6D3A1EB9F58800EBF1C3 /* AudioWaveformNode.swift in Sources */, @@ -5666,7 +5523,6 @@ D0EC6D3C1EB9F58800EBF1C3 /* PhoneInputNode.swift in Sources */, D0147BAB206EA6C100E40378 /* SecureIdDocumentImageGalleryItem.swift in Sources */, D0AD02EC20000D0100C1DCFF /* ChatMessageLiveLocationPositionNode.swift in Sources */, - D0EC6D3D1EB9F58800EBF1C3 /* ProgressNavigationButtonNode.swift in Sources */, D01BAA581ED3283D00295217 /* AddFormatToStringWithRanges.swift in Sources */, D0E2CE6C222930540084E3DD /* PrefetchManager.swift in Sources */, D0EC6D3E1EB9F58800EBF1C3 /* TelegramController.swift in Sources */, @@ -5890,7 +5746,6 @@ D097C26C20DD1EA5007BB4B8 /* OverlayStatusController.swift in Sources */, D0EC6D9E1EB9F58900EBF1C3 /* ChatMessageWebpageBubbleContentNode.swift in Sources */, D06CF82720D0080200AC4CFF /* SecureIdAuthListContentNode.swift in Sources */, - D0C0B5901EDB505E000F4D2C /* ActivityIndicator.swift in Sources */, 09797873210633CD0077D77F /* InstantPageSettingsButtonItemNode.swift in Sources */, D0750C8722B2E76300BE5F6E /* ShareExtensionContext.swift in Sources */, D0EC6D9F1EB9F58900EBF1C3 /* ChatUnreadItem.swift in Sources */, @@ -5899,7 +5754,6 @@ D0EC6DA01EB9F58900EBF1C3 /* ChatHoleItem.swift in Sources */, D093D82020699A7300BC3599 /* FormController.swift in Sources */, D0EC6DA11EB9F58900EBF1C3 /* ChatMessageSelectionNode.swift in Sources */, - D0EC6DA21EB9F58900EBF1C3 /* ChatMessageBubbleImages.swift in Sources */, 09CE9502223272B700A7D2C3 /* GifPaneSearchContentNode.swift in Sources */, D0EC6DA31EB9F58900EBF1C3 /* ChatMessageDateHeader.swift in Sources */, D0EC6DA41EB9F58900EBF1C3 /* ChatMessageActionButtonsNode.swift in Sources */, @@ -6012,10 +5866,8 @@ D064EF871F69A06F00AC0398 /* MessageContentKind.swift in Sources */, D020A9DA1FEAE675008C66F7 /* OverlayPlayerController.swift in Sources */, 09CE9513223825B700A7D2C3 /* CustomWallpaperPicker.swift in Sources */, - D0E817472010E62F00B82BBB /* MergeLists.swift in Sources */, D0E8174C2011F8A300B82BBB /* ChatMessageEventLogPreviousMessageContentNode.swift in Sources */, D0EC6DD91EB9F58900EBF1C3 /* HorizontalListContextResultsChatInputContextPanelNode.swift in Sources */, - 09CE950C2237D61B00A7D2C3 /* PresentationResourcesSettings.swift in Sources */, D0E9BA161F05574500F079A4 /* STPCardValidator.m in Sources */, D0EC6DDA1EB9F58900EBF1C3 /* HorizontalListContextResultsChatInputPanelItem.swift in Sources */, D0EC6DDB1EB9F58900EBF1C3 /* ChatInputPanelNode.swift in Sources */, @@ -6032,7 +5884,6 @@ D0E9BAC91F05738600F079A4 /* STPAPIClient+ApplePay.m in Sources */, 09F79A0721C829BC00820234 /* GalleryNavigationCheckNode.swift in Sources */, D0EC6DDF1EB9F58900EBF1C3 /* ChatTextInputAudioRecordingTimeNode.swift in Sources */, - D0BFAE5B20AB35D200793CF2 /* IconSwitchNode.swift in Sources */, D0EC6DE01EB9F58900EBF1C3 /* ChatTextInputAudioRecordingCancelIndicator.swift in Sources */, 0962E67F21BA786A00245FD9 /* WebSearchItem.swift in Sources */, D081A9A922EB26AE0069C449 /* PhoneLabelController.swift in Sources */, @@ -6048,7 +5899,6 @@ 090E777922A6A32E00CD99F5 /* ThemeSettingsThemeItem.swift in Sources */, D06BEC771F62F68B0035A545 /* OverlayUniversalVideoNode.swift in Sources */, D0EC6DE61EB9F58900EBF1C3 /* DeleteChatInputPanelNode.swift in Sources */, - D01BAA241ECE173200295217 /* PresentationResourcesCallList.swift in Sources */, D0428200200E6A00009DDE36 /* ChatRecentActionsHistoryTransition.swift in Sources */, D0EC6DE71EB9F58900EBF1C3 /* ChatTitleAccessoryPanelNode.swift in Sources */, D0EC6DE81EB9F58900EBF1C3 /* ChatPinnedMessageTitlePanelNode.swift in Sources */, @@ -6060,7 +5910,6 @@ D0EC6DEB1EB9F58900EBF1C3 /* ChatRequestInProgressTitlePanelNode.swift in Sources */, D0EC6DEC1EB9F58900EBF1C3 /* ChatToastAlertPanelNode.swift in Sources */, D0EC6DED1EB9F58900EBF1C3 /* ChatHistoryNavigationButtonNode.swift in Sources */, - 09E2DA112273340E00EA0AA4 /* AnimationNode.swift in Sources */, D0F4B01A211073C500912B92 /* DeviceContactInfoController.swift in Sources */, D0FB87B21F7C4C19004DE005 /* FetchMediaUtils.swift in Sources */, 0979787E210646C00077D77F /* YoutubeEmbedImplementation.swift in Sources */, @@ -6206,37 +6055,24 @@ D0EC55A3210231D600D1992C /* SearchPeerMembers.swift in Sources */, D0EC6E331EB9F58900EBF1C3 /* CreateChannelController.swift in Sources */, D0AA29AE1F72770D00C050AC /* ChatListItemStrings.swift in Sources */, - D0EC6E341EB9F58900EBF1C3 /* ItemListItem.swift in Sources */, D0EC6E351EB9F58900EBF1C3 /* ItemListAvatarAndNameItem.swift in Sources */, - D0EC6E361EB9F58900EBF1C3 /* ItemListTextWithLabelItem.swift in Sources */, 09F215A622649C3000AEDF6D /* PasscodeLockIconNode.swift in Sources */, - D0EC6E371EB9F58900EBF1C3 /* ItemListActionItem.swift in Sources */, - D0EC6E381EB9F58900EBF1C3 /* ItemListDisclosureItem.swift in Sources */, D0E9BA651F055B4500F079A4 /* BotCheckoutNativeCardEntryController.swift in Sources */, D02D60B3206C18A600FEFE1E /* SecureIdPlaintextFormControllerNode.swift in Sources */, D00ACA5A2022897D0045D427 /* ProcessedPeerRestrictionText.swift in Sources */, - 09EC0DEB22CAFF1400E7185B /* UpdateInfoItem.swift in Sources */, D0192D3C210A44D00005FA10 /* DeviceContactData.swift in Sources */, - D0EC6E391EB9F58900EBF1C3 /* ItemListCheckboxItem.swift in Sources */, - D0EC6E3A1EB9F58900EBF1C3 /* ItemListSwitchItem.swift in Sources */, D04203152037162700490EA5 /* MediaInputPaneTrendingItem.swift in Sources */, D0EC6E3B1EB9F58900EBF1C3 /* ItemListPeerItem.swift in Sources */, D0EC6E3C1EB9F58900EBF1C3 /* ItemListPeerActionItem.swift in Sources */, - D0EC6E3D1EB9F58900EBF1C3 /* ItemListMultilineInputItem.swift in Sources */, D0CE8CE71F6F35A300AA2DB0 /* ChatTextInputPanelState.swift in Sources */, D0AF796E22C2E26500CECCB8 /* astc.cc in Sources */, D0CE6F70213EEE5000BCD44B /* CreatePasswordController.swift in Sources */, D0EC6E3E1EB9F58900EBF1C3 /* ItemListSectionHeaderItem.swift in Sources */, - D0EC6E3F1EB9F58900EBF1C3 /* ItemListTextItem.swift in Sources */, - D0EC6E401EB9F58900EBF1C3 /* ItemListActivityTextItem.swift in Sources */, 0958FBB9218AD6AF00E0CBD8 /* InstantPageFeedbackItem.swift in Sources */, 0940932622E73E12003846A3 /* ChatSendMessageActionSheetControllerNode.swift in Sources */, D00817D022B47A14008A895F /* WakeupManager.swift in Sources */, D0AF798822C2E26500CECCB8 /* matrix.cc in Sources */, - D0EC6E411EB9F58900EBF1C3 /* ItemListEditableItem.swift in Sources */, - D0EC6E421EB9F58900EBF1C3 /* ItemListRevealOptionsNode.swift in Sources */, D0E8175920122FE100B82BBB /* ChatRecentActionsFilterController.swift in Sources */, - D0EC6E431EB9F58900EBF1C3 /* ItemListEditableDeleteControlNode.swift in Sources */, D08557E722C5FEB90026D6D2 /* AnimatedStickerNode.swift in Sources */, D0EC6E441EB9F58900EBF1C3 /* ItemListSingleLineInputItem.swift in Sources */, D01776B31F1D69A80044446D /* RadialStatusNode.swift in Sources */, @@ -6245,25 +6081,19 @@ 0900678D21ED5EA800530762 /* WallpaperColorPanelNode.swift in Sources */, 0957DE2522DE2909001B4D57 /* ThemePreviewControllerNode.swift in Sources */, 09A218DA229EE1B600DE6898 /* HorizontalStickersChatContextPanelNode.swift in Sources */, - D0EC6E451EB9F58900EBF1C3 /* ItemListMultilineTextItem.swift in Sources */, 091417F421EF4F5F00C8325A /* WallpaperGalleryItem.swift in Sources */, D02F4AE91FCF370B004DFBAE /* ChatMessageInteractiveMediaBadge.swift in Sources */, - D0EC6E461EB9F58900EBF1C3 /* ItemListLoadingIndicatorEmptyStateItem.swift in Sources */, D00817CF22B47A14008A895F /* LegacyFileImport.swift in Sources */, D01A21AF1F39EA2E00DDA104 /* InstantPageTheme.swift in Sources */, D0EC6E471EB9F58900EBF1C3 /* ItemListTextEmptyStateItem.swift in Sources */, D0E412C62069B60600BEE4A2 /* FormControllerHeaderItem.swift in Sources */, - D0EC6E481EB9F58900EBF1C3 /* ItemListController.swift in Sources */, D0E412D5206A842900BEE4A2 /* SecureIdVerificationDocument.swift in Sources */, - D0EC6E491EB9F58900EBF1C3 /* ItemListControllerEmptyStateItem.swift in Sources */, - D0EC6E4A1EB9F58900EBF1C3 /* ItemListControllerNode.swift in Sources */, D0147BA9206EA35000E40378 /* SecureIdDocumentGalleryController.swift in Sources */, D00817DF22B47A14008A895F /* LegacyDataImportSplash.swift in Sources */, D0B37C5C1F8D22AE004252DF /* ThemeSettingsController.swift in Sources */, D05D8B412192FC8A0064586F /* LocalizationListItem.swift in Sources */, D0383ED4207CFBB900C45548 /* GalleryThumbnailContainerNode.swift in Sources */, 0962E67B21BA00C900245FD9 /* WebSearchInterfaceState.swift in Sources */, - D0EC6E4B1EB9F58900EBF1C3 /* ItemListControllerSegmentedTitleView.swift in Sources */, 09DD88F521BF9730000766BC /* WebSearchRecentQueries.swift in Sources */, D0AE303822B1D3620058D3BC /* TGBridgeAudioDecoder.mm in Sources */, D0EC6E4D1EB9F58900EBF1C3 /* PeerInfoController.swift in Sources */, @@ -6287,7 +6117,6 @@ D093D8242069A06600BC3599 /* FormControllerScrollerNode.swift in Sources */, D081E106217F5834003CD921 /* LanguageLinkPreviewControllerNode.swift in Sources */, D093D7E72063E57F00BC3599 /* BotPaymentActionItemNode.swift in Sources */, - D01C06BA1FBBB076001561AB /* ItemListSelectableControlNode.swift in Sources */, 098CF79222B924E200AF6134 /* ThemeSettingsAccentColorItem.swift in Sources */, D0EC6E541EB9F58900EBF1C3 /* ConvertToSupergroupController.swift in Sources */, D0EC6E561EB9F58900EBF1C3 /* UserInfoController.swift in Sources */, @@ -6365,7 +6194,6 @@ D0EC6E811EB9F58900EBF1C3 /* NotificationContainerController.swift in Sources */, 090E778822A9B96100CD99F5 /* PeersNearbyHeaderItem.swift in Sources */, D0754D271EEE10C800884F6E /* BotCheckoutController.swift in Sources */, - D053DADA201A4C4400993D32 /* ChatTextInputAttributes.swift in Sources */, 0952D1752176DEB500194860 /* NotificationMuteSettingsController.swift in Sources */, D0EC6E821EB9F58900EBF1C3 /* NotificationContainerControllerNode.swift in Sources */, D0EC6E831EB9F58900EBF1C3 /* NotificationItemContainerNode.swift in Sources */, @@ -6523,7 +6351,7 @@ PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = DebugFork; @@ -6721,7 +6549,7 @@ PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = DebugAppStore; @@ -6839,7 +6667,7 @@ SKIP_INSTALL = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = ReleaseHockeyappInternal; @@ -6964,7 +6792,7 @@ PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = DebugAppStoreLLC; @@ -7081,7 +6909,7 @@ SKIP_INSTALL = YES; SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = ReleaseAppStoreLLC; @@ -7128,7 +6956,7 @@ SKIP_INSTALL = YES; SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = DebugHockeyapp; @@ -7173,7 +7001,7 @@ SKIP_INSTALL = NO; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = ReleaseHockeyapp; @@ -7217,7 +7045,7 @@ SKIP_INSTALL = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; name = ReleaseAppStore; From ee3142966e6d78de6093ab91a2ca3f1593e2e3f2 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 2 Aug 2019 02:28:24 +0300 Subject: [PATCH 41/41] Update workspace --- .../contents.xcworkspacedata | 150 ++++++++++++------ 1 file changed, 102 insertions(+), 48 deletions(-) diff --git a/Telegram-iOS.xcworkspace/contents.xcworkspacedata b/Telegram-iOS.xcworkspace/contents.xcworkspacedata index da55a164a5..8e6a323970 100644 --- a/Telegram-iOS.xcworkspace/contents.xcworkspacedata +++ b/Telegram-iOS.xcworkspace/contents.xcworkspacedata @@ -1,66 +1,123 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - @@ -73,9 +130,6 @@ - -