From 5497a40f0e7e9f5c27a5ffcd8c53d4b2d27c7d84 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Tue, 2 Sep 2025 17:33:12 +0400 Subject: [PATCH 1/4] Deploy build --- build-system/Make/DeployBuild.py | 117 +++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 build-system/Make/DeployBuild.py diff --git a/build-system/Make/DeployBuild.py b/build-system/Make/DeployBuild.py new file mode 100644 index 0000000000..da50a96a44 --- /dev/null +++ b/build-system/Make/DeployBuild.py @@ -0,0 +1,117 @@ +#!/bin/python3 + +import argparse +import os +import sys +import json +import hashlib +import base64 +import requests + +def sha256_file(path): + h = hashlib.sha256() + with open(path, 'rb') as f: + while True: + data = f.read(1024 * 64) + if not data: + break + h.update(data) + return h.hexdigest() + +def init_build(host, token, files): + url = host.rstrip('/') + '/upload/init' + headers = {"Authorization": "Bearer " + token} + payload = {"files": files} + r = requests.post(url, json=payload, headers=headers, timeout=30) + r.raise_for_status() + return r.json() + +def upload_file(path, upload_info): + url = upload_info.get('url') + headers = dict(upload_info.get('headers', {})) + + size = os.path.getsize(path) + headers['Content-Length'] = str(size) + + print('Uploading', path) + with open(path, 'rb') as f: + r = requests.put(url, data=f, headers=headers, timeout=900) + if r.status_code != 200: + print('Upload failed', r.status_code) + print(r.text[:500]) + r.raise_for_status() + +def commit_build(host, token, build_id): + url = host.rstrip('/') + '/upload/commit' + headers = {"Authorization": "Bearer " + token} + r = requests.post(url, json={"buildId": build_id}, headers=headers, timeout=900) + if r.status_code != 200: + print('Commit failed', r.status_code) + print(r.text[:500]) + r.raise_for_status() + return r.json() + +if __name__ == '__main__': + parser = argparse.ArgumentParser(prog='deploy-build') + parser.add_argument('--ipa', required=True, help='Path to IPA') + parser.add_argument('--dsyms', help='Path to dSYMs.zip') + parser.add_argument('--configuration', required=True, help='Path to JSON config') + args = parser.parse_args() + + if not os.path.exists(args.configuration): + print('{} does not exist'.format(args.configuration)) + sys.exit(1) + if not os.path.exists(args.ipa): + print('{} does not exist'.format(args.ipa)) + sys.exit(1) + if args.dsyms is not None and not os.path.exists(args.dsyms): + print('{} does not exist'.format(args.dsyms)) + sys.exit(1) + + try: + with open(args.configuration, 'r') as f: + config = json.load(f) + except Exception as e: + print('Failed to read configuration:', e) + sys.exit(1) + + host = config.get('host') + token = config.get('auth_token') + if not host or not token: + print('Invalid configuration') + sys.exit(1) + ipa_path = args.ipa + dsym_path = args.dsyms + + ipa_sha = sha256_file(ipa_path) + files = { + 'ipa': { + 'filename': os.path.basename(ipa_path), + 'size': os.path.getsize(ipa_path), + 'sha256': ipa_sha, + } + } + if dsym_path: + dsym_sha = sha256_file(dsym_path) + files['dsym'] = { + 'filename': os.path.basename(dsym_path), + 'size': os.path.getsize(dsym_path), + 'sha256': dsym_sha, + } + + print('Init build') + init = init_build(host, token, files) + build_id = init.get('build_id') + urls = init.get('upload_urls', {}) + if not build_id: + print('No build_id') + sys.exit(1) + + upload_file(ipa_path, urls.get('ipa', {})) + if dsym_path and 'dsym' in urls: + upload_file(dsym_path, urls.get('dsym', {})) + + print('Commit build') + result = commit_build(host, token, build_id) + + print('Done! Install page:', result.get('install_page_url')) From e60cd2d4d47bb59bf1a883251f6c19b14ae4fbb1 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Tue, 2 Sep 2025 13:57:13 +0000 Subject: [PATCH 2/4] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4b3b00460e..c212b67c31 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,6 +27,7 @@ internal: - rm -rf build-input/configuration-repository - python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="$TELEGRAM_PRIVATE_DATA_PATH/build-configurations/enterprise-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=enterprise --configuration=release_arm64 - python3 -u build-system/Make/DeployToFirebase.py --configuration="$TELEGRAM_PRIVATE_DATA_PATH/firebase-configurations/firebase-enterprise.json" --ipa="build/artifacts/Telegram.ipa" --dsyms="build/artifacts/Telegram.DSYMs.zip" + - python3 -u build-system/Make/DeployBuild.py --configuration="$TELEGRAM_PRIVATE_DATA_PATH/deploy-configurations/enterprise-configuration.json" --ipa="build/artifacts/Telegram.ipa" --dsyms="build/artifacts/Telegram.DSYMs.zip" environment: name: internal artifacts: From 3f9820f2eff67a3179508213e236a56209b2825e Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 3 Sep 2025 21:37:47 +0500 Subject: [PATCH 3/4] Various fixes --- .../Sources/TelegramEngine/Payments/StarGifts.swift | 2 +- .../Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift | 6 +++++- .../Gifts/GiftViewScreen/Sources/GiftViewScreen.swift | 6 +++--- .../PeerInfoScreen/Sources/PeerInfoHeaderNode.swift | 4 +++- .../PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift | 4 ++-- .../PeerInfoVisualMediaPaneNode/Sources/GiftsListView.swift | 4 ++-- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift index 055890e327..9464fa8bf1 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift @@ -976,7 +976,7 @@ func _internal_keepCachedStarGiftsUpdated(postbox: Postbox, network: Network, ac let updateSignal = _internal_cachedStarGifts(postbox: postbox) |> take(1) |> mapToSignal { list -> Signal in - return network.request(Api.functions.payments.getStarGifts(hash: 0)) + return network.request(Api.functions.payments.getStarGifts(hash: list?.hashValue ?? 0)) |> map(Optional.init) |> `catch` { _ -> Signal in return .single(nil) diff --git a/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift index 25bee3463c..3dedd98b87 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift @@ -124,7 +124,6 @@ final class GiftSetupScreenComponent: Component { private var inProgress = false - private var previousHadInputHeight: Bool = false private var previousInputHeight: CGFloat? private var recenterOnTag: NSObject? @@ -134,6 +133,8 @@ final class GiftSetupScreenComponent: Component { private var starImage: (UIImage, PresentationTheme)? + private var updateDisposable: Disposable? + private var optionsDisposable: Disposable? private(set) var options: [StarsTopUpOption] = [] { didSet { @@ -173,6 +174,9 @@ final class GiftSetupScreenComponent: Component { } deinit { + self.inputMediaNodeDataDisposable?.dispose() + self.updateDisposable?.dispose() + self.optionsDisposable?.dispose() } func scrollToTop() { diff --git a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift index ba017d2150..4c3a90a7ea 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift @@ -931,7 +931,7 @@ private final class GiftViewSheetContent: CombinedComponent { }) if let tranfserGiftImpl { - return tranfserGiftImpl(transferStars == 0, peerId) + return tranfserGiftImpl(transferStars == 0, reference, peerId) } else { return (context.engine.payments.transferStarGift(prepaid: transferStars == 0, reference: reference, peerId: peerId) |> deliverOnMainQueue) @@ -4554,7 +4554,7 @@ public class GiftViewScreen: ViewControllerComponentContainer { fileprivate let updateSavedToProfile: ((StarGiftReference, Bool) -> Void)? fileprivate let convertToStars: ((StarGiftReference) -> Void)? - fileprivate let transferGift: ((Bool, EnginePeer.Id) -> Signal)? + fileprivate let transferGift: ((Bool, StarGiftReference, EnginePeer.Id) -> Signal)? fileprivate let upgradeGift: ((Int64?, StarGiftReference, Bool) -> Signal)? fileprivate let buyGift: ((String, EnginePeer.Id, CurrencyAmount?) -> Signal)? fileprivate let updateResellStars: ((StarGiftReference, CurrencyAmount?) -> Signal)? @@ -4572,7 +4572,7 @@ public class GiftViewScreen: ViewControllerComponentContainer { forceDark: Bool = false, updateSavedToProfile: ((StarGiftReference, Bool) -> Void)? = nil, convertToStars: ((StarGiftReference) -> Void)? = nil, - transferGift: ((Bool, EnginePeer.Id) -> Signal)? = nil, + transferGift: ((Bool, StarGiftReference, EnginePeer.Id) -> Signal)? = nil, upgradeGift: ((Int64?, StarGiftReference, Bool) -> Signal)? = nil, buyGift: ((String, EnginePeer.Id, CurrencyAmount?) -> Signal)? = nil, updateResellStars: ((StarGiftReference, CurrencyAmount?) -> Signal)? = nil, diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift index d38cf5f67f..9e6172ea02 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift @@ -1905,7 +1905,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { transition.updateFrameAdditive(node: self.avatarListNode, frame: CGRect(origin: apparentAvatarFrame.center, size: CGSize())) transition.updateFrameAdditive(node: self.avatarOverlayNode, frame: CGRect(origin: apparentAvatarFrame.center, size: CGSize())) - let avatarListContainerFrame: CGRect + var avatarListContainerFrame: CGRect let avatarListContainerScale: CGFloat if self.isAvatarExpanded { if let transitionSourceAvatarFrame = transitionSourceAvatarFrame { @@ -1922,6 +1922,8 @@ final class PeerInfoHeaderNode: ASDisplayNode { avatarListContainerFrame = CGRect(origin: CGPoint(x: -expandedAvatarListSize.width / 2.0, y: -expandedAvatarListSize.width / 2.0), size: expandedAvatarListSize) } avatarListContainerScale = 1.0 + max(0.0, -contentOffset / avatarListContainerFrame.width) + let heightDelta = avatarListContainerFrame.height * avatarListContainerScale - avatarListContainerFrame.height + avatarListContainerFrame.origin.y -= heightDelta / 4.0 } else { let expandHeightFraction = expandedAvatarListSize.height / expandedAvatarListSize.width avatarListContainerFrame = CGRect(origin: CGPoint(x: -apparentAvatarFrame.width / 2.0, y: -apparentAvatarFrame.width / 2.0 + expandHeightFraction * 0.0 * apparentAvatarFrame.width), size: apparentAvatarFrame.size) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 5627e06ed1..180b0bc579 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -5018,8 +5018,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } profileGifts.convertStarGift(reference: reference) }, - transferGift: { [weak profileGifts] prepaid, peerId in - guard let profileGifts, let reference = gift.reference else { + transferGift: { [weak profileGifts] prepaid, reference, peerId in + guard let profileGifts else { return .complete() } return profileGifts.transferStarGift(prepaid: prepaid, reference: reference, peerId: peerId) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/GiftsListView.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/GiftsListView.swift index 89396b24d4..88028c55e6 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/GiftsListView.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/GiftsListView.swift @@ -617,8 +617,8 @@ final class GiftsListView: UIView { } self.profileGifts.convertStarGift(reference: reference) }, - transferGift: { [weak self] prepaid, peerId in - guard let self, let reference = product.reference else { + transferGift: { [weak self] prepaid, reference, peerId in + guard let self else { return .complete() } return self.profileGifts.transferStarGift(prepaid: prepaid, reference: reference, peerId: peerId) From 3c61b4a1e4fccdc826f7013c9b166ee5768ae5c0 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 3 Sep 2025 21:44:56 +0500 Subject: [PATCH 4/4] Various fixes --- .../PeerInfoVisualMediaPaneNode/Sources/GiftsListView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/GiftsListView.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/GiftsListView.swift index 88028c55e6..ac6ade2870 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/GiftsListView.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/GiftsListView.swift @@ -502,7 +502,7 @@ final class GiftsListView: UIView { peer = nil resellAmount = gift.resellAmounts?.first(where: { $0.currency == .stars }) - if let _ = resellAmount { + if !(gift.resellAmounts ?? []).isEmpty { ribbonText = params.presentationData.strings.PeerInfo_Gifts_Sale ribbonFont = .larger ribbonColor = .green