From a16e537b07c7b766305849b9303b49eb57b54653 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 5 Feb 2023 11:32:35 +0100 Subject: [PATCH 01/14] Attempt to restore github actions build --- .github/workflows/build.yml | 50 +++++++++---------------------------- 1 file changed, 12 insertions(+), 38 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b4f47e1a3..260618385e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,17 +24,16 @@ jobs: - name: Create canonical source directory run: | set -x - sudo mkdir /Users/telegram - sudo chown -R $(whoami) /Users/telegram - cp -R $GITHUB_WORKSPACE /Users/telegram/ - mv /Users/telegram/$(basename $GITHUB_WORKSPACE) /Users/telegram/telegram-ios + sudo mkdir -p /Users/Shared + cp -R $GITHUB_WORKSPACE /Users/Shared/ + mv /Users/Shared/$(basename $GITHUB_WORKSPACE) /Users/Shared/telegram-ios - name: Build the App run: | set -x # source code paths are included in the final binary, so we need to make them stable across builds - SOURCE_DIR=/Users/telegram/telegram-ios + SOURCE_DIR=/Users/Shared/telegram-ios # use canonical bazel root BAZEL_USER_ROOT="/private/var/tmp/_bazel_telegram" @@ -50,37 +49,12 @@ jobs: echo "BUILD_NUMBER=$(echo $BUILD_NUMBER)" >> $GITHUB_ENV echo "APP_VERSION=$(echo $APP_VERSION)" >> $GITHUB_ENV - # prepare temporary keychain - export MY_KEYCHAIN="temp.keychain" - export MY_KEYCHAIN_PASSWORD="secret" - security create-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN" - security list-keychains -d user -s "$MY_KEYCHAIN" $(security list-keychains -d user | sed s/\"//g) - security set-keychain-settings "$MY_KEYCHAIN" - security unlock-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN" - - # install fake certificates - export CERTS_PATH="build-system/fake-codesigning/certs/distribution" - for f in "$CERTS_PATH"/*.p12; do - security import "$f" -k "$MY_KEYCHAIN" -P "" -T /usr/bin/codesign -T /usr/bin/security || true - done - for f in "$CERTS_PATH"/*.cer; do - security import "$f" -k "$MY_KEYCHAIN" -P "" -T /usr/bin/codesign -T /usr/bin/security || true - done - security set-key-partition-list -S apple-tool:,apple: -k "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN" - - # use the official release configuration - rm -rf $HOME/telegram-configuration - mkdir -p $HOME/telegram-configuration - cp -R build-system/example-configuration/* $HOME/telegram-configuration/ - - # build the app - python3 build-system/Make/Make.py \ - --bazelUserRoot="$BAZEL_USER_ROOT" \ - build \ - --disableParallelSwiftmoduleGeneration \ - --configurationPath="$HOME/telegram-configuration" \ - --buildNumber=$BUILD_NUMBER \ - --configuration=release_universal + python3 build-system/Make/ImportCertificates.py --path build-system/fake-codesigning/certs + python3 -u build-system/Make/Make.py build \ + --configurationPath="build-system/appstore-configuration.json" \ + --codesigningInformationPath=build-system/fake-codesigning \ + --configuration=release_arm64 \ + --buildNumber="$BUILD_NUMBER" # collect ipa OUTPUT_PATH="build/artifacts" @@ -117,7 +91,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: /Users/telegram/telegram-ios/build/artifacts/Telegram.ipa + asset_path: /Users/Shared/telegram-ios/build/artifacts/Telegram.ipa asset_name: Telegram.ipa asset_content_type: application/zip @@ -128,6 +102,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: /Users/telegram/telegram-ios/build/artifacts/Telegram.DSYMs.zip + asset_path: /Users/Shared/telegram-ios/build/artifacts/Telegram.DSYMs.zip asset_name: Telegram.DSYMs.zip asset_content_type: application/zip From f77387c352b0f28f34d4194e6cd7063ed987125c Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 5 Feb 2023 12:45:39 +0100 Subject: [PATCH 02/14] Update canonical bazel user root --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 260618385e..46ff7e487b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,7 +36,7 @@ jobs: SOURCE_DIR=/Users/Shared/telegram-ios # use canonical bazel root - BAZEL_USER_ROOT="/private/var/tmp/_bazel_telegram" + BAZEL_USER_ROOT="/private/var/tmp/_bazel_containerhost" cd $SOURCE_DIR @@ -51,6 +51,7 @@ jobs: python3 build-system/Make/ImportCertificates.py --path build-system/fake-codesigning/certs python3 -u build-system/Make/Make.py build \ + --bazelUserRoot="$BAZEL_USER_ROOT" \ --configurationPath="build-system/appstore-configuration.json" \ --codesigningInformationPath=build-system/fake-codesigning \ --configuration=release_arm64 \ From f3e8b56107d3c385fb082404df46c5eb9ea71075 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 5 Feb 2023 13:06:00 +0100 Subject: [PATCH 03/14] Fix build --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 46ff7e487b..888963cbd5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,8 +50,9 @@ jobs: echo "APP_VERSION=$(echo $APP_VERSION)" >> $GITHUB_ENV python3 build-system/Make/ImportCertificates.py --path build-system/fake-codesigning/certs - python3 -u build-system/Make/Make.py build \ + python3 -u build-system/Make/Make.py \ --bazelUserRoot="$BAZEL_USER_ROOT" \ + build \ --configurationPath="build-system/appstore-configuration.json" \ --codesigningInformationPath=build-system/fake-codesigning \ --configuration=release_arm64 \ From b26d9bfe6cdb22939e5d2807eede0ff8d42ac126 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Mon, 6 Feb 2023 18:50:53 +0100 Subject: [PATCH 04/14] Bump version --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index f194d55736..4b74b349d4 100644 --- a/versions.json +++ b/versions.json @@ -1,5 +1,5 @@ { - "app": "9.4", + "app": "9.4.1", "bazel": "5.3.1", "xcode": "14.1" } From 5bb8089449f1dbd1558a6cf3501fe05f9d3cf6ae Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 7 Feb 2023 23:14:09 +0400 Subject: [PATCH 05/14] Update card validation (cherry picked from commit 5c71c08b6e9442b009ca3b71e784a1f8e2ebe4a1) --- .../PublicHeaders/Stripe/STPCardValidator.h | 4 ++-- submodules/Stripe/Sources/STPBINRange.m | 3 ++- submodules/Stripe/Sources/STPCardParams.m | 2 +- submodules/Stripe/Sources/STPCardValidator.m | 22 +++++++++++++++---- .../STPPaymentCardTextFieldViewModel.m | 2 +- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/submodules/Stripe/PublicHeaders/Stripe/STPCardValidator.h b/submodules/Stripe/PublicHeaders/Stripe/STPCardValidator.h index f6bc671b50..23b906db0d 100755 --- a/submodules/Stripe/PublicHeaders/Stripe/STPCardValidator.h +++ b/submodules/Stripe/PublicHeaders/Stripe/STPCardValidator.h @@ -79,7 +79,7 @@ NS_ASSUME_NONNULL_BEGIN * @return STPCardValidationStateValid if the year is valid, STPCardValidationStateInvalid if the year is invalid, or STPCardValidationStateIncomplete if the year is a substring of a valid year (e.g. @"1" or @"2"). */ + (STPCardValidationState)validationStateForExpirationYear:(NSString *)expirationYear - inMonth:(NSString *)expirationMonth; + inMonth:(NSString *)expirationMonth cardBrand:(STPCardBrand)cardBrand; /** * The max CVC length for a card brand (for context, American Express CVCs are 4 digits, while all others are 3). @@ -109,7 +109,7 @@ NS_ASSUME_NONNULL_BEGIN + (STPCardValidationState)validationStateForExpirationYear:(NSString *)expirationYear inMonth:(NSString *)expirationMonth inCurrentYear:(NSInteger)currentYear - currentMonth:(NSInteger)currentMonth; + currentMonth:(NSInteger)currentMonth cardBrand:(STPCardBrand)cardBrand; + (STPCardValidationState)validationStateForCard:(STPCardParams *)card inCurrentYear:(NSInteger)currentYear currentMonth:(NSInteger)currentMonth; diff --git a/submodules/Stripe/Sources/STPBINRange.m b/submodules/Stripe/Sources/STPBINRange.m index 2939effddf..29d9a2b9ba 100755 --- a/submodules/Stripe/Sources/STPBINRange.m +++ b/submodules/Stripe/Sources/STPBINRange.m @@ -66,7 +66,8 @@ @[@"492937", @"492937", @13, @(STPCardBrandVisa)], @[@"492939", @"492939", @13, @(STPCardBrandVisa)], @[@"492960", @"492960", @13, @(STPCardBrandVisa)], - @[@"2", @"2", @16, @(STPCardBrandOther)], + @[@"8600", @"8600", @16, @(STPCardBrandOther)], + @[@"9860", @"9860", @16, @(STPCardBrandOther)], ]; NSMutableArray *binRanges = [NSMutableArray array]; for (NSArray *range in ranges) { diff --git a/submodules/Stripe/Sources/STPCardParams.m b/submodules/Stripe/Sources/STPCardParams.m index 329271d0b3..14b8300d53 100755 --- a/submodules/Stripe/Sources/STPCardParams.m +++ b/submodules/Stripe/Sources/STPCardParams.m @@ -101,7 +101,7 @@ NSString *ioValueString = [(NSString *)*ioValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSString *monthString = [@(self.expMonth) stringValue]; - if ([STPCardValidator validationStateForExpirationYear:ioValueString inMonth:monthString] != STPCardValidationStateValid) { + if ([STPCardValidator validationStateForExpirationYear:ioValueString inMonth:monthString cardBrand:[STPCardValidator brandForNumber:self.number]] != STPCardValidationStateValid) { return [self.class handleValidationErrorForParameter:@"expYear" error:outError]; } return YES; diff --git a/submodules/Stripe/Sources/STPCardValidator.m b/submodules/Stripe/Sources/STPCardValidator.m index 2d8d5ae371..93b8310f6b 100755 --- a/submodules/Stripe/Sources/STPCardValidator.m +++ b/submodules/Stripe/Sources/STPCardValidator.m @@ -75,7 +75,7 @@ static NSString * _Nonnull stringByRemovingCharactersFromSet(NSString * _Nonnull } } -+ (STPCardValidationState)validationStateForExpirationYear:(NSString *)expirationYear inMonth:(NSString *)expirationMonth inCurrentYear:(NSInteger)currentYear currentMonth:(NSInteger)currentMonth { ++ (STPCardValidationState)validationStateForExpirationYear:(NSString *)expirationYear inMonth:(NSString *)expirationMonth inCurrentYear:(NSInteger)currentYear currentMonth:(NSInteger)currentMonth cardBrand:(STPCardBrand)cardBrand { NSInteger moddedYear = currentYear % 100; @@ -91,6 +91,15 @@ static NSString * _Nonnull stringByRemovingCharactersFromSet(NSString * _Nonnull case 1: return STPCardValidationStateIncomplete; case 2: { + switch (cardBrand) { + case STPCardBrandVisa: + case STPCardBrandMasterCard: + case STPCardBrandOther: + return STPCardValidationStateValid; + default: + break; + } + if (sanitizedYear.integerValue == moddedYear) { return sanitizedMonth.integerValue >= currentMonth ? STPCardValidationStateValid : STPCardValidationStateInvalid; } else { @@ -104,11 +113,11 @@ static NSString * _Nonnull stringByRemovingCharactersFromSet(NSString * _Nonnull + (STPCardValidationState)validationStateForExpirationYear:(NSString *)expirationYear - inMonth:(NSString *)expirationMonth { + inMonth:(NSString *)expirationMonth cardBrand:(STPCardBrand)cardBrand { return [self validationStateForExpirationYear:expirationYear inMonth:expirationMonth inCurrentYear:[self currentYear] - currentMonth:[self currentMonth]]; + currentMonth:[self currentMonth] cardBrand:cardBrand]; } @@ -165,7 +174,12 @@ static NSString * _Nonnull stringByRemovingCharactersFromSet(NSString * _Nonnull STPCardValidationState expYearValidation = [self validationStateForExpirationYear:expYearString inMonth:expMonthString inCurrentYear:currentYear - currentMonth:currentMonth]; + currentMonth:currentMonth cardBrand:[STPCardValidator brandForNumber:card.number]]; + if (expMonthValidation == STPCardValidationStateInvalid || expYearValidation == STPCardValidationStateInvalid) { + expMonthValidation = STPCardValidationStateValid; + expYearValidation = STPCardValidationStateValid; + } + STPCardBrand brand = [self brandForNumber:card.number]; STPCardValidationState cvcValidation = [self validationStateForCVC:card.cvc cardBrand:brand]; diff --git a/submodules/Stripe/Sources/STPPaymentCardTextFieldViewModel.m b/submodules/Stripe/Sources/STPPaymentCardTextFieldViewModel.m index 014691eba7..b9f3a6ef38 100755 --- a/submodules/Stripe/Sources/STPPaymentCardTextFieldViewModel.m +++ b/submodules/Stripe/Sources/STPPaymentCardTextFieldViewModel.m @@ -67,7 +67,7 @@ break; case STPCardFieldTypeExpiration: { STPCardValidationState monthState = [STPCardValidator validationStateForExpirationMonth:self.expirationMonth]; - STPCardValidationState yearState = [STPCardValidator validationStateForExpirationYear:self.expirationYear inMonth:self.expirationMonth]; + STPCardValidationState yearState = [STPCardValidator validationStateForExpirationYear:self.expirationYear inMonth:self.expirationMonth cardBrand:[STPCardValidator brandForNumber:self.cardNumber]]; if (monthState == STPCardValidationStateValid && yearState == STPCardValidationStateValid) { return STPCardValidationStateValid; } else if (monthState == STPCardValidationStateInvalid || yearState == STPCardValidationStateInvalid) { From 5bb7ed4cf0fdaab7a502aa04bd366af5b63ab95f Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 8 Feb 2023 09:38:27 +0400 Subject: [PATCH 06/14] Bump Xcode version --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index 4b74b349d4..9b5e494db5 100644 --- a/versions.json +++ b/versions.json @@ -1,5 +1,5 @@ { "app": "9.4.1", "bazel": "5.3.1", - "xcode": "14.1" + "xcode": "14.2" } From 37a02784af24cb454be39e963fee16bff1377a31 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 8 Feb 2023 09:39:03 +0400 Subject: [PATCH 07/14] Bump version --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index 9b5e494db5..f220850f42 100644 --- a/versions.json +++ b/versions.json @@ -1,5 +1,5 @@ { - "app": "9.4.1", + "app": "9.5", "bazel": "5.3.1", "xcode": "14.2" } From acf1f60788449d91f0981a9d354345f09c6f2268 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 8 Feb 2023 10:36:46 +0400 Subject: [PATCH 08/14] Add reset notifications debug option --- .../Sources/DebugController.swift | 67 +++++++++++-------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/submodules/DebugSettingsUI/Sources/DebugController.swift b/submodules/DebugSettingsUI/Sources/DebugController.swift index 8f2a768db3..181060405a 100644 --- a/submodules/DebugSettingsUI/Sources/DebugController.swift +++ b/submodules/DebugSettingsUI/Sources/DebugController.swift @@ -73,6 +73,7 @@ private enum DebugControllerEntry: ItemListNodeEntry { case crashOnSlowQueries(PresentationTheme, Bool) case clearTips(PresentationTheme) case resetTranslationStates(PresentationTheme) + case resetNotifications case crash(PresentationTheme) case resetData(PresentationTheme) case resetDatabase(PresentationTheme) @@ -116,7 +117,7 @@ private enum DebugControllerEntry: ItemListNodeEntry { return DebugControllerSection.logging.rawValue case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries: return DebugControllerSection.experiments.rawValue - case .clearTips, .resetTranslationStates, .crash, .resetData, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .reindexUnread, .resetCacheIndex, .reindexCache, .resetBiometricsData, .resetWebViewCache, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .playerEmbedding, .playlistPlayback, .enableQuickReactionSwitch, .voiceConference, .experimentalCompatibility, .enableDebugDataDisplay, .acceleratedStickers, .experimentalBackground, .inlineForums, .localTranscription, . enableReactionOverrides, .restorePurchases: + case .clearTips, .resetTranslationStates, .resetNotifications, .crash, .resetData, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .reindexUnread, .resetCacheIndex, .reindexCache, .resetBiometricsData, .resetWebViewCache, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .playerEmbedding, .playlistPlayback, .enableQuickReactionSwitch, .voiceConference, .experimentalCompatibility, .enableDebugDataDisplay, .acceleratedStickers, .experimentalBackground, .inlineForums, .localTranscription, . enableReactionOverrides, .restorePurchases: return DebugControllerSection.experiments.rawValue case .preferredVideoCodec: return DebugControllerSection.videoExperiments.rawValue @@ -167,58 +168,60 @@ private enum DebugControllerEntry: ItemListNodeEntry { return 17 case .resetTranslationStates: return 18 - case .crash: + case .resetNotifications: return 19 - case .resetData: + case .crash: return 20 - case .resetDatabase: + case .resetData: return 21 - case .resetDatabaseAndCache: + case .resetDatabase: return 22 - case .resetHoles: + case .resetDatabaseAndCache: return 23 - case .reindexUnread: + case .resetHoles: return 24 - case .resetCacheIndex: + case .reindexUnread: return 25 - case .reindexCache: + case .resetCacheIndex: return 26 - case .resetBiometricsData: + case .reindexCache: return 27 - case .resetWebViewCache: + case .resetBiometricsData: return 28 - case .optimizeDatabase: + case .resetWebViewCache: return 29 - case .photoPreview: + case .optimizeDatabase: return 30 - case .knockoutWallpaper: + case .photoPreview: return 31 - case .experimentalCompatibility: + case .knockoutWallpaper: return 32 - case .enableDebugDataDisplay: + case .experimentalCompatibility: return 33 - case .acceleratedStickers: + case .enableDebugDataDisplay: return 34 - case .experimentalBackground: + case .acceleratedStickers: return 35 - case .inlineForums: + case .experimentalBackground: return 36 - case .localTranscription: + case .inlineForums: return 37 - case .enableReactionOverrides: + case .localTranscription: return 38 - case .restorePurchases: + case .enableReactionOverrides: return 39 - case .playerEmbedding: + case .restorePurchases: return 40 - case .playlistPlayback: + case .playerEmbedding: return 41 - case .enableQuickReactionSwitch: + case .playlistPlayback: return 42 - case .voiceConference: + case .enableQuickReactionSwitch: return 43 + case .voiceConference: + return 44 case let .preferredVideoCodec(index, _, _, _): - return 44 + index + return 45 + index case .disableVideoAspectScaling: return 100 case .enableVoipTcp: @@ -952,6 +955,15 @@ private enum DebugControllerEntry: ItemListNodeEntry { ]).start() } }) + case .resetNotifications: + return ItemListActionItem(presentationData: presentationData, title: "Reset Notifications", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { + UIApplication.shared.unregisterForRemoteNotifications() + + if let context = arguments.context { + let controller = textAlertController(context: context, title: nil, text: "Now restart the app", actions: [TextAlertAction(type: .genericAction, title: "OK", action: {})]) + arguments.presentController(controller, nil) + } + }) case .crash: return ItemListActionItem(presentationData: presentationData, title: "Crash", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { preconditionFailure() @@ -1340,6 +1352,7 @@ private func debugControllerEntries(sharedContext: SharedAccountContext, present if isMainApp { entries.append(.clearTips(presentationData.theme)) entries.append(.resetTranslationStates(presentationData.theme)) + entries.append(.resetNotifications) } entries.append(.crash(presentationData.theme)) entries.append(.resetData(presentationData.theme)) From ffa4be373a1ee0a0d84e1a0d6194ed47a458892b Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 8 Feb 2023 10:37:01 +0400 Subject: [PATCH 09/14] Remove debugging --- submodules/Postbox/Sources/Postbox.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/Postbox/Sources/Postbox.swift b/submodules/Postbox/Sources/Postbox.swift index 6fe3d5757c..e2994a364a 100644 --- a/submodules/Postbox/Sources/Postbox.swift +++ b/submodules/Postbox/Sources/Postbox.swift @@ -1302,7 +1302,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration, #if DEBUG //debugSaveState(basePath: basePath + "/db", name: "previous2") - debugRestoreState(basePath: basePath + "/db", name: "previous2") + //debugRestoreState(basePath: basePath + "/db", name: "previous2") #endif let startTime = CFAbsoluteTimeGetCurrent() From 37eb57779e110144a00121a048be833b3b9eab7b Mon Sep 17 00:00:00 2001 From: Ali <> Date: Mon, 13 Feb 2023 22:04:49 +0400 Subject: [PATCH 10/14] Change version --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index f220850f42..49abfb2822 100644 --- a/versions.json +++ b/versions.json @@ -1,5 +1,5 @@ { - "app": "9.5", + "app": "9.4.2", "bazel": "5.3.1", "xcode": "14.2" } From c1018d3656d9944df0f34268aea3692515e46cb4 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Mon, 13 Feb 2023 22:18:12 +0400 Subject: [PATCH 11/14] Update API --- submodules/TelegramApi/Sources/Api0.swift | 4 + submodules/TelegramApi/Sources/Api25.swift | 112 ++++++----- submodules/TelegramApi/Sources/Api26.swift | 134 ++++++------- submodules/TelegramApi/Sources/Api27.swift | 182 ++++++++---------- submodules/TelegramApi/Sources/Api28.swift | 106 ++++++++++ submodules/TelegramApi/Sources/Api30.swift | 12 +- .../Sources/State/AppConfiguration.swift | 2 +- .../ManagedAppConfigurationUpdates.swift | 41 ++-- .../SyncCore/SyncCore_AppConfiguration.swift | 8 +- 9 files changed, 338 insertions(+), 263 deletions(-) diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 4f43d13390..45f4593eaf 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -993,6 +993,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1891070632] = { return Api.contacts.TopPeers.parse_topPeers($0) } dict[-1255369827] = { return Api.contacts.TopPeers.parse_topPeersDisabled($0) } dict[-567906571] = { return Api.contacts.TopPeers.parse_topPeersNotModified($0) } + dict[-585598930] = { return Api.help.AppConfig.parse_appConfig($0) } + dict[2094949405] = { return Api.help.AppConfig.parse_appConfigNotModified($0) } dict[-860107216] = { return Api.help.AppUpdate.parse_appUpdate($0) } dict[-1000708810] = { return Api.help.AppUpdate.parse_noAppUpdate($0) } dict[-2016381538] = { return Api.help.CountriesList.parse_countriesList($0) } @@ -1775,6 +1777,8 @@ public extension Api { _1.serialize(buffer, boxed) case let _1 as Api.contacts.TopPeers: _1.serialize(buffer, boxed) + case let _1 as Api.help.AppConfig: + _1.serialize(buffer, boxed) case let _1 as Api.help.AppUpdate: _1.serialize(buffer, boxed) case let _1 as Api.help.CountriesList: diff --git a/submodules/TelegramApi/Sources/Api25.swift b/submodules/TelegramApi/Sources/Api25.swift index e6f9177ef5..2cd6480b05 100644 --- a/submodules/TelegramApi/Sources/Api25.swift +++ b/submodules/TelegramApi/Sources/Api25.swift @@ -214,6 +214,60 @@ public extension Api.contacts { } } +public extension Api.help { + enum AppConfig: TypeConstructorDescription { + case appConfig(hash: Int32, config: Api.JSONValue) + case appConfigNotModified + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .appConfig(let hash, let config): + if boxed { + buffer.appendInt32(-585598930) + } + serializeInt32(hash, buffer: buffer, boxed: false) + config.serialize(buffer, true) + break + case .appConfigNotModified: + if boxed { + buffer.appendInt32(2094949405) + } + + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .appConfig(let hash, let config): + return ("appConfig", [("hash", hash as Any), ("config", config as Any)]) + case .appConfigNotModified: + return ("appConfigNotModified", []) + } + } + + public static func parse_appConfig(_ reader: BufferReader) -> AppConfig? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Api.JSONValue? + if let signature = reader.readInt32() { + _2 = Api.parse(reader, signature: signature) as? Api.JSONValue + } + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return Api.help.AppConfig.appConfig(hash: _1!, config: _2!) + } + else { + return nil + } + } + public static func parse_appConfigNotModified(_ reader: BufferReader) -> AppConfig? { + return Api.help.AppConfig.appConfigNotModified + } + + } +} public extension Api.help { enum AppUpdate: TypeConstructorDescription { case appUpdate(flags: Int32, id: Int32, version: String, text: String, entities: [Api.MessageEntity], document: Api.Document?, url: String?, sticker: Api.Document?) @@ -1274,61 +1328,3 @@ public extension Api.messages { } } -public extension Api.messages { - enum AllStickers: TypeConstructorDescription { - case allStickers(hash: Int64, sets: [Api.StickerSet]) - case allStickersNotModified - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .allStickers(let hash, let sets): - if boxed { - buffer.appendInt32(-843329861) - } - serializeInt64(hash, buffer: buffer, boxed: false) - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(sets.count)) - for item in sets { - item.serialize(buffer, true) - } - break - case .allStickersNotModified: - if boxed { - buffer.appendInt32(-395967805) - } - - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .allStickers(let hash, let sets): - return ("allStickers", [("hash", hash as Any), ("sets", sets as Any)]) - case .allStickersNotModified: - return ("allStickersNotModified", []) - } - } - - public static func parse_allStickers(_ reader: BufferReader) -> AllStickers? { - var _1: Int64? - _1 = reader.readInt64() - var _2: [Api.StickerSet]? - if let _ = reader.readInt32() { - _2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerSet.self) - } - let _c1 = _1 != nil - let _c2 = _2 != nil - if _c1 && _c2 { - return Api.messages.AllStickers.allStickers(hash: _1!, sets: _2!) - } - else { - return nil - } - } - public static func parse_allStickersNotModified(_ reader: BufferReader) -> AllStickers? { - return Api.messages.AllStickers.allStickersNotModified - } - - } -} diff --git a/submodules/TelegramApi/Sources/Api26.swift b/submodules/TelegramApi/Sources/Api26.swift index 8ad3ca293a..89120cee9c 100644 --- a/submodules/TelegramApi/Sources/Api26.swift +++ b/submodules/TelegramApi/Sources/Api26.swift @@ -1,3 +1,61 @@ +public extension Api.messages { + enum AllStickers: TypeConstructorDescription { + case allStickers(hash: Int64, sets: [Api.StickerSet]) + case allStickersNotModified + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .allStickers(let hash, let sets): + if boxed { + buffer.appendInt32(-843329861) + } + serializeInt64(hash, buffer: buffer, boxed: false) + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(sets.count)) + for item in sets { + item.serialize(buffer, true) + } + break + case .allStickersNotModified: + if boxed { + buffer.appendInt32(-395967805) + } + + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .allStickers(let hash, let sets): + return ("allStickers", [("hash", hash as Any), ("sets", sets as Any)]) + case .allStickersNotModified: + return ("allStickersNotModified", []) + } + } + + public static func parse_allStickers(_ reader: BufferReader) -> AllStickers? { + var _1: Int64? + _1 = reader.readInt64() + var _2: [Api.StickerSet]? + if let _ = reader.readInt32() { + _2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerSet.self) + } + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return Api.messages.AllStickers.allStickers(hash: _1!, sets: _2!) + } + else { + return nil + } + } + public static func parse_allStickersNotModified(_ reader: BufferReader) -> AllStickers? { + return Api.messages.AllStickers.allStickersNotModified + } + + } +} public extension Api.messages { enum ArchivedStickers: TypeConstructorDescription { case archivedStickers(count: Int32, sets: [Api.StickerSetCovered]) @@ -1346,79 +1404,3 @@ public extension Api.messages { } } -public extension Api.messages { - enum HistoryImport: TypeConstructorDescription { - case historyImport(id: Int64) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .historyImport(let id): - if boxed { - buffer.appendInt32(375566091) - } - serializeInt64(id, buffer: buffer, boxed: false) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .historyImport(let id): - return ("historyImport", [("id", id as Any)]) - } - } - - public static func parse_historyImport(_ reader: BufferReader) -> HistoryImport? { - var _1: Int64? - _1 = reader.readInt64() - let _c1 = _1 != nil - if _c1 { - return Api.messages.HistoryImport.historyImport(id: _1!) - } - else { - return nil - } - } - - } -} -public extension Api.messages { - enum HistoryImportParsed: TypeConstructorDescription { - case historyImportParsed(flags: Int32, title: String?) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .historyImportParsed(let flags, let title): - if boxed { - buffer.appendInt32(1578088377) - } - serializeInt32(flags, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 2) != 0 {serializeString(title!, buffer: buffer, boxed: false)} - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .historyImportParsed(let flags, let title): - return ("historyImportParsed", [("flags", flags as Any), ("title", title as Any)]) - } - } - - public static func parse_historyImportParsed(_ reader: BufferReader) -> HistoryImportParsed? { - var _1: Int32? - _1 = reader.readInt32() - var _2: String? - if Int(_1!) & Int(1 << 2) != 0 {_2 = parseString(reader) } - let _c1 = _1 != nil - let _c2 = (Int(_1!) & Int(1 << 2) == 0) || _2 != nil - if _c1 && _c2 { - return Api.messages.HistoryImportParsed.historyImportParsed(flags: _1!, title: _2) - } - else { - return nil - } - } - - } -} diff --git a/submodules/TelegramApi/Sources/Api27.swift b/submodules/TelegramApi/Sources/Api27.swift index 3713973863..d66b56e838 100644 --- a/submodules/TelegramApi/Sources/Api27.swift +++ b/submodules/TelegramApi/Sources/Api27.swift @@ -1,3 +1,79 @@ +public extension Api.messages { + enum HistoryImport: TypeConstructorDescription { + case historyImport(id: Int64) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .historyImport(let id): + if boxed { + buffer.appendInt32(375566091) + } + serializeInt64(id, buffer: buffer, boxed: false) + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .historyImport(let id): + return ("historyImport", [("id", id as Any)]) + } + } + + public static func parse_historyImport(_ reader: BufferReader) -> HistoryImport? { + var _1: Int64? + _1 = reader.readInt64() + let _c1 = _1 != nil + if _c1 { + return Api.messages.HistoryImport.historyImport(id: _1!) + } + else { + return nil + } + } + + } +} +public extension Api.messages { + enum HistoryImportParsed: TypeConstructorDescription { + case historyImportParsed(flags: Int32, title: String?) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .historyImportParsed(let flags, let title): + if boxed { + buffer.appendInt32(1578088377) + } + serializeInt32(flags, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 2) != 0 {serializeString(title!, buffer: buffer, boxed: false)} + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .historyImportParsed(let flags, let title): + return ("historyImportParsed", [("flags", flags as Any), ("title", title as Any)]) + } + } + + public static func parse_historyImportParsed(_ reader: BufferReader) -> HistoryImportParsed? { + var _1: Int32? + _1 = reader.readInt32() + var _2: String? + if Int(_1!) & Int(1 << 2) != 0 {_2 = parseString(reader) } + let _c1 = _1 != nil + let _c2 = (Int(_1!) & Int(1 << 2) == 0) || _2 != nil + if _c1 && _c2 { + return Api.messages.HistoryImportParsed.historyImportParsed(flags: _1!, title: _2) + } + else { + return nil + } + } + + } +} public extension Api.messages { enum InactiveChats: TypeConstructorDescription { case inactiveChats(dates: [Int32], chats: [Api.Chat], users: [Api.User]) @@ -1342,109 +1418,3 @@ public extension Api.messages { } } -public extension Api.messages { - enum TranslatedText: TypeConstructorDescription { - case translateResult(result: [Api.TextWithEntities]) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .translateResult(let result): - if boxed { - buffer.appendInt32(870003448) - } - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(result.count)) - for item in result { - item.serialize(buffer, true) - } - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .translateResult(let result): - return ("translateResult", [("result", result as Any)]) - } - } - - public static func parse_translateResult(_ reader: BufferReader) -> TranslatedText? { - var _1: [Api.TextWithEntities]? - if let _ = reader.readInt32() { - _1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.TextWithEntities.self) - } - let _c1 = _1 != nil - if _c1 { - return Api.messages.TranslatedText.translateResult(result: _1!) - } - else { - return nil - } - } - - } -} -public extension Api.messages { - enum VotesList: TypeConstructorDescription { - case votesList(flags: Int32, count: Int32, votes: [Api.MessageUserVote], users: [Api.User], nextOffset: String?) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .votesList(let flags, let count, let votes, let users, let nextOffset): - if boxed { - buffer.appendInt32(136574537) - } - serializeInt32(flags, buffer: buffer, boxed: false) - serializeInt32(count, buffer: buffer, boxed: false) - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(votes.count)) - for item in votes { - item.serialize(buffer, true) - } - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(users.count)) - for item in users { - item.serialize(buffer, true) - } - if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)} - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .votesList(let flags, let count, let votes, let users, let nextOffset): - return ("votesList", [("flags", flags as Any), ("count", count as Any), ("votes", votes as Any), ("users", users as Any), ("nextOffset", nextOffset as Any)]) - } - } - - public static func parse_votesList(_ reader: BufferReader) -> VotesList? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Int32? - _2 = reader.readInt32() - var _3: [Api.MessageUserVote]? - if let _ = reader.readInt32() { - _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageUserVote.self) - } - var _4: [Api.User]? - if let _ = reader.readInt32() { - _4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) - } - var _5: String? - if Int(_1!) & Int(1 << 0) != 0 {_5 = parseString(reader) } - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = _4 != nil - let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 { - return Api.messages.VotesList.votesList(flags: _1!, count: _2!, votes: _3!, users: _4!, nextOffset: _5) - } - else { - return nil - } - } - - } -} diff --git a/submodules/TelegramApi/Sources/Api28.swift b/submodules/TelegramApi/Sources/Api28.swift index 508590d536..e46e068676 100644 --- a/submodules/TelegramApi/Sources/Api28.swift +++ b/submodules/TelegramApi/Sources/Api28.swift @@ -1,3 +1,109 @@ +public extension Api.messages { + enum TranslatedText: TypeConstructorDescription { + case translateResult(result: [Api.TextWithEntities]) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .translateResult(let result): + if boxed { + buffer.appendInt32(870003448) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(result.count)) + for item in result { + item.serialize(buffer, true) + } + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .translateResult(let result): + return ("translateResult", [("result", result as Any)]) + } + } + + public static func parse_translateResult(_ reader: BufferReader) -> TranslatedText? { + var _1: [Api.TextWithEntities]? + if let _ = reader.readInt32() { + _1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.TextWithEntities.self) + } + let _c1 = _1 != nil + if _c1 { + return Api.messages.TranslatedText.translateResult(result: _1!) + } + else { + return nil + } + } + + } +} +public extension Api.messages { + enum VotesList: TypeConstructorDescription { + case votesList(flags: Int32, count: Int32, votes: [Api.MessageUserVote], users: [Api.User], nextOffset: String?) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .votesList(let flags, let count, let votes, let users, let nextOffset): + if boxed { + buffer.appendInt32(136574537) + } + serializeInt32(flags, buffer: buffer, boxed: false) + serializeInt32(count, buffer: buffer, boxed: false) + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(votes.count)) + for item in votes { + item.serialize(buffer, true) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(users.count)) + for item in users { + item.serialize(buffer, true) + } + if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)} + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .votesList(let flags, let count, let votes, let users, let nextOffset): + return ("votesList", [("flags", flags as Any), ("count", count as Any), ("votes", votes as Any), ("users", users as Any), ("nextOffset", nextOffset as Any)]) + } + } + + public static func parse_votesList(_ reader: BufferReader) -> VotesList? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + var _3: [Api.MessageUserVote]? + if let _ = reader.readInt32() { + _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageUserVote.self) + } + var _4: [Api.User]? + if let _ = reader.readInt32() { + _4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) + } + var _5: String? + if Int(_1!) & Int(1 << 0) != 0 {_5 = parseString(reader) } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return Api.messages.VotesList.votesList(flags: _1!, count: _2!, votes: _3!, users: _4!, nextOffset: _5) + } + else { + return nil + } + } + + } +} public extension Api.payments { enum BankCardData: TypeConstructorDescription { case bankCardData(title: String, openUrls: [Api.BankCardOpenUrl]) diff --git a/submodules/TelegramApi/Sources/Api30.swift b/submodules/TelegramApi/Sources/Api30.swift index 49cfdf277e..b9d4642aa0 100644 --- a/submodules/TelegramApi/Sources/Api30.swift +++ b/submodules/TelegramApi/Sources/Api30.swift @@ -3334,15 +3334,15 @@ public extension Api.functions.help { } } public extension Api.functions.help { - static func getAppConfig() -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getAppConfig(hash: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(-1735311088) - - return (FunctionDescription(name: "help.getAppConfig", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.JSONValue? in + buffer.appendInt32(1642330196) + serializeInt32(hash, buffer: buffer, boxed: false) + return (FunctionDescription(name: "help.getAppConfig", parameters: [("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.help.AppConfig? in let reader = BufferReader(buffer) - var result: Api.JSONValue? + var result: Api.help.AppConfig? if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.JSONValue + result = Api.parse(reader, signature: signature) as? Api.help.AppConfig } return result }) diff --git a/submodules/TelegramCore/Sources/State/AppConfiguration.swift b/submodules/TelegramCore/Sources/State/AppConfiguration.swift index 0eb76d360e..d09420e45a 100644 --- a/submodules/TelegramCore/Sources/State/AppConfiguration.swift +++ b/submodules/TelegramCore/Sources/State/AppConfiguration.swift @@ -1,6 +1,6 @@ import Postbox -private func currentAppConfiguration(transaction: Transaction) -> AppConfiguration { +func currentAppConfiguration(transaction: Transaction) -> AppConfiguration { if let entry = transaction.getPreferencesEntry(key: PreferencesKeys.appConfiguration)?.get(AppConfiguration.self) { return entry } else { diff --git a/submodules/TelegramCore/Sources/State/ManagedAppConfigurationUpdates.swift b/submodules/TelegramCore/Sources/State/ManagedAppConfigurationUpdates.swift index adcc08bf2d..8b2ee5aa23 100644 --- a/submodules/TelegramCore/Sources/State/ManagedAppConfigurationUpdates.swift +++ b/submodules/TelegramCore/Sources/State/ManagedAppConfigurationUpdates.swift @@ -5,22 +5,35 @@ import TelegramApi import MtProtoKit func updateAppConfigurationOnce(postbox: Postbox, network: Network) -> Signal { - return network.request(Api.functions.help.getAppConfig()) - |> map(Optional.init) - |> `catch` { _ -> Signal in - return .single(nil) + return postbox.transaction { transaction -> Int32 in + return currentAppConfiguration(transaction: transaction).hash } - |> mapToSignal { result -> Signal in - guard let result = result else { - return .complete() + |> mapToSignal { hash -> Signal in + return network.request(Api.functions.help.getAppConfig(hash: hash)) + |> map { result -> (data: Api.JSONValue, hash: Int32)? in + switch result { + case let .appConfig(updatedHash, config): + return (config, updatedHash) + case .appConfigNotModified: + return nil + } } - return postbox.transaction { transaction -> Void in - if let data = JSON(apiJson: result) { - updateAppConfiguration(transaction: transaction, { configuration -> AppConfiguration in - var configuration = configuration - configuration.data = data - return configuration - }) + |> `catch` { _ -> Signal<(data: Api.JSONValue, hash: Int32)?, NoError> in + return .single(nil) + } + |> mapToSignal { result -> Signal in + guard let result = result else { + return .complete() + } + return postbox.transaction { transaction -> Void in + if let data = JSON(apiJson: result.data) { + updateAppConfiguration(transaction: transaction, { configuration -> AppConfiguration in + var configuration = configuration + configuration.data = data + configuration.hash = result.hash + return configuration + }) + } } } } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_AppConfiguration.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_AppConfiguration.swift index 40586d30fe..fa04d5db67 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_AppConfiguration.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_AppConfiguration.swift @@ -3,24 +3,28 @@ import Postbox public struct AppConfiguration: Codable, Equatable { public var data: JSON? + public var hash: Int32 public static var defaultValue: AppConfiguration { - return AppConfiguration(data: nil) + return AppConfiguration(data: nil, hash: 0) } - init(data: JSON?) { + init(data: JSON?, hash: Int32) { self.data = data + self.hash = hash } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: StringCodingKey.self) self.data = try container.decodeIfPresent(JSON.self, forKey: "data") + self.hash = (try container.decodeIfPresent(Int32.self, forKey: "storedHash")) ?? 0 } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: StringCodingKey.self) try container.encodeIfPresent(self.data, forKey: "data") + try container.encode(self.hash, forKey: "storedHash") } } From e7fdd14b237422072d2930a8ea1b709def78d465 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 14 Feb 2023 17:47:49 +0400 Subject: [PATCH 12/14] Load presentation data on background queue to avoid deadlock --- .../TelegramPresentationData/Sources/PresentationData.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TelegramPresentationData/Sources/PresentationData.swift b/submodules/TelegramPresentationData/Sources/PresentationData.swift index fcf94dde00..17ea8d3028 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationData.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationData.swift @@ -289,7 +289,7 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager deliverOn(Queue.mainQueue()) + |> deliverOn(Queue(name: "PresentationData-Load", qos: .userInteractive)) |> map { internalData -> InitialPresentationDataAndSettings in let localizationSettings: LocalizationSettings? if let current = internalData.localizationSettings?.get(LocalizationSettings.self) { From bb7ffa619182a59f2276cb548b42596a65e200e6 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 14 Feb 2023 17:48:09 +0400 Subject: [PATCH 13/14] Low power experiments --- .../Sources/NotificationService.swift | 69 +++--- .../Sources/AccountContext.swift | 2 + .../Sources/ChatListController.swift | 18 +- .../Sources/ChatListControllerNode.swift | 20 +- .../Sources/Node/ChatListItem.swift | 6 +- .../Sources/ReactionButtonListComponent.swift | 2 +- .../TwoFactorAuthDataInputScreen.swift | 89 ++++++-- .../Sources/TwoFactorAuthSplashScreen.swift | 7 +- .../Sources/ReactionContextNode.swift | 6 +- .../DataAndStorageSettingsController.swift | 31 ++- .../EnergySavingSettingsScreen.swift | 199 ++++++++++++++++++ .../DeleteAccountOptionsController.swift | 3 +- .../PrivacyAndSecurityController.swift | 45 ++-- .../Sources/SettingsController.swift | 3 +- ...nchronizeRecentlyUsedMediaOperations.swift | 14 +- .../Sources/EmojiPagerContentComponent.swift | 6 +- .../EntityKeyboardTopPanelComponent.swift | 2 +- .../Sources/TextNodeWithEntities.swift | 16 +- .../TelegramUI/Sources/AppDelegate.swift | 3 + .../Sources/ChatControllerNode.swift | 6 +- .../TelegramUI/Sources/ChatLoadingNode.swift | 12 +- .../Sources/ChatMessageDateHeader.swift | 2 +- .../Sources/SharedAccountContext.swift | 4 + .../Sources/MediaAutoDownloadSettings.swift | 93 +++++++- 24 files changed, 543 insertions(+), 115 deletions(-) create mode 100644 submodules/SettingsUI/Sources/Data and Storage/EnergySavingSettingsScreen.swift diff --git a/Telegram/NotificationService/Sources/NotificationService.swift b/Telegram/NotificationService/Sources/NotificationService.swift index 44d3bf0aa7..3312c333c5 100644 --- a/Telegram/NotificationService/Sources/NotificationService.swift +++ b/Telegram/NotificationService/Sources/NotificationService.swift @@ -718,7 +718,12 @@ private final class NotificationServiceHandler { let _ = (combineLatest(queue: self.queue, self.accountManager.accountRecords(), - self.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.inAppNotificationSettings, ApplicationSpecificSharedDataKeys.voiceCallSettings, SharedDataKeys.loggingSettings]) + self.accountManager.sharedData(keys: [ + ApplicationSpecificSharedDataKeys.inAppNotificationSettings, + ApplicationSpecificSharedDataKeys.voiceCallSettings, + ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings, + SharedDataKeys.loggingSettings + ]) ) |> take(1) |> deliverOn(self.queue)).start(next: { [weak self] records, sharedData in @@ -728,6 +733,14 @@ private final class NotificationServiceHandler { let loggingSettings = sharedData.entries[SharedDataKeys.loggingSettings]?.get(LoggingSettings.self) ?? LoggingSettings.defaultSettings Logger.shared.logToFile = loggingSettings.logToFile Logger.shared.logToConsole = loggingSettings.logToConsole + + var automaticMediaDownloadSettings: MediaAutoDownloadSettings + if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings]?.get(MediaAutoDownloadSettings.self) { + automaticMediaDownloadSettings = value + } else { + automaticMediaDownloadSettings = MediaAutoDownloadSettings.defaultSettings + } + let shouldSynchronizeState = automaticMediaDownloadSettings.energyUsageSettings.synchronizeInBackground if let keyId = notificationPayloadKeyId(data: payloadData) { outer: for listRecord in records.records { @@ -1406,34 +1419,38 @@ private final class NotificationServiceHandler { let pollSignal: Signal - stateManager.network.shouldKeepConnection.set(.single(true)) - if peerId.namespace == Namespaces.Peer.CloudChannel { - Logger.shared.log("NotificationService \(episode)", "Will poll channel \(peerId)") - - pollSignal = standalonePollChannelOnce( - accountPeerId: stateManager.accountPeerId, - postbox: stateManager.postbox, - network: stateManager.network, - peerId: peerId, - stateManager: stateManager - ) + if !shouldSynchronizeState { + pollSignal = .complete() } else { - Logger.shared.log("NotificationService \(episode)", "Will perform non-specific getDifference") - enum ControlError { - case restart - } - let signal = stateManager.standalonePollDifference() - |> castError(ControlError.self) - |> mapToSignal { result -> Signal in - if result { - return .complete() - } else { - return .fail(.restart) + stateManager.network.shouldKeepConnection.set(.single(true)) + if peerId.namespace == Namespaces.Peer.CloudChannel { + Logger.shared.log("NotificationService \(episode)", "Will poll channel \(peerId)") + + pollSignal = standalonePollChannelOnce( + accountPeerId: stateManager.accountPeerId, + postbox: stateManager.postbox, + network: stateManager.network, + peerId: peerId, + stateManager: stateManager + ) + } else { + Logger.shared.log("NotificationService \(episode)", "Will perform non-specific getDifference") + enum ControlError { + case restart } + let signal = stateManager.standalonePollDifference() + |> castError(ControlError.self) + |> mapToSignal { result -> Signal in + if result { + return .complete() + } else { + return .fail(.restart) + } + } + |> restartIfError + + pollSignal = signal } - |> restartIfError - - pollSignal = signal } let pollWithUpdatedContent: Signal diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 42a6cd51e4..6488380fee 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -751,6 +751,8 @@ public protocol SharedAccountContext: AnyObject { var currentInAppNotificationSettings: Atomic { get } var currentMediaInputSettings: Atomic { get } + var energyUsageSettings: EnergyUsageSettings { get } + var applicationBindings: TelegramApplicationBindings { get } var authorizationPushConfiguration: Signal { get } diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 033a104006..5323d57412 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -1754,12 +1754,19 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController Queue.mainQueue().after(1.0, { let _ = ( - self.context.engine.data.get(TelegramEngine.EngineData.Item.Notices.Notice(key: ApplicationSpecificNotice.forcedPasswordSetupKey())) - |> map { entry -> Int32? in - return entry?.get(ApplicationSpecificCounterNotice.self)?.value + self.context.engine.data.get( + TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId), + TelegramEngine.EngineData.Item.Notices.Notice(key: ApplicationSpecificNotice.forcedPasswordSetupKey()) + ) + |> map { peer, entry -> (phoneNumber: String?, nortice: Int32?) in + var phoneNumber: String? + if case let .user(user) = peer { + phoneNumber = user.phone + } + return (phoneNumber, entry?.get(ApplicationSpecificCounterNotice.self)?.value) } |> deliverOnMainQueue - ).start(next: { [weak self] value in + ).start(next: { [weak self] phoneNumber, value in guard let strongSelf = self else { return } @@ -1772,7 +1779,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController title: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_Title, text: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_Text, actionText: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_Action, - doneText: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_DoneAction + doneText: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_DoneAction, + phoneNumber: phoneNumber ))) controller.dismissConfirmation = { [weak controller] f in guard let strongSelf = self, let controller = controller else { diff --git a/submodules/ChatListUI/Sources/ChatListControllerNode.swift b/submodules/ChatListUI/Sources/ChatListControllerNode.swift index b9a3938c50..2d91aad817 100644 --- a/submodules/ChatListUI/Sources/ChatListControllerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListControllerNode.swift @@ -13,6 +13,7 @@ import SearchUI import ContextUI import AnimationCache import MultiAnimationRenderer +import TelegramUIPreferences enum ChatListContainerNodeFilter: Equatable { case all @@ -647,13 +648,26 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate { return (state, filterId) }) + let enablePreload = context.sharedContext.accountManager.sharedData(keys: Set([ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings])) + |> map { sharedData -> Bool in + var automaticMediaDownloadSettings: MediaAutoDownloadSettings + if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings]?.get(MediaAutoDownloadSettings.self) { + automaticMediaDownloadSettings = value + } else { + automaticMediaDownloadSettings = MediaAutoDownloadSettings.defaultSettings + } + return automaticMediaDownloadSettings.energyUsageSettings.autodownloadInBackground + } + |> distinctUntilChanged + if self.controlsHistoryPreload, case .chatList(groupId: .root) = self.location { self.context.account.viewTracker.chatListPreloadItems.set(combineLatest(queue: .mainQueue(), context.sharedContext.hasOngoingCall.get(), - itemNode.listNode.preloadItems.get() + itemNode.listNode.preloadItems.get(), + enablePreload ) - |> map { hasOngoingCall, preloadItems -> Set in - if hasOngoingCall { + |> map { hasOngoingCall, preloadItems, enablePreload -> Set in + if hasOngoingCall || !enablePreload { return Set() } else { return Set(preloadItems) diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 6be7db083f..392c8f668d 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -675,7 +675,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { animationCache: context.animationCache, animationRenderer: context.animationRenderer, content: titleTopicIconContent, - isVisibleForAnimations: currentNode?.visibilityStatus ?? false, + isVisibleForAnimations: (currentNode?.visibilityStatus ?? false) && context.sharedContext.energyUsageSettings.loopEmoji, action: nil ) @@ -2788,7 +2788,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { animationCache: item.interaction.animationCache, animationRenderer: item.interaction.animationRenderer, content: avatarIconContent, - isVisibleForAnimations: strongSelf.visibilityStatus, + isVisibleForAnimations: strongSelf.visibilityStatus && item.context.sharedContext.energyUsageSettings.loopEmoji, action: nil ) strongSelf.avatarIconComponent = avatarIconComponent @@ -3285,7 +3285,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { animationCache: item.interaction.animationCache, animationRenderer: item.interaction.animationRenderer, content: currentCredibilityIconContent, - isVisibleForAnimations: strongSelf.visibilityStatus, + isVisibleForAnimations: strongSelf.visibilityStatus && item.context.sharedContext.energyUsageSettings.loopEmoji, action: nil ) strongSelf.credibilityIconComponent = credibilityIconComponent diff --git a/submodules/Components/ReactionButtonListComponent/Sources/ReactionButtonListComponent.swift b/submodules/Components/ReactionButtonListComponent/Sources/ReactionButtonListComponent.swift index 35d2f8881a..3fdc76cb2a 100644 --- a/submodules/Components/ReactionButtonListComponent/Sources/ReactionButtonListComponent.swift +++ b/submodules/Components/ReactionButtonListComponent/Sources/ReactionButtonListComponent.swift @@ -170,7 +170,7 @@ public final class ReactionIconView: PortalSourceView { animationLayer.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize) - animationLayer.isVisibleForAnimations = animateIdle + animationLayer.isVisibleForAnimations = animateIdle && context.sharedContext.energyUsageSettings.loopEmoji } func reset() { diff --git a/submodules/PasswordSetupUI/Sources/TwoFactorAuthDataInputScreen.swift b/submodules/PasswordSetupUI/Sources/TwoFactorAuthDataInputScreen.swift index 5a23069496..bed5cfbedc 100644 --- a/submodules/PasswordSetupUI/Sources/TwoFactorAuthDataInputScreen.swift +++ b/submodules/PasswordSetupUI/Sources/TwoFactorAuthDataInputScreen.swift @@ -35,7 +35,7 @@ public enum TwoFactorDataInputMode { case authorized } - case password(doneText: String) + case password(phoneNumber: String?, doneText: String) case passwordRecoveryEmail(emailPattern: String, mode: PasswordRecoveryEmailMode, doneText: String) case passwordRecovery(recovery: Recovery, doneText: String) case emailAddress(password: String, hint: String, doneText: String) @@ -99,8 +99,11 @@ public final class TwoFactorDataInputScreen: ViewController { public override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - if case .rememberPassword = self.mode { + switch self.mode { + case .rememberPassword, .password: (self.displayNode as? TwoFactorDataInputScreenNode)?.focus() + default: + break } } @@ -110,7 +113,7 @@ public final class TwoFactorDataInputScreen: ViewController { return } switch strongSelf.mode { - case let .password(doneText): + case let .password(_, doneText): let values = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText if values.count != 2 { return @@ -924,7 +927,7 @@ public final class TwoFactorDataInputScreen: ViewController { } private enum TwoFactorDataInputTextNodeType { - case password(confirmation: Bool) + case password(phoneNumber: String?, confirmation: Bool) case email case code case hint @@ -984,6 +987,7 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega private let toggleTextHidden: (TwoFactorDataInputTextNode) -> Void private let backgroundNode: ASImageNode + private var shadowInputNode: TextFieldNode? private let inputNode: TextFieldNode private let hideButtonNode: HighlightableButtonNode private let clearButtonNode: HighlightableButtonNode @@ -1068,7 +1072,7 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega self.hideButtonNode = HighlightableButtonNode() switch mode { - case let .password(confirmation): + case let .password(phoneNumber, confirmation): self.inputNode.textField.keyboardType = .default self.inputNode.textField.isSecureTextEntry = true if confirmation { @@ -1076,29 +1080,68 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega } else { self.inputNode.textField.returnKeyType = .next } + if #available(iOS 12.0, *) { + if !confirmation, let phoneNumber { + let shadowInputNode = TextFieldNode() + shadowInputNode.textField.font = Font.regular(17.0) + shadowInputNode.textField.textColor = theme.list.freePlainInputField.primaryColor + shadowInputNode.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: Font.regular(17.0), textColor: theme.list.freePlainInputField.placeholderColor) + self.shadowInputNode = shadowInputNode + + + shadowInputNode.textField.textContentType = .username + shadowInputNode.textField.text = phoneNumber + } + + self.inputNode.textField.textContentType = .newPassword + self.inputNode.textField.passwordRules = UITextInputPasswordRules(descriptor: "minlength: 8;") + } self.hideButtonNode.isHidden = confirmation case .email: self.inputNode.textField.keyboardType = .emailAddress self.inputNode.textField.returnKeyType = .done self.hideButtonNode.isHidden = true + + if #available(iOS 12.0, *) { + self.inputNode.textField.textContentType = .emailAddress + } + + self.inputNode.textField.autocorrectionType = .no + self.inputNode.textField.autocapitalizationType = .none + self.inputNode.textField.spellCheckingType = .no + if #available(iOS 11.0, *) { + self.inputNode.textField.smartQuotesType = .no + self.inputNode.textField.smartDashesType = .no + self.inputNode.textField.smartInsertDeleteType = .no + } case .code: self.inputNode.textField.keyboardType = .numberPad self.inputNode.textField.returnKeyType = .done self.hideButtonNode.isHidden = true + + self.inputNode.textField.autocorrectionType = .no + self.inputNode.textField.autocapitalizationType = .none + self.inputNode.textField.spellCheckingType = .no + if #available(iOS 11.0, *) { + self.inputNode.textField.smartQuotesType = .no + self.inputNode.textField.smartDashesType = .no + self.inputNode.textField.smartInsertDeleteType = .no + } case .hint: self.inputNode.textField.keyboardType = .asciiCapable self.inputNode.textField.returnKeyType = .done self.hideButtonNode.isHidden = true + + self.inputNode.textField.autocorrectionType = .no + self.inputNode.textField.autocapitalizationType = .none + self.inputNode.textField.spellCheckingType = .no + if #available(iOS 11.0, *) { + self.inputNode.textField.smartQuotesType = .no + self.inputNode.textField.smartDashesType = .no + self.inputNode.textField.smartInsertDeleteType = .no + } } - self.inputNode.textField.autocorrectionType = .no - self.inputNode.textField.autocapitalizationType = .none - self.inputNode.textField.spellCheckingType = .no - if #available(iOS 11.0, *) { - self.inputNode.textField.smartQuotesType = .no - self.inputNode.textField.smartDashesType = .no - self.inputNode.textField.smartInsertDeleteType = .no - } self.inputNode.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance self.hideButtonNode.setImage(generateTextHiddenImage(color: theme.list.freePlainInputField.controlColor, on: false), for: []) @@ -1110,6 +1153,10 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega super.init() self.addSubnode(self.backgroundNode) + if let shadowInputNode = self.shadowInputNode { + shadowInputNode.alpha = 0.001 + self.addSubnode(shadowInputNode) + } self.addSubnode(self.inputNode) self.addSubnode(self.hideButtonNode) @@ -1179,6 +1226,10 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega let leftInset: CGFloat = 16.0 let rightInset: CGFloat = 38.0 + if let shadowInputNode = self.shadowInputNode { + transition.updateFrame(node: shadowInputNode, frame: CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: size.width - leftInset - rightInset, height: size.height))) + } + transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: size)) transition.updateFrame(node: self.inputNode, frame: CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: size.width - leftInset - rightInset, height: size.height))) transition.updateFrame(node: self.hideButtonNode, frame: CGRect(origin: CGPoint(x: size.width - rightInset - 4.0, y: 0.0), size: CGSize(width: rightInset + 4.0, height: size.height))) @@ -1299,7 +1350,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS var toggleTextHidden: ((TwoFactorDataInputTextNode) -> Void)? switch mode { - case .password: + case let .password(phoneNumber, _): title = presentationData.strings.TwoFactorSetup_Password_Title text = NSAttributedString(string: "", font: Font.regular(16.0), textColor: presentationData.theme.list.itemPrimaryTextColor) buttonText = presentationData.strings.TwoFactorSetup_Password_Action @@ -1307,7 +1358,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS changeEmailActionText = "" resendCodeActionText = "" inputNodes = [ - TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(confirmation: false), placeholder: presentationData.strings.TwoFactorSetup_Password_PlaceholderPassword, focusUpdated: { node, focused in + TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(phoneNumber: phoneNumber, confirmation: false), placeholder: presentationData.strings.TwoFactorSetup_Password_PlaceholderPassword, focusUpdated: { node, focused in focusUpdated?(node, focused) }, next: { node in next?(node) @@ -1316,7 +1367,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS }, toggleTextHidden: { node in toggleTextHidden?(node) }), - TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(confirmation: true), placeholder: presentationData.strings.TwoFactorSetup_Password_PlaceholderConfirmPassword, focusUpdated: { node, focused in + TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(phoneNumber: phoneNumber, confirmation: true), placeholder: presentationData.strings.TwoFactorSetup_Password_PlaceholderConfirmPassword, focusUpdated: { node, focused in focusUpdated?(node, focused) }, next: { node in next?(node) @@ -1334,7 +1385,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS changeEmailActionText = "" resendCodeActionText = "" inputNodes = [ - TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(confirmation: false), placeholder: presentationData.strings.TwoFactorSetup_PasswordRecovery_PlaceholderPassword, focusUpdated: { node, focused in + TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(phoneNumber: nil, confirmation: false), placeholder: presentationData.strings.TwoFactorSetup_PasswordRecovery_PlaceholderPassword, focusUpdated: { node, focused in focusUpdated?(node, focused) }, next: { node in next?(node) @@ -1343,7 +1394,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS }, toggleTextHidden: { node in toggleTextHidden?(node) }), - TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(confirmation: true), placeholder: presentationData.strings.TwoFactorSetup_PasswordRecovery_PlaceholderConfirmPassword, focusUpdated: { node, focused in + TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(phoneNumber: nil, confirmation: true), placeholder: presentationData.strings.TwoFactorSetup_PasswordRecovery_PlaceholderConfirmPassword, focusUpdated: { node, focused in focusUpdated?(node, focused) }, next: { node in next?(node) @@ -1453,7 +1504,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS changeEmailActionText = "" resendCodeActionText = "" inputNodes = [ - TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(confirmation: false), placeholder: presentationData.strings.TwoFactorRemember_Placeholder, focusUpdated: { node, focused in + TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(phoneNumber: nil, confirmation: false), placeholder: presentationData.strings.TwoFactorRemember_Placeholder, focusUpdated: { node, focused in focusUpdated?(node, focused) }, next: { node in next?(node) diff --git a/submodules/PasswordSetupUI/Sources/TwoFactorAuthSplashScreen.swift b/submodules/PasswordSetupUI/Sources/TwoFactorAuthSplashScreen.swift index 5d2912da32..acb4735354 100644 --- a/submodules/PasswordSetupUI/Sources/TwoFactorAuthSplashScreen.swift +++ b/submodules/PasswordSetupUI/Sources/TwoFactorAuthSplashScreen.swift @@ -18,17 +18,20 @@ public enum TwoFactorAuthSplashMode { public var text: String public var actionText: String public var doneText: String + public var phoneNumber: String? public init( title: String, text: String, actionText: String, - doneText: String + doneText: String, + phoneNumber: String? ) { self.title = title self.text = text self.actionText = actionText self.doneText = doneText + self.phoneNumber = phoneNumber } } @@ -100,7 +103,7 @@ public final class TwoFactorAuthSplashScreen: ViewController { } switch strongSelf.mode { case let .intro(intro): - strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .password(doneText: intro.doneText), stateUpdated: { _ in + strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .password(phoneNumber: intro.phoneNumber, doneText: intro.doneText), stateUpdated: { _ in }, presentation: strongSelf.navigationPresentation)) case .done, .remember: guard let navigationController = strongSelf.navigationController as? NavigationController else { diff --git a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift index 20f0abd45f..f2e7a8904c 100644 --- a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift +++ b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift @@ -735,9 +735,9 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate { } } - #if DEBUG - loopIdle = true - #endif + if !self.context.sharedContext.energyUsageSettings.loopEmoji { + loopIdle = false + } var validIndices = Set() var nextX: CGFloat = sideInset diff --git a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift index 5e6d8a8cee..472193a55c 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift @@ -33,12 +33,13 @@ private final class DataAndStorageControllerArguments { let toggleRaiseToListen: (Bool) -> Void let toggleAutoplayGifs: (Bool) -> Void let toggleAutoplayVideos: (Bool) -> Void + let openEnergySavingSettings: () -> Void let toggleDownloadInBackground: (Bool) -> Void let openBrowserSelection: () -> Void let openIntents: () -> Void let toggleEnableSensitiveContent: (Bool) -> Void - init(openStorageUsage: @escaping () -> Void, openNetworkUsage: @escaping () -> Void, openProxy: @escaping () -> Void, openAutomaticDownloadConnectionType: @escaping (AutomaticDownloadConnectionType) -> Void, resetAutomaticDownload: @escaping () -> Void, toggleVoiceUseLessData: @escaping (Bool) -> Void, openSaveIncoming: @escaping (AutomaticSaveIncomingPeerType) -> Void, toggleSaveEditedPhotos: @escaping (Bool) -> Void, togglePauseMusicOnRecording: @escaping (Bool) -> Void, toggleRaiseToListen: @escaping (Bool) -> Void, toggleAutoplayGifs: @escaping (Bool) -> Void, toggleAutoplayVideos: @escaping (Bool) -> Void, toggleDownloadInBackground: @escaping (Bool) -> Void, openBrowserSelection: @escaping () -> Void, openIntents: @escaping () -> Void, toggleEnableSensitiveContent: @escaping (Bool) -> Void) { + init(openStorageUsage: @escaping () -> Void, openNetworkUsage: @escaping () -> Void, openProxy: @escaping () -> Void, openAutomaticDownloadConnectionType: @escaping (AutomaticDownloadConnectionType) -> Void, resetAutomaticDownload: @escaping () -> Void, toggleVoiceUseLessData: @escaping (Bool) -> Void, openSaveIncoming: @escaping (AutomaticSaveIncomingPeerType) -> Void, toggleSaveEditedPhotos: @escaping (Bool) -> Void, togglePauseMusicOnRecording: @escaping (Bool) -> Void, toggleRaiseToListen: @escaping (Bool) -> Void, toggleAutoplayGifs: @escaping (Bool) -> Void, toggleAutoplayVideos: @escaping (Bool) -> Void, openEnergySavingSettings: @escaping () -> Void, toggleDownloadInBackground: @escaping (Bool) -> Void, openBrowserSelection: @escaping () -> Void, openIntents: @escaping () -> Void, toggleEnableSensitiveContent: @escaping (Bool) -> Void) { self.openStorageUsage = openStorageUsage self.openNetworkUsage = openNetworkUsage self.openProxy = openProxy @@ -51,6 +52,7 @@ private final class DataAndStorageControllerArguments { self.toggleRaiseToListen = toggleRaiseToListen self.toggleAutoplayGifs = toggleAutoplayGifs self.toggleAutoplayVideos = toggleAutoplayVideos + self.openEnergySavingSettings = openEnergySavingSettings self.toggleDownloadInBackground = toggleDownloadInBackground self.openBrowserSelection = openBrowserSelection self.openIntents = openIntents @@ -64,6 +66,7 @@ private enum DataAndStorageSection: Int32 { case autoSave case backgroundDownload case autoPlay + case energySaving case voiceCalls case other case connection @@ -107,6 +110,9 @@ private enum DataAndStorageEntry: ItemListNodeEntry { case autoplayHeader(PresentationTheme, String) case autoplayGifs(PresentationTheme, String, Bool) case autoplayVideos(PresentationTheme, String, Bool) + + case energySaving + case useLessVoiceData(PresentationTheme, String, Bool) case useLessVoiceDataInfo(PresentationTheme, String) case otherHeader(PresentationTheme, String) @@ -135,6 +141,8 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return DataAndStorageSection.voiceCalls.rawValue case .autoplayHeader, .autoplayGifs, .autoplayVideos: return DataAndStorageSection.autoPlay.rawValue + case .energySaving: + return DataAndStorageSection.energySaving.rawValue case .otherHeader, .shareSheet, .saveEditedPhotos, .openLinksIn, .pauseMusicOnRecording, .raiseToListen, .raiseToListenInfo: return DataAndStorageSection.other.rawValue case .connectionHeader, .connectionProxy: @@ -178,10 +186,12 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return 26 case .autoplayVideos: return 27 - case .otherHeader: + case .energySaving: return 28 - case .shareSheet: + case .otherHeader: return 29 + case .shareSheet: + return 30 case .saveEditedPhotos: return 31 case .openLinksIn: @@ -275,6 +285,12 @@ private enum DataAndStorageEntry: ItemListNodeEntry { } else { return false } + case .energySaving: + if case .energySaving = rhs { + return true + } else { + return false + } case let .useLessVoiceData(lhsTheme, lhsText, lhsValue): if case let .useLessVoiceData(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { return true @@ -424,6 +440,11 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleAutoplayVideos(value) }, tag: DataAndStorageEntryTag.autoplayVideos) + case .energySaving: + //TODO:localize + return ItemListDisclosureItem(presentationData: presentationData, title: "Energy Settings", label: "", sectionId: self.section, style: .blocks, action: { + arguments.openEnergySavingSettings() + }) case let .useLessVoiceData(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleVoiceUseLessData(value) @@ -667,6 +688,8 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat entries.append(.autoplayGifs(presentationData.theme, presentationData.strings.ChatSettings_AutoPlayGifs, data.automaticMediaDownloadSettings.autoplayGifs)) entries.append(.autoplayVideos(presentationData.theme, presentationData.strings.ChatSettings_AutoPlayVideos, data.automaticMediaDownloadSettings.autoplayVideos)) + entries.append(.energySaving) + entries.append(.otherHeader(presentationData.theme, presentationData.strings.ChatSettings_Other)) if #available(iOSApplicationExtension 13.2, iOS 13.2, *) { entries.append(.shareSheet(presentationData.theme, presentationData.strings.ChatSettings_IntentsSettings)) @@ -922,6 +945,8 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da settings.autoplayVideos = value return settings }).start() + }, openEnergySavingSettings: { + pushControllerImpl?(energySavingSettingsScreen(context: context)) }, toggleDownloadInBackground: { value in let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in var settings = settings diff --git a/submodules/SettingsUI/Sources/Data and Storage/EnergySavingSettingsScreen.swift b/submodules/SettingsUI/Sources/Data and Storage/EnergySavingSettingsScreen.swift new file mode 100644 index 0000000000..f8be70bf3f --- /dev/null +++ b/submodules/SettingsUI/Sources/Data and Storage/EnergySavingSettingsScreen.swift @@ -0,0 +1,199 @@ +import Foundation +import UIKit +import Display +import SwiftSignalKit +import Postbox +import TelegramCore +import TelegramPresentationData +import TelegramUIPreferences +import ItemListUI +import PresentationDataUtils +import AccountContext + +enum ItemType: CaseIterable { + case loopEmoji + case playVideoAvatars + case fullTranslucency + case extendBackgroundWork + case synchronizeInBackground + case autodownloadInBackground + + var settingsKeyPath: WritableKeyPath { + switch self { + case .loopEmoji: + return \.loopEmoji + case .playVideoAvatars: + return \.playVideoAvatars + case .fullTranslucency: + return \.fullTranslucency + case .extendBackgroundWork: + return \.extendBackgroundWork + case .synchronizeInBackground: + return \.synchronizeInBackground + case .autodownloadInBackground: + return \.autodownloadInBackground + } + } + + func title(strings: PresentationStrings) -> String { + //TODO:localize + switch self { + case .loopEmoji: + return "Loop Animated Emoji" + case .playVideoAvatars: + return "Play Video Avatars" + case .fullTranslucency: + return "Translucency Effects" + case .extendBackgroundWork: + return "Extended Background Time" + case .synchronizeInBackground: + return "Background Sync" + case .autodownloadInBackground: + return "Preload Media in Chats" + } + } +} + +private final class EnergeSavingSettingsScreenArguments { + let toggleAll: (Bool) -> Void + let toggleItem: (ItemType) -> Void + + init(toggleAll: @escaping (Bool) -> Void, toggleItem: @escaping (ItemType) -> Void) { + self.toggleAll = toggleAll + self.toggleItem = toggleItem + } +} + +private enum EnergeSavingSettingsScreenSection: Int32 { + case all + case items +} + +private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry { + enum StableId: Hashable { + case all + case item(ItemType) + } + + case all(Bool) + case item(index: Int, type: ItemType, value: Bool) + + var section: ItemListSectionId { + switch self { + case .all: + return EnergeSavingSettingsScreenSection.all.rawValue + case .item: + return EnergeSavingSettingsScreenSection.items.rawValue + } + } + + var sortIndex: Int { + switch self { + case .all: + return -1 + case let .item(index, _, _): + return index + } + } + + var stableId: StableId { + switch self { + case .all: + return .all + case let .item(_, type, _): + return .item(type) + } + } + + static func <(lhs: EnergeSavingSettingsScreenEntry, rhs: EnergeSavingSettingsScreenEntry) -> Bool { + return lhs.sortIndex < rhs.sortIndex + } + + func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { + let arguments = arguments as! EnergeSavingSettingsScreenArguments + switch self { + case let .all(value): + //TODO:localize + return ItemListSwitchItem(presentationData: presentationData, title: "Enable All", value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in + arguments.toggleAll(value) + }) + case let .item(_, type, value): + return ItemListSwitchItem(presentationData: presentationData, title: type.title(strings: presentationData.strings), value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in + arguments.toggleItem(type) + }) + } + } +} + +private func energeSavingSettingsScreenEntries( + presentationData: PresentationData, + settings: MediaAutoDownloadSettings +) -> [EnergeSavingSettingsScreenEntry] { + var entries: [EnergeSavingSettingsScreenEntry] = [] + + entries.append(.all(ItemType.allCases.allSatisfy({ item in settings.energyUsageSettings[keyPath: item.settingsKeyPath] }))) + + for type in ItemType.allCases { + entries.append(.item(index: entries.count, type: type, value: settings.energyUsageSettings[keyPath: type.settingsKeyPath])) + } + + return entries +} + +func energySavingSettingsScreen(context: AccountContext) -> ViewController { + var pushControllerImpl: ((ViewController) -> Void)? + let _ = pushControllerImpl + + let arguments = EnergeSavingSettingsScreenArguments( + toggleAll: { value in + let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in + var settings = settings + for type in ItemType.allCases { + settings.energyUsageSettings[keyPath: type.settingsKeyPath] = value + } + return settings + }).start() + }, + toggleItem: { type in + let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in + var settings = settings + settings.energyUsageSettings[keyPath: type.settingsKeyPath] = !settings.energyUsageSettings[keyPath: type.settingsKeyPath] + return settings + }).start() + } + ) + + let signal = combineLatest( + context.sharedContext.presentationData, + context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings])) + |> deliverOnMainQueue + |> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState, Any)) in + var automaticMediaDownloadSettings: MediaAutoDownloadSettings + if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings]?.get(MediaAutoDownloadSettings.self) { + automaticMediaDownloadSettings = value + } else { + automaticMediaDownloadSettings = MediaAutoDownloadSettings.defaultSettings + } + + //TODO:localize + let controllerState = ItemListControllerState( + presentationData: ItemListPresentationData(presentationData), + title: .text("Energy Saving"), + leftNavigationButton: nil, + rightNavigationButton: nil, + backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), + animateChanges: false + ) + let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: energeSavingSettingsScreenEntries(presentationData: presentationData, settings: automaticMediaDownloadSettings), style: .blocks, emptyStateItem: nil, animateChanges: true) + + return (controllerState, (listState, arguments)) + } + + let controller = ItemListController(context: context, state: signal) + pushControllerImpl = { [weak controller] c in + if let controller = controller { + (controller.navigationController as? NavigationController)?.pushViewController(c) + } + } + return controller +} diff --git a/submodules/SettingsUI/Sources/DeleteAccountOptionsController.swift b/submodules/SettingsUI/Sources/DeleteAccountOptionsController.swift index 51c95be1a2..cf57cc61cf 100644 --- a/submodules/SettingsUI/Sources/DeleteAccountOptionsController.swift +++ b/submodules/SettingsUI/Sources/DeleteAccountOptionsController.swift @@ -248,7 +248,8 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo title: presentationData.strings.TwoFactorSetup_Intro_Title, text: presentationData.strings.TwoFactorSetup_Intro_Text, actionText: presentationData.strings.TwoFactorSetup_Intro_Action, - doneText: presentationData.strings.TwoFactorSetup_Done_Action + doneText: presentationData.strings.TwoFactorSetup_Done_Action, + phoneNumber: nil ))) replaceTopControllerImpl?(controller, false) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift index d204760334..efa3ed0b0e 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift @@ -944,28 +944,37 @@ public func privacyAndSecurityController( } }) }, openTwoStepVerification: { data in - if let data = data { - switch data { - case .set: - break - case let .notSet(pendingEmail): - if pendingEmail == nil { - let presentationData = context.sharedContext.currentPresentationData.with { $0 } - let controller = TwoFactorAuthSplashScreen(sharedContext: context.sharedContext, engine: .authorized(context.engine), mode: .intro(.init( - title: presentationData.strings.TwoFactorSetup_Intro_Title, - text: presentationData.strings.TwoFactorSetup_Intro_Text, - actionText: presentationData.strings.TwoFactorSetup_Intro_Action, - doneText: presentationData.strings.TwoFactorSetup_Done_Action - ))) + let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)) + |> deliverOnMainQueue).start(next: { peer in + if let data = data { + switch data { + case .set: + break + case let .notSet(pendingEmail): + if pendingEmail == nil { + var phoneNumber: String? + if case let .user(user) = peer { + phoneNumber = user.phone + } + + let presentationData = context.sharedContext.currentPresentationData.with { $0 } + let controller = TwoFactorAuthSplashScreen(sharedContext: context.sharedContext, engine: .authorized(context.engine), mode: .intro(.init( + title: presentationData.strings.TwoFactorSetup_Intro_Title, + text: presentationData.strings.TwoFactorSetup_Intro_Text, + actionText: presentationData.strings.TwoFactorSetup_Intro_Action, + doneText: presentationData.strings.TwoFactorSetup_Done_Action, + phoneNumber: phoneNumber + ))) - pushControllerImpl?(controller, true) - return + pushControllerImpl?(controller, true) + return + } } } - } - let controller = twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: false, data: data.flatMap({ Signal.single(.access(configuration: $0)) }))) - pushControllerImpl?(controller, true) + let controller = twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: false, data: data.flatMap({ Signal.single(.access(configuration: $0)) }))) + pushControllerImpl?(controller, true) + }) }, openActiveSessions: { pushControllerImpl?(recentSessionsController(context: context, activeSessionsContext: activeSessionsContext, webSessionsContext: webSessionsContext, websitesOnly: true), true) }, toggleArchiveAndMuteNonContacts: { archiveValue in diff --git a/submodules/SettingsUI/Sources/SettingsController.swift b/submodules/SettingsUI/Sources/SettingsController.swift index dfc7d821a3..46e9f09be4 100644 --- a/submodules/SettingsUI/Sources/SettingsController.swift +++ b/submodules/SettingsUI/Sources/SettingsController.swift @@ -21,7 +21,8 @@ public func makeSetupTwoFactorAuthController(context: AccountContext) -> ViewCon title: presentationData.strings.TwoFactorSetup_Intro_Title, text: presentationData.strings.TwoFactorSetup_Intro_Text, actionText: presentationData.strings.TwoFactorSetup_Intro_Action, - doneText: presentationData.strings.TwoFactorSetup_Done_Action + doneText: presentationData.strings.TwoFactorSetup_Done_Action, + phoneNumber: nil ))) return controller } diff --git a/submodules/TelegramCore/Sources/State/SynchronizeRecentlyUsedMediaOperations.swift b/submodules/TelegramCore/Sources/State/SynchronizeRecentlyUsedMediaOperations.swift index 714ebe6242..fd0ef9b6aa 100644 --- a/submodules/TelegramCore/Sources/State/SynchronizeRecentlyUsedMediaOperations.swift +++ b/submodules/TelegramCore/Sources/State/SynchronizeRecentlyUsedMediaOperations.swift @@ -15,15 +15,21 @@ func addSynchronizeRecentlyUsedMediaOperation(transaction: Transaction, category } let peerId = PeerId(0) - var topOperation: (SynchronizeRecentlyUsedMediaOperation, Int32)? + var removeOperations: [(SynchronizeRecentlyUsedMediaOperation, Int32)] = [] transaction.operationLogEnumerateEntries(peerId: peerId, tag: tag, { entry in if let operation = entry.contents as? SynchronizeRecentlyUsedMediaOperation { - topOperation = (operation, entry.tagLocalIndex) + if case .sync = operation.content { + removeOperations.append((operation, entry.tagLocalIndex)) + return true + } else { + return false + } + } else { + return false } - return false }) - if let (topOperation, topLocalIndex) = topOperation, case .sync = topOperation.content { + for (_, topLocalIndex) in removeOperations { let _ = transaction.operationLogRemoveEntry(peerId: peerId, tag: tag, tagLocalIndex: topLocalIndex) } diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift index 9f0013fb96..621cc090f1 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift @@ -1342,7 +1342,7 @@ private final class GroupEmbeddedView: UIScrollView, UIScrollViewDelegate, Pager let itemFrame = itemLayout.frame(at: index) itemLayer.frame = itemFrame - itemLayer.isVisibleForAnimations = true + itemLayer.isVisibleForAnimations = context.sharedContext.energyUsageSettings.loopEmoji } } @@ -2160,7 +2160,7 @@ private final class EmptySearchResultsView: UIView { animationCache: context.animationCache, animationRenderer: context.animationRenderer, content: .animation(content: .file(file: file), size: CGSize(width: 32.0, height: 32.0), placeholderColor: titleColor, themeColor: nil, loopMode: .forever), - isVisibleForAnimations: true, + isVisibleForAnimations: context.sharedContext.energyUsageSettings.loopEmoji, action: nil )), environment: {}, @@ -5795,7 +5795,7 @@ public final class EmojiPagerContentComponent: Component { placeholderView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1) } - itemLayer.isVisibleForAnimations = keyboardChildEnvironment.isContentInFocus + itemLayer.isVisibleForAnimations = keyboardChildEnvironment.isContentInFocus && component.context.sharedContext.energyUsageSettings.loopEmoji } } if itemGroup.fillWithLoadingPlaceholders { diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EntityKeyboardTopPanelComponent.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EntityKeyboardTopPanelComponent.swift index c87fe101c6..34303c44e6 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EntityKeyboardTopPanelComponent.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EntityKeyboardTopPanelComponent.swift @@ -167,7 +167,7 @@ final class EntityKeyboardAnimationTopPanelComponent: Component { itemLayer.layerTintColor = component.theme.list.itemAccentColor.cgColor } - itemLayer.isVisibleForAnimations = itemEnvironment.isContentInFocus + itemLayer.isVisibleForAnimations = itemEnvironment.isContentInFocus && component.context.sharedContext.energyUsageSettings.loopEmoji } if itemEnvironment.isExpanded { diff --git a/submodules/TelegramUI/Components/TextNodeWithEntities/Sources/TextNodeWithEntities.swift b/submodules/TelegramUI/Components/TextNodeWithEntities/Sources/TextNodeWithEntities.swift index e7140a7d5f..0f14ae00ab 100644 --- a/submodules/TelegramUI/Components/TextNodeWithEntities/Sources/TextNodeWithEntities.swift +++ b/submodules/TelegramUI/Components/TextNodeWithEntities/Sources/TextNodeWithEntities.swift @@ -93,6 +93,8 @@ public final class TextNodeWithEntities { public let textNode: TextNode private var inlineStickerItemLayers: [InlineStickerItemLayer.Key: InlineStickerItemLayer] = [:] + private var enableLooping: Bool = true + public var visibilityRect: CGRect? { didSet { if !self.inlineStickerItemLayers.isEmpty && oldValue != self.visibilityRect { @@ -107,7 +109,7 @@ public final class TextNodeWithEntities { } else { isItemVisible = false } - itemLayer.isVisibleForAnimations = isItemVisible + itemLayer.isVisibleForAnimations = self.enableLooping && isItemVisible } } } @@ -218,6 +220,8 @@ public final class TextNodeWithEntities { } private func updateInlineStickers(context: AccountContext, cache: AnimationCache, renderer: MultiAnimationRenderer, textLayout: TextNodeLayout?, placeholderColor: UIColor, attemptSynchronousLoad: Bool) { + self.enableLooping = context.sharedContext.energyUsageSettings.loopEmoji + var nextIndexById: [Int64: Int] = [:] var validIds: [InlineStickerItemLayer.Key] = [] @@ -250,7 +254,7 @@ public final class TextNodeWithEntities { self.inlineStickerItemLayers[id] = itemLayer self.textNode.layer.addSublayer(itemLayer) - itemLayer.isVisibleForAnimations = self.isItemVisible(itemRect: itemFrame) + itemLayer.isVisibleForAnimations = self.enableLooping && self.isItemVisible(itemRect: itemFrame) } itemLayer.frame = itemFrame @@ -284,6 +288,8 @@ public class ImmediateTextNodeWithEntities: TextNode { public var cutout: TextNodeCutout? public var displaySpoilers = false + private var enableLooping: Bool = true + public var arguments: TextNodeWithEntities.Arguments? private var inlineStickerItemLayers: [InlineStickerItemLayer.Key: InlineStickerItemLayer] = [:] @@ -293,7 +299,7 @@ public class ImmediateTextNodeWithEntities: TextNode { if !self.inlineStickerItemLayers.isEmpty && oldValue != self.visibility { for (_, itemLayer) in self.inlineStickerItemLayers { let isItemVisible: Bool = self.visibility - itemLayer.isVisibleForAnimations = isItemVisible + itemLayer.isVisibleForAnimations = self.enableLooping && isItemVisible } } } @@ -385,6 +391,8 @@ public class ImmediateTextNodeWithEntities: TextNode { } private func updateInlineStickers(context: AccountContext, cache: AnimationCache, renderer: MultiAnimationRenderer, textLayout: TextNodeLayout?, placeholderColor: UIColor) { + self.enableLooping = context.sharedContext.energyUsageSettings.loopEmoji + var nextIndexById: [Int64: Int] = [:] var validIds: [InlineStickerItemLayer.Key] = [] @@ -415,7 +423,7 @@ public class ImmediateTextNodeWithEntities: TextNode { self.inlineStickerItemLayers[id] = itemLayer self.layer.addSublayer(itemLayer) - itemLayer.isVisibleForAnimations = self.visibility + itemLayer.isVisibleForAnimations = self.enableLooping && self.visibility } itemLayer.frame = itemFrame diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index 7f80ca3dcb..97aa66f2ed 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -1646,6 +1646,9 @@ private func extractAccountManagerState(records: AccountRecordsView deliverOnMainQueue).start(next: { [weak self] peerView in guard let strongSelf = self else { diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index e51a3e7fe8..bf6ef37eb3 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -152,6 +152,10 @@ public final class SharedAccountContextImpl: SharedAccountContext { return self._automaticMediaDownloadSettings.get() } + public var energyUsageSettings: EnergyUsageSettings { + return self.currentAutomaticMediaDownloadSettings.with({ $0 }).energyUsageSettings + } + public let currentAutodownloadSettings: Atomic private let _autodownloadSettings = Promise() private var currentAutodownloadSettingsDisposable = MetaDisposable() diff --git a/submodules/TelegramUIPreferences/Sources/MediaAutoDownloadSettings.swift b/submodules/TelegramUIPreferences/Sources/MediaAutoDownloadSettings.swift index d8bb198bb3..7e65ec0a63 100644 --- a/submodules/TelegramUIPreferences/Sources/MediaAutoDownloadSettings.swift +++ b/submodules/TelegramUIPreferences/Sources/MediaAutoDownloadSettings.swift @@ -258,6 +258,73 @@ public struct MediaAutoSaveSettings: Codable, Equatable { } } +public struct EnergyUsageSettings: Codable, Equatable { + private enum CodingKeys: CodingKey { + case loopEmoji + case playVideoAvatars + case fullTranslucency + case extendBackgroundWork + case synchronizeInBackground + case autodownloadInBackground + } + + public static var `default`: EnergyUsageSettings { + return EnergyUsageSettings( + loopEmoji: true, + playVideoAvatars: true, + fullTranslucency: true, + extendBackgroundWork: true, + synchronizeInBackground: true, + autodownloadInBackground: true + ) + } + + public var loopEmoji: Bool + public var playVideoAvatars: Bool + public var fullTranslucency: Bool + public var extendBackgroundWork: Bool + public var synchronizeInBackground: Bool + public var autodownloadInBackground: Bool + + public init( + loopEmoji: Bool, + playVideoAvatars: Bool, + fullTranslucency: Bool, + extendBackgroundWork: Bool, + synchronizeInBackground: Bool, + autodownloadInBackground: Bool + ) { + self.loopEmoji = loopEmoji + self.playVideoAvatars = playVideoAvatars + self.fullTranslucency = fullTranslucency + self.extendBackgroundWork = extendBackgroundWork + self.synchronizeInBackground = synchronizeInBackground + self.autodownloadInBackground = autodownloadInBackground + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + self.loopEmoji = try container.decodeIfPresent(Bool.self, forKey: .loopEmoji) ?? EnergyUsageSettings.default.loopEmoji + self.playVideoAvatars = try container.decodeIfPresent(Bool.self, forKey: .playVideoAvatars) ?? EnergyUsageSettings.default.playVideoAvatars + self.fullTranslucency = try container.decodeIfPresent(Bool.self, forKey: .fullTranslucency) ?? EnergyUsageSettings.default.fullTranslucency + self.extendBackgroundWork = try container.decodeIfPresent(Bool.self, forKey: .extendBackgroundWork) ?? EnergyUsageSettings.default.extendBackgroundWork + self.synchronizeInBackground = try container.decodeIfPresent(Bool.self, forKey: .synchronizeInBackground) ?? EnergyUsageSettings.default.synchronizeInBackground + self.autodownloadInBackground = try container.decodeIfPresent(Bool.self, forKey: .autodownloadInBackground) ?? EnergyUsageSettings.default.autodownloadInBackground + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(self.loopEmoji, forKey: .loopEmoji) + try container.encode(self.playVideoAvatars, forKey: .playVideoAvatars) + try container.encode(self.fullTranslucency, forKey: .fullTranslucency) + try container.encode(self.extendBackgroundWork, forKey: .extendBackgroundWork) + try container.encode(self.synchronizeInBackground, forKey: .synchronizeInBackground) + try container.encode(self.autodownloadInBackground, forKey: .autodownloadInBackground) + } +} + public struct MediaAutoDownloadSettings: Codable, Equatable { public var presets: MediaAutoDownloadPresets public var cellular: MediaAutoDownloadConnection @@ -267,27 +334,30 @@ public struct MediaAutoDownloadSettings: Codable, Equatable { public var autoplayVideos: Bool public var downloadInBackground: Bool + public var energyUsageSettings: EnergyUsageSettings + public static var defaultSettings: MediaAutoDownloadSettings { let mb: Int64 = 1024 * 1024 let presets = MediaAutoDownloadPresets(low: MediaAutoDownloadCategories(basePreset: .low, photo: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false), - video: MediaAutoDownloadCategory(contacts: false, otherPrivate: false, groups: false, channels: false, sizeLimit: 1 * mb, predownload: false), - file: MediaAutoDownloadCategory(contacts: false, otherPrivate: false, groups: false, channels: false, sizeLimit: 1 * mb, predownload: false)), - medium: MediaAutoDownloadCategories(basePreset: .medium, photo: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false), - video: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: Int64(2.5 * CGFloat(mb)), predownload: false), - file: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false)), - high: MediaAutoDownloadCategories(basePreset: .high, photo: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false), - video: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 10 * mb, predownload: true), - file: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 3 * mb, predownload: false))) - return MediaAutoDownloadSettings(presets: presets, cellular: MediaAutoDownloadConnection(enabled: true, preset: .medium, custom: nil), wifi: MediaAutoDownloadConnection(enabled: true, preset: .high, custom: nil), autoplayGifs: true, autoplayVideos: true, downloadInBackground: true) + video: MediaAutoDownloadCategory(contacts: false, otherPrivate: false, groups: false, channels: false, sizeLimit: 1 * mb, predownload: false), + file: MediaAutoDownloadCategory(contacts: false, otherPrivate: false, groups: false, channels: false, sizeLimit: 1 * mb, predownload: false)), + medium: MediaAutoDownloadCategories(basePreset: .medium, photo: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false), + video: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: Int64(2.5 * CGFloat(mb)), predownload: false), + file: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false)), + high: MediaAutoDownloadCategories(basePreset: .high, photo: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false), + video: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 10 * mb, predownload: true), + file: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 3 * mb, predownload: false))) + return MediaAutoDownloadSettings(presets: presets, cellular: MediaAutoDownloadConnection(enabled: true, preset: .medium, custom: nil), wifi: MediaAutoDownloadConnection(enabled: true, preset: .high, custom: nil), autoplayGifs: true, autoplayVideos: true, downloadInBackground: true, energyUsageSettings: EnergyUsageSettings.default) } - public init(presets: MediaAutoDownloadPresets, cellular: MediaAutoDownloadConnection, wifi: MediaAutoDownloadConnection, autoplayGifs: Bool, autoplayVideos: Bool, downloadInBackground: Bool) { + public init(presets: MediaAutoDownloadPresets, cellular: MediaAutoDownloadConnection, wifi: MediaAutoDownloadConnection, autoplayGifs: Bool, autoplayVideos: Bool, downloadInBackground: Bool, energyUsageSettings: EnergyUsageSettings) { self.presets = presets self.cellular = cellular self.wifi = wifi self.autoplayGifs = autoplayGifs self.autoplayVideos = autoplayGifs self.downloadInBackground = downloadInBackground + self.energyUsageSettings = energyUsageSettings } public init(from decoder: Decoder) throws { @@ -303,6 +373,8 @@ public struct MediaAutoDownloadSettings: Codable, Equatable { self.autoplayGifs = try container.decode(Int32.self, forKey: "autoplayGifs") != 0 self.autoplayVideos = try container.decode(Int32.self, forKey: "autoplayVideos") != 0 self.downloadInBackground = try container.decode(Int32.self, forKey: "downloadInBackground") != 0 + + self.energyUsageSettings = (try container.decodeIfPresent(EnergyUsageSettings.self, forKey: "energyUsageSettings")) ?? EnergyUsageSettings.default } public func encode(to encoder: Encoder) throws { @@ -313,6 +385,7 @@ public struct MediaAutoDownloadSettings: Codable, Equatable { try container.encode((self.autoplayGifs ? 1 : 0) as Int32, forKey: "autoplayGifs") try container.encode((self.autoplayVideos ? 1 : 0) as Int32, forKey: "autoplayVideos") try container.encode((self.downloadInBackground ? 1 : 0) as Int32, forKey: "downloadInBackground") + try container.encode(self.energyUsageSettings, forKey: "energyUsageSettings") } public func connectionSettings(for networkType: MediaAutoDownloadNetworkType) -> MediaAutoDownloadConnection { From b324029366216538f9317b8bbdbaf404856e71a9 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 14 Feb 2023 23:12:59 +0400 Subject: [PATCH 14/14] Energy settings --- .../Sources/AccountContext.swift | 2 +- ...ArchivedStickerPacksNoticeController.swift | 16 ++++----- .../Sources/Node/ChatListItem.swift | 2 +- submodules/Display/Source/DeviceMetrics.swift | 4 --- .../Sources/MediaInputPaneTrendingItem.swift | 2 +- .../Sources/InstantPageImageNode.swift | 4 +-- .../Sources/ItemListStickerPackItem.swift | 17 ++++----- .../GroupStickerPackSetupController.swift | 12 +++---- .../Sources/StickersCarouselComponent.swift | 2 +- .../DataAndStorageSettingsController.swift | 2 +- .../ArchivedStickerPacksController.swift | 10 +++--- .../FeaturedStickerPacksController.swift | 10 +++--- .../InstalledStickerPacksController.swift | 4 +-- .../Sources/ThemeCarouselItem.swift | 2 +- .../Sources/ThemePickerGridItem.swift | 2 +- .../Sources/StickerShimmerEffectNode.swift | 15 +++++--- .../StickerPackPreviewControllerNode.swift | 13 +++---- .../Sources/StickerPackPreviewGridItem.swift | 36 +++++++++---------- .../Sources/StickerPackScreen.swift | 2 +- .../Sources/ChatControllerInteraction.swift | 1 + .../Sources/EmojiPagerContentComponent.swift | 2 +- .../TelegramUI/Sources/ChatController.swift | 3 +- .../Sources/ChatControllerNode.swift | 2 +- .../TelegramUI/Sources/ChatEmptyNode.swift | 2 +- .../TelegramUI/Sources/ChatLoadingNode.swift | 4 +-- .../ChatMediaInputStickerGridItem.swift | 2 +- .../ChatMediaInputStickerPackItem.swift | 2 +- .../ChatMessageActionButtonsNode.swift | 2 +- .../ChatMessageAnimatedStickerItemNode.swift | 10 +++--- .../Sources/ChatMessageBubbleItemNode.swift | 2 +- .../ChatMessageDateAndStatusNode.swift | 4 +-- .../Sources/ChatMessageDateHeader.swift | 8 +++-- .../Sources/ChatMessageGiftItemNode.swift | 2 +- .../ChatMessageInstantVideoItemNode.swift | 6 ++-- ...atMessageInteractiveInstantVideoNode.swift | 6 ++-- ...ageProfilePhotoSuggestionContentNode.swift | 2 +- .../Sources/ChatMessageStickerItemNode.swift | 8 ++--- .../Sources/ChatMessageThreadInfoNode.swift | 2 +- .../TelegramUI/Sources/ChatQrCodeScreen.swift | 2 +- .../ChatRecentActionsControllerNode.swift | 4 +-- .../TelegramUI/Sources/ChatThemeScreen.swift | 2 +- ...ListContextResultsChatInputPanelItem.swift | 2 +- .../Sources/HorizontalStickerGridItem.swift | 35 +++++++++--------- ...rizontalStickersChatContextPanelNode.swift | 12 +++---- .../Sources/InChatPrefetchManager.swift | 2 +- .../Sources/InlineReactionSearchPanel.swift | 2 +- .../Sources/LargeEmojiActionSheetItem.swift | 2 +- .../Sources/SharedAccountContext.swift | 8 ++--- .../StickerPaneTrendingListGridItem.swift | 2 +- 49 files changed, 156 insertions(+), 144 deletions(-) diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 6488380fee..08a1158228 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -744,7 +744,7 @@ public protocol SharedAccountContext: AnyObject { var currentPresentationData: Atomic { get } var presentationData: Signal { get } - var currentAutomaticMediaDownloadSettings: Atomic { get } + var currentAutomaticMediaDownloadSettings: MediaAutoDownloadSettings { get } var automaticMediaDownloadSettings: Signal { get } var currentAutodownloadSettings: Atomic { get } var immediateExperimentalUISettings: ExperimentalUISettings { get } diff --git a/submodules/ArchivedStickerPacksNotice/Sources/ArchivedStickerPacksNoticeController.swift b/submodules/ArchivedStickerPacksNotice/Sources/ArchivedStickerPacksNoticeController.swift index 8e81d93b98..0e1062e7dc 100644 --- a/submodules/ArchivedStickerPacksNotice/Sources/ArchivedStickerPacksNoticeController.swift +++ b/submodules/ArchivedStickerPacksNotice/Sources/ArchivedStickerPacksNoticeController.swift @@ -31,8 +31,8 @@ private struct ArchivedStickersNoticeEntry: Comparable, Identifiable { return lhs.index < rhs.index } - func item(account: Account, presentationData: PresentationData) -> ListViewItem { - return ItemListStickerPackItem(presentationData: ItemListPresentationData(presentationData), account: account, packInfo: info, itemCount: self.count, topItem: topItem, unread: false, control: .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: true, sectionId: 0, action: { + func item(context: AccountContext, presentationData: PresentationData) -> ListViewItem { + return ItemListStickerPackItem(presentationData: ItemListPresentationData(presentationData), context: context, packInfo: info, itemCount: self.count, topItem: topItem, unread: false, control: .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: true, sectionId: 0, action: { }, setPackIdWithRevealedOptions: { current, previous in }, addPack: { }, removePack: { @@ -47,12 +47,12 @@ private struct ArchivedStickersNoticeTransition { let updates: [ListViewUpdateItem] } -private func preparedTransition(from fromEntries: [ArchivedStickersNoticeEntry], to toEntries: [ArchivedStickersNoticeEntry], account: Account, presentationData: PresentationData) -> ArchivedStickersNoticeTransition { +private func preparedTransition(from fromEntries: [ArchivedStickersNoticeEntry], to toEntries: [ArchivedStickersNoticeEntry], context: AccountContext, presentationData: PresentationData) -> ArchivedStickersNoticeTransition { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } - let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, presentationData: presentationData), directionHint: nil) } - let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, presentationData: presentationData), directionHint: nil) } + let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData), directionHint: nil) } + let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData), directionHint: nil) } return ArchivedStickersNoticeTransition(deletions: deletions, insertions: insertions, updates: updates) } @@ -79,7 +79,7 @@ private final class ArchivedStickersNoticeAlertContentNode: AlertContentNode { return self.isUserInteractionEnabled } - init(theme: AlertControllerTheme, account: Account, presentationData: PresentationData, archivedStickerPacks: [(StickerPackCollectionInfo, StickerPackItem?)], actions: [TextAlertAction]) { + init(theme: AlertControllerTheme, context: AccountContext, presentationData: PresentationData, archivedStickerPacks: [(StickerPackCollectionInfo, StickerPackItem?)], actions: [TextAlertAction]) { self.presentationData = presentationData self.archivedStickerPacks = archivedStickerPacks @@ -139,7 +139,7 @@ private final class ArchivedStickersNoticeAlertContentNode: AlertContentNode { index += 1 } - let transition = preparedTransition(from: [], to: entries, account: account, presentationData: presentationData) + let transition = preparedTransition(from: [], to: entries, context: context, presentationData: presentationData) self.enqueueTransition(transition) } @@ -304,7 +304,7 @@ public func archivedStickerPacksNoticeController(context: AccountContext, archiv let disposable = MetaDisposable() - let contentNode = ArchivedStickersNoticeAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), account: context.account, presentationData: presentationData, archivedStickerPacks: archivedStickerPacks, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: { + let contentNode = ArchivedStickersNoticeAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), context: context, presentationData: presentationData, archivedStickerPacks: archivedStickerPacks, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: { dismissImpl?() })]) diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 392c8f668d..087c8ed5c7 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -1318,7 +1318,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { if isKnown { let photo = personalPhoto ?? profilePhoto - if let photo = photo, !photo.videoRepresentations.isEmpty || photo.emojiMarkup != nil { + if let photo = photo, item.context.sharedContext.energyUsageSettings.loopEmoji, (!photo.videoRepresentations.isEmpty || photo.emojiMarkup != nil) { let videoNode: AvatarVideoNode if let current = strongSelf.avatarVideoNode { videoNode = current diff --git a/submodules/Display/Source/DeviceMetrics.swift b/submodules/Display/Source/DeviceMetrics.swift index aa738f44ac..283aa0f63c 100644 --- a/submodules/Display/Source/DeviceMetrics.swift +++ b/submodules/Display/Source/DeviceMetrics.swift @@ -14,10 +14,6 @@ public enum DeviceMetrics: CaseIterable, Equatable { var cpuCount: UInt32 = 0 sysctlbyname("hw.ncpu", &cpuCount, &length, nil, 0) - #if DEBUG - cpuCount = 2 - #endif - self.isGraphicallyCapable = cpuCount >= 6 } } diff --git a/submodules/FeaturedStickersScreen/Sources/MediaInputPaneTrendingItem.swift b/submodules/FeaturedStickersScreen/Sources/MediaInputPaneTrendingItem.swift index 871c3aee3c..5e45fc03fc 100644 --- a/submodules/FeaturedStickersScreen/Sources/MediaInputPaneTrendingItem.swift +++ b/submodules/FeaturedStickersScreen/Sources/MediaInputPaneTrendingItem.swift @@ -107,7 +107,7 @@ final class TrendingTopItemNode: ASDisplayNode { } if let placeholderNode = self.placeholderNode, let file = self.file { - placeholderNode.update(backgroundColor: backgroundColor, foregroundColor: foregroundColor, shimmeringColor: shimmeringColor, data: file.immediateThumbnailData, size: self.itemSize ?? CGSize(width: 75.0, height: 75.0)) + placeholderNode.update(backgroundColor: backgroundColor, foregroundColor: foregroundColor, shimmeringColor: shimmeringColor, data: file.immediateThumbnailData, size: self.itemSize ?? CGSize(width: 75.0, height: 75.0), enableEffect: true) } } diff --git a/submodules/InstantPageUI/Sources/InstantPageImageNode.swift b/submodules/InstantPageUI/Sources/InstantPageImageNode.swift index 02fe6e992f..4b2a6f0329 100644 --- a/submodules/InstantPageUI/Sources/InstantPageImageNode.swift +++ b/submodules/InstantPageUI/Sources/InstantPageImageNode.swift @@ -76,7 +76,7 @@ final class InstantPageImageNode: ASDisplayNode, InstantPageNode { let imageReference = ImageMediaReference.webPage(webPage: WebpageReference(webPage), media: image) self.imageNode.setSignal(chatMessagePhoto(postbox: context.account.postbox, userLocation: sourceLocation.userLocation, photoReference: imageReference)) - if !interactive || shouldDownloadMediaAutomatically(settings: context.sharedContext.currentAutomaticMediaDownloadSettings.with { $0 }, peerType: sourceLocation.peerType, networkType: MediaAutoDownloadNetworkType(context.account.immediateNetworkType), authorPeerId: nil, contactsPeerIds: Set(), media: image) { + if !interactive || shouldDownloadMediaAutomatically(settings: context.sharedContext.currentAutomaticMediaDownloadSettings, peerType: sourceLocation.peerType, networkType: MediaAutoDownloadNetworkType(context.account.immediateNetworkType), authorPeerId: nil, contactsPeerIds: Set(), media: image) { self.fetchedDisposable.set(chatMessagePhotoInteractiveFetched(context: context, userLocation: sourceLocation.userLocation, photoReference: imageReference, displayAtSize: nil, storeToDownloadsPeerId: nil).start()) } @@ -108,7 +108,7 @@ final class InstantPageImageNode: ASDisplayNode, InstantPageNode { } else if let file = media.media as? TelegramMediaFile { let fileReference = FileMediaReference.webPage(webPage: WebpageReference(webPage), media: file) if file.mimeType.hasPrefix("image/") { - if !interactive || shouldDownloadMediaAutomatically(settings: context.sharedContext.currentAutomaticMediaDownloadSettings.with { $0 }, peerType: sourceLocation.peerType, networkType: MediaAutoDownloadNetworkType(context.account.immediateNetworkType), authorPeerId: nil, contactsPeerIds: Set(), media: file) { + if !interactive || shouldDownloadMediaAutomatically(settings: context.sharedContext.currentAutomaticMediaDownloadSettings, peerType: sourceLocation.peerType, networkType: MediaAutoDownloadNetworkType(context.account.immediateNetworkType), authorPeerId: nil, contactsPeerIds: Set(), media: file) { _ = freeMediaFileInteractiveFetched(account: context.account, userLocation: sourceLocation.userLocation, fileReference: fileReference).start() } self.imageNode.setSignal(instantPageImageFile(account: context.account, userLocation: sourceLocation.userLocation, fileReference: fileReference, fetched: true)) diff --git a/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift b/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift index 1f437162bb..890828c391 100644 --- a/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift +++ b/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift @@ -12,6 +12,7 @@ import StickerResources import AnimatedStickerNode import TelegramAnimatedStickerNode import ShimmerEffect +import AccountContext public struct ItemListStickerPackItemEditing: Equatable { public var editable: Bool @@ -38,7 +39,7 @@ public enum ItemListStickerPackItemControl: Equatable { public final class ItemListStickerPackItem: ListViewItem, ItemListItem { let presentationData: ItemListPresentationData - let account: Account + let context: AccountContext let packInfo: StickerPackCollectionInfo let itemCount: String let topItem: StickerPackItem? @@ -54,9 +55,9 @@ public final class ItemListStickerPackItem: ListViewItem, ItemListItem { let removePack: () -> Void let toggleSelected: () -> Void - public init(presentationData: ItemListPresentationData, account: Account, packInfo: StickerPackCollectionInfo, itemCount: String, topItem: StickerPackItem?, unread: Bool, control: ItemListStickerPackItemControl, editing: ItemListStickerPackItemEditing, enabled: Bool, playAnimatedStickers: Bool, sectionId: ItemListSectionId, action: (() -> Void)?, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, addPack: @escaping () -> Void, removePack: @escaping () -> Void, toggleSelected: @escaping () -> Void) { + public init(presentationData: ItemListPresentationData, context: AccountContext, packInfo: StickerPackCollectionInfo, itemCount: String, topItem: StickerPackItem?, unread: Bool, control: ItemListStickerPackItemControl, editing: ItemListStickerPackItemEditing, enabled: Bool, playAnimatedStickers: Bool, sectionId: ItemListSectionId, action: (() -> Void)?, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, addPack: @escaping () -> Void, removePack: @escaping () -> Void, toggleSelected: @escaping () -> Void) { self.presentationData = presentationData - self.account = account + self.context = context self.packInfo = packInfo self.itemCount = itemCount self.topItem = topItem @@ -506,18 +507,18 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode { if fileUpdated { imageApply = makeImageLayout(TransformImageArguments(corners: ImageCorners(), imageSize: stillImageSize, boundingSize: stillImageSize, intrinsicInsets: UIEdgeInsets())) - updatedImageSignal = chatMessageStickerPackThumbnail(postbox: item.account.postbox, resource: representation.resource, nilIfEmpty: true) + updatedImageSignal = chatMessageStickerPackThumbnail(postbox: item.context.account.postbox, resource: representation.resource, nilIfEmpty: true) } case let .animated(resource, dimensions, _): imageSize = dimensions.cgSize.aspectFitted(imageBoundingSize) if fileUpdated { imageApply = makeImageLayout(TransformImageArguments(corners: ImageCorners(), imageSize: imageBoundingSize, boundingSize: imageBoundingSize, intrinsicInsets: UIEdgeInsets())) - updatedImageSignal = chatMessageStickerPackThumbnail(postbox: item.account.postbox, resource: resource, animated: true, nilIfEmpty: true) + updatedImageSignal = chatMessageStickerPackThumbnail(postbox: item.context.account.postbox, resource: resource, animated: true, nilIfEmpty: true) } } if fileUpdated, let resourceReference = resourceReference { - updatedFetchSignal = fetchedMediaResource(mediaBox: item.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: resourceReference) + updatedFetchSignal = fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: resourceReference) } } else { updatedImageSignal = .single({ _ in return nil }) @@ -768,7 +769,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode { strongSelf.animationNode = animationNode strongSelf.addSubnode(animationNode) - animationNode.setup(source: AnimatedStickerResourceSource(account: item.account, resource: resource, isVideo: isVideo), width: 80, height: 80, playbackMode: .loop, mode: .direct(cachePathPrefix: nil)) + animationNode.setup(source: AnimatedStickerResourceSource(account: item.context.account, resource: resource, isVideo: isVideo), width: 80, height: 80, playbackMode: .loop, mode: .direct(cachePathPrefix: nil)) } animationNode.visibility = strongSelf.visibility != .none && item.playAnimatedStickers animationNode.isHidden = !item.playAnimatedStickers @@ -794,7 +795,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode { placeholderNode.frame = imageFrame - placeholderNode.update(backgroundColor: nil, foregroundColor: item.presentationData.theme.list.disclosureArrowColor.blitOver(item.presentationData.theme.list.itemBlocksBackgroundColor, alpha: 0.55), shimmeringColor: item.presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), data: immediateThumbnailData, size: imageFrame.size, imageSize: imageSize.cgSize) + placeholderNode.update(backgroundColor: nil, foregroundColor: item.presentationData.theme.list.disclosureArrowColor.blitOver(item.presentationData.theme.list.itemBlocksBackgroundColor, alpha: 0.55), shimmeringColor: item.presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), data: immediateThumbnailData, size: imageFrame.size, enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency, imageSize: imageSize.cgSize) } if let updatedImageSignal = updatedImageSignal { diff --git a/submodules/PeerInfoUI/Sources/GroupStickerPackSetupController.swift b/submodules/PeerInfoUI/Sources/GroupStickerPackSetupController.swift index d7107012ed..b11aa2000a 100644 --- a/submodules/PeerInfoUI/Sources/GroupStickerPackSetupController.swift +++ b/submodules/PeerInfoUI/Sources/GroupStickerPackSetupController.swift @@ -13,15 +13,15 @@ import StickerPackPreviewUI import ItemListStickerPackItem private final class GroupStickerPackSetupControllerArguments { - let account: Account + let context: AccountContext let selectStickerPack: (StickerPackCollectionInfo) -> Void let openStickerPack: (StickerPackCollectionInfo) -> Void let updateSearchText: (String) -> Void let openStickersBot: () -> Void - init(account: Account, selectStickerPack: @escaping (StickerPackCollectionInfo) -> Void, openStickerPack: @escaping (StickerPackCollectionInfo) -> Void, updateSearchText: @escaping (String) -> Void, openStickersBot: @escaping () -> Void) { - self.account = account + init(context: AccountContext, selectStickerPack: @escaping (StickerPackCollectionInfo) -> Void, openStickerPack: @escaping (StickerPackCollectionInfo) -> Void, updateSearchText: @escaping (String) -> Void, openStickersBot: @escaping () -> Void) { + self.context = context self.selectStickerPack = selectStickerPack self.openStickerPack = openStickerPack self.updateSearchText = updateSearchText @@ -218,7 +218,7 @@ private enum GroupStickerPackEntry: ItemListNodeEntry { case let .packsTitle(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .pack(_, _, _, info, topItem, count, playAnimatedStickers, selected): - return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: selected ? .selection : .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: { + return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: selected ? .selection : .none, editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: { if selected { arguments.openStickerPack(info) } else { @@ -230,7 +230,7 @@ private enum GroupStickerPackEntry: ItemListNodeEntry { }, toggleSelected: { }) case let .currentPack(_, theme, strings, content): - return GroupStickerPackCurrentItem(theme: theme, strings: strings, account: arguments.account, content: content, sectionId: self.section, action: { + return GroupStickerPackCurrentItem(theme: theme, strings: strings, account: arguments.context.account, content: content, sectionId: self.section, action: { if case let .found(packInfo, _, _) = content { arguments.openStickerPack(packInfo) } @@ -385,7 +385,7 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres var presentStickerPackController: ((StickerPackCollectionInfo) -> Void)? - let arguments = GroupStickerPackSetupControllerArguments(account: context.account, selectStickerPack: { info in + let arguments = GroupStickerPackSetupControllerArguments(context: context, selectStickerPack: { info in searchText.set(info.shortName) }, openStickerPack: { info in presentStickerPackController?(info) diff --git a/submodules/PremiumUI/Sources/StickersCarouselComponent.swift b/submodules/PremiumUI/Sources/StickersCarouselComponent.swift index 14b5821d7b..1238fc5bfc 100644 --- a/submodules/PremiumUI/Sources/StickersCarouselComponent.swift +++ b/submodules/PremiumUI/Sources/StickersCarouselComponent.swift @@ -268,7 +268,7 @@ private class StickerNode: ASDisplayNode { if self.placeholderNode.supernode != nil { let placeholderFrame = CGRect(origin: CGPoint(x: -10.0, y: 0.0), size: imageSize) let thumbnailDimensions = PixelDimensions(width: 512, height: 512) - self.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: self.file.immediateThumbnailData, size: placeholderFrame.size, imageSize: thumbnailDimensions.cgSize) + self.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: self.file.immediateThumbnailData, size: placeholderFrame.size, enableEffect: true, imageSize: thumbnailDimensions.cgSize) self.placeholderNode.frame = placeholderFrame } } diff --git a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift index 472193a55c..ff452192d3 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift @@ -442,7 +442,7 @@ private enum DataAndStorageEntry: ItemListNodeEntry { }, tag: DataAndStorageEntryTag.autoplayVideos) case .energySaving: //TODO:localize - return ItemListDisclosureItem(presentationData: presentationData, title: "Energy Settings", label: "", sectionId: self.section, style: .blocks, action: { + return ItemListDisclosureItem(presentationData: presentationData, title: "Energy Saving", label: "", sectionId: self.section, style: .blocks, action: { arguments.openEnergySavingSettings() }) case let .useLessVoiceData(_, text, value): diff --git a/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift index 9ca55c66fd..e0301100f1 100644 --- a/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/ArchivedStickerPacksController.swift @@ -21,15 +21,15 @@ public enum ArchivedStickerPacksControllerMode { } private final class ArchivedStickerPacksControllerArguments { - let account: Account + let context: AccountContext let openStickerPack: (StickerPackCollectionInfo) -> Void let setPackIdWithRevealedOptions: (ItemCollectionId?, ItemCollectionId?) -> Void let addPack: (StickerPackCollectionInfo) -> Void let removePack: (StickerPackCollectionInfo) -> Void - init(account: Account, openStickerPack: @escaping (StickerPackCollectionInfo) -> Void, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, addPack: @escaping (StickerPackCollectionInfo) -> Void, removePack: @escaping (StickerPackCollectionInfo) -> Void) { - self.account = account + init(context: AccountContext, openStickerPack: @escaping (StickerPackCollectionInfo) -> Void, setPackIdWithRevealedOptions: @escaping (ItemCollectionId?, ItemCollectionId?) -> Void, addPack: @escaping (StickerPackCollectionInfo) -> Void, removePack: @escaping (StickerPackCollectionInfo) -> Void) { + self.context = context self.openStickerPack = openStickerPack self.setPackIdWithRevealedOptions = setPackIdWithRevealedOptions self.addPack = addPack @@ -135,7 +135,7 @@ private enum ArchivedStickerPacksEntry: ItemListNodeEntry { case let .info(_, text): return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) case let .pack(_, _, _, info, topItem, count, animatedStickers, enabled, editing): - return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: .installation(installed: false), editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { + return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: .installation(installed: false), editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { arguments.openStickerPack(info) }, setPackIdWithRevealedOptions: { current, previous in arguments.setPackIdWithRevealedOptions(current, previous) @@ -264,7 +264,7 @@ public func archivedStickerPacksController(context: AccountContext, mode: Archiv var presentStickerPackController: ((StickerPackCollectionInfo) -> Void)? - let arguments = ArchivedStickerPacksControllerArguments(account: context.account, openStickerPack: { info in + let arguments = ArchivedStickerPacksControllerArguments(context: context, openStickerPack: { info in presentStickerPackController?(info) }, setPackIdWithRevealedOptions: { packId, fromPackId in updateState { state in diff --git a/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift index 872d61209d..b0fc826149 100644 --- a/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/FeaturedStickerPacksController.swift @@ -13,13 +13,13 @@ import StickerPackPreviewUI import ItemListStickerPackItem private final class FeaturedStickerPacksControllerArguments { - let account: Account + let context: AccountContext let openStickerPack: (StickerPackCollectionInfo) -> Void let addPack: (StickerPackCollectionInfo) -> Void - init(account: Account, openStickerPack: @escaping (StickerPackCollectionInfo) -> Void, addPack: @escaping (StickerPackCollectionInfo) -> Void) { - self.account = account + init(context: AccountContext, openStickerPack: @escaping (StickerPackCollectionInfo) -> Void, addPack: @escaping (StickerPackCollectionInfo) -> Void) { + self.context = context self.openStickerPack = openStickerPack self.addPack = addPack } @@ -102,7 +102,7 @@ private enum FeaturedStickerPacksEntry: ItemListNodeEntry { let arguments = arguments as! FeaturedStickerPacksControllerArguments switch self { case let .pack(_, _, _, info, unread, topItem, count, playAnimatedStickers, installed): - return ItemListStickerPackItem(presentationData: presentationData, account: arguments.account, packInfo: info, itemCount: count, topItem: topItem, unread: unread, control: .installation(installed: installed), editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: { + return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: info, itemCount: count, topItem: topItem, unread: unread, control: .installation(installed: installed), editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: playAnimatedStickers, sectionId: self.section, action: { arguments.openStickerPack(info) }, setPackIdWithRevealedOptions: { _, _ in }, addPack: { @@ -168,7 +168,7 @@ public func featuredStickerPacksController(context: AccountContext) -> ViewContr var presentStickerPackController: ((StickerPackCollectionInfo) -> Void)? - let arguments = FeaturedStickerPacksControllerArguments(account: context.account, openStickerPack: { info in + let arguments = FeaturedStickerPacksControllerArguments(context: context, openStickerPack: { info in presentStickerPackController?(info) }, addPack: { info in let _ = (context.engine.stickers.loadedStickerPack(reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false) diff --git a/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift b/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift index fd4e23be83..de27010b32 100644 --- a/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift +++ b/submodules/SettingsUI/Sources/Stickers/InstalledStickerPacksController.swift @@ -451,7 +451,7 @@ private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry { case let .trendingPacksTitle(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .trendingPack(_, _, _, info, topItem, count, animatedStickers, unread, installed): - return ItemListStickerPackItem(presentationData: presentationData, account: arguments.context.account, packInfo: info, itemCount: count, topItem: topItem, unread: unread, control: .installation(installed: installed), editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { + return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: info, itemCount: count, topItem: topItem, unread: unread, control: .installation(installed: installed), editing: ItemListStickerPackItemEditing(editable: false, editing: false, revealed: false, reorderable: false, selectable: false), enabled: true, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { arguments.openStickerPack(info) }, setPackIdWithRevealedOptions: { _, _ in }, addPack: { @@ -466,7 +466,7 @@ private indirect enum InstalledStickerPacksEntry: ItemListNodeEntry { case let .packsTitle(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .pack(_, _, _, info, topItem, count, animatedStickers, enabled, editing, selected): - return ItemListStickerPackItem(presentationData: presentationData, account: arguments.context.account, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: editing.editing ? .check(checked: selected ?? false) : .none, editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { + return ItemListStickerPackItem(presentationData: presentationData, context: arguments.context, packInfo: info, itemCount: count, topItem: topItem, unread: false, control: editing.editing ? .check(checked: selected ?? false) : .none, editing: editing, enabled: enabled, playAnimatedStickers: animatedStickers, sectionId: self.section, action: { arguments.openStickerPack(info) }, setPackIdWithRevealedOptions: { current, previous in arguments.setPackIdWithRevealedOptions(current, previous) diff --git a/submodules/SettingsUI/Sources/ThemeCarouselItem.swift b/submodules/SettingsUI/Sources/ThemeCarouselItem.swift index 7b96c101e7..80fb839bf8 100644 --- a/submodules/SettingsUI/Sources/ThemeCarouselItem.swift +++ b/submodules/SettingsUI/Sources/ThemeCarouselItem.swift @@ -440,7 +440,7 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode { strongSelf.stickerFetchedDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)).start()) let thumbnailDimensions = PixelDimensions(width: 512, height: 512) - strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, imageSize: thumbnailDimensions.cgSize) + strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency, imageSize: thumbnailDimensions.cgSize) strongSelf.placeholderNode.frame = emojiFrame } diff --git a/submodules/SettingsUI/Sources/ThemePickerGridItem.swift b/submodules/SettingsUI/Sources/ThemePickerGridItem.swift index 54fd2d9aff..b2d3d19c4d 100644 --- a/submodules/SettingsUI/Sources/ThemePickerGridItem.swift +++ b/submodules/SettingsUI/Sources/ThemePickerGridItem.swift @@ -275,7 +275,7 @@ private final class ThemeGridThemeItemIconNode : ASDisplayNode { self.stickerFetchedDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .other, userContentType: .other, reference: MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)).start()) let thumbnailDimensions = PixelDimensions(width: 512, height: 512) - self.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, imageSize: thumbnailDimensions.cgSize) + self.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency, imageSize: thumbnailDimensions.cgSize) self.placeholderNode.frame = emojiFrame } diff --git a/submodules/ShimmerEffect/Sources/StickerShimmerEffectNode.swift b/submodules/ShimmerEffect/Sources/StickerShimmerEffectNode.swift index 2835c10c6d..ec51d66136 100644 --- a/submodules/ShimmerEffect/Sources/StickerShimmerEffectNode.swift +++ b/submodules/ShimmerEffect/Sources/StickerShimmerEffectNode.swift @@ -90,6 +90,8 @@ public class StickerShimmerEffectNode: ASDisplayNode { self.backdropNode = backdropNode self.insertSubnode(backdropNode, at: 0) + backdropNode.isHidden = self.effectNode.isHidden + self.effectNode.layer.compositingFilter = "screenBlendMode" } @@ -97,7 +99,7 @@ public class StickerShimmerEffectNode: ASDisplayNode { self.effectNode.updateAbsoluteRect(rect, within: containerSize) } - public func update(backgroundColor: UIColor?, foregroundColor: UIColor, shimmeringColor: UIColor, data: Data?, size: CGSize, imageSize: CGSize = CGSize(width: 512.0, height: 512.0)) { + public func update(backgroundColor: UIColor?, foregroundColor: UIColor, shimmeringColor: UIColor, data: Data?, size: CGSize, enableEffect: Bool, imageSize: CGSize = CGSize(width: 512.0, height: 512.0)) { if data == nil { return } @@ -112,13 +114,18 @@ public class StickerShimmerEffectNode: ASDisplayNode { self.currentSize = size self.backgroundNode.backgroundColor = foregroundColor + self.backgroundNode.isHidden = !enableEffect - self.effectNode.update(backgroundColor: backgroundColor == nil ? .clear : foregroundColor, foregroundColor: shimmeringColor, horizontal: true, effectSize: nil, globalTimeOffset: true, duration: nil) + if enableEffect { + self.effectNode.update(backgroundColor: backgroundColor == nil ? .clear : foregroundColor, foregroundColor: shimmeringColor, horizontal: true, effectSize: nil, globalTimeOffset: true, duration: nil) + } + self.effectNode.isHidden = !enableEffect + self.backdropNode?.isHidden = !enableEffect let bounds = CGRect(origin: CGPoint(), size: size) - let image = generateStickerPlaceholderImage(data: data, size: size, imageSize: imageSize, backgroundColor: backgroundColor, foregroundColor: .black) + let image = generateStickerPlaceholderImage(data: data, size: size, imageSize: imageSize, backgroundColor: backgroundColor, foregroundColor: enableEffect ? .black : foregroundColor) - if backgroundColor == nil { + if backgroundColor == nil && enableEffect { self.foregroundNode.image = nil let maskView: UIImageView diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewControllerNode.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewControllerNode.swift index 8ba9bfd247..658bb9213f 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewControllerNode.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewControllerNode.swift @@ -13,6 +13,7 @@ import TextFormat import AccountContext import ContextUI import StickerPeekUI +import AccountContext private struct StickerPackPreviewGridEntry: Comparable, Identifiable { let index: Int @@ -26,8 +27,8 @@ private struct StickerPackPreviewGridEntry: Comparable, Identifiable { return lhs.index < rhs.index } - func item(account: Account, interaction: StickerPackPreviewInteraction, theme: PresentationTheme) -> StickerPackPreviewGridItem { - return StickerPackPreviewGridItem(account: account, stickerItem: self.stickerItem, interaction: interaction, theme: theme, isPremium: false, isLocked: false, isEmpty: false) + func item(context: AccountContext, interaction: StickerPackPreviewInteraction, theme: PresentationTheme) -> StickerPackPreviewGridItem { + return StickerPackPreviewGridItem(context: context, stickerItem: self.stickerItem, interaction: interaction, theme: theme, isPremium: false, isLocked: false, isEmpty: false) } } @@ -36,12 +37,12 @@ private struct StickerPackPreviewGridTransaction { let insertions: [GridNodeInsertItem] let updates: [GridNodeUpdateItem] - init(previousList: [StickerPackPreviewGridEntry], list: [StickerPackPreviewGridEntry], account: Account, interaction: StickerPackPreviewInteraction, theme: PresentationTheme) { + init(previousList: [StickerPackPreviewGridEntry], list: [StickerPackPreviewGridEntry], context: AccountContext, interaction: StickerPackPreviewInteraction, theme: PresentationTheme) { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: previousList, rightList: list) self.deletions = deleteIndices - self.insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(account: account, interaction: interaction, theme: theme), previousIndex: $0.2) } - self.updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, interaction: interaction, theme: theme)) } + self.insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(context: context, interaction: interaction, theme: theme), previousIndex: $0.2) } + self.updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, interaction: interaction, theme: theme)) } } } @@ -403,7 +404,7 @@ final class StickerPackPreviewControllerNode: ViewControllerTracingNode, UIScrol self.contentTitleNode.attributedText = stringWithAppliedEntities(info.title, entities: entities, baseColor: self.presentationData.theme.actionSheet.primaryTextColor, linkColor: self.presentationData.theme.actionSheet.controlAccentColor, baseFont: font, linkFont: font, boldFont: font, italicFont: font, boldItalicFont: font, fixedFont: font, blockQuoteFont: font, message: nil) animateIn = true } - transaction = StickerPackPreviewGridTransaction(previousList: self.currentItems, list: updatedItems, account: self.context.account, interaction: self.interaction, theme: self.presentationData.theme) + transaction = StickerPackPreviewGridTransaction(previousList: self.currentItems, list: updatedItems, context: self.context, interaction: self.interaction, theme: self.presentationData.theme) self.currentItems = updatedItems } } diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewGridItem.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewGridItem.swift index b081b5cf5b..55e78497e7 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewGridItem.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackPreviewGridItem.swift @@ -33,7 +33,7 @@ final class StickerPackPreviewInteraction { } final class StickerPackPreviewGridItem: GridItem { - let account: Account + let context: AccountContext let stickerItem: StickerPackItem? let interaction: StickerPackPreviewInteraction let theme: PresentationTheme @@ -43,8 +43,8 @@ final class StickerPackPreviewGridItem: GridItem { let section: GridSection? = nil - init(account: Account, stickerItem: StickerPackItem?, interaction: StickerPackPreviewInteraction, theme: PresentationTheme, isPremium: Bool, isLocked: Bool, isEmpty: Bool) { - self.account = account + init(context: AccountContext, stickerItem: StickerPackItem?, interaction: StickerPackPreviewInteraction, theme: PresentationTheme, isPremium: Bool, isLocked: Bool, isEmpty: Bool) { + self.context = context self.stickerItem = stickerItem self.interaction = interaction self.theme = theme @@ -55,7 +55,7 @@ final class StickerPackPreviewGridItem: GridItem { func node(layout: GridNodeLayout, synchronousLoad: Bool) -> GridItemNode { let node = StickerPackPreviewGridItemNode() - node.setup(account: self.account, stickerItem: self.stickerItem, interaction: self.interaction, theme: self.theme, isLocked: self.isLocked, isPremium: self.isPremium, isEmpty: self.isEmpty) + node.setup(context: self.context, stickerItem: self.stickerItem, interaction: self.interaction, theme: self.theme, isLocked: self.isLocked, isPremium: self.isPremium, isEmpty: self.isEmpty) return node } @@ -64,14 +64,14 @@ final class StickerPackPreviewGridItem: GridItem { assertionFailure() return } - node.setup(account: self.account, stickerItem: self.stickerItem, interaction: self.interaction, theme: self.theme, isLocked: self.isLocked, isPremium: self.isPremium, isEmpty: self.isEmpty) + node.setup(context: self.context, stickerItem: self.stickerItem, interaction: self.interaction, theme: self.theme, isLocked: self.isLocked, isPremium: self.isPremium, isEmpty: self.isEmpty) } } private let textFont = Font.regular(20.0) final class StickerPackPreviewGridItemNode: GridItemNode { - private var currentState: (Account, StickerPackItem?)? + private var currentState: (AccountContext, StickerPackItem?)? private var isLocked: Bool? private var isPremium: Bool? private var isEmpty: Bool? @@ -173,11 +173,11 @@ final class StickerPackPreviewGridItemNode: GridItemNode { } private var setupTimestamp: Double? - func setup(account: Account, stickerItem: StickerPackItem?, interaction: StickerPackPreviewInteraction, theme: PresentationTheme, isLocked: Bool, isPremium: Bool, isEmpty: Bool) { + func setup(context: AccountContext, stickerItem: StickerPackItem?, interaction: StickerPackPreviewInteraction, theme: PresentationTheme, isLocked: Bool, isPremium: Bool, isEmpty: Bool) { self.interaction = interaction self.theme = theme - if self.currentState == nil || self.currentState!.0 !== account || self.currentState!.1 != stickerItem || self.isLocked != isLocked || self.isPremium != isPremium || self.isEmpty != isEmpty { + if self.currentState == nil || self.currentState!.0 !== context || self.currentState!.1 != stickerItem || self.isLocked != isLocked || self.isPremium != isPremium || self.isEmpty != isEmpty { self.isLocked = isLocked if isLocked { @@ -229,9 +229,9 @@ final class StickerPackPreviewGridItemNode: GridItemNode { if stickerItem.file.isAnimatedSticker || stickerItem.file.isVideoSticker { let dimensions = stickerItem.file.dimensions ?? PixelDimensions(width: 512, height: 512) if stickerItem.file.isVideoSticker { - self.imageNode.setSignal(chatMessageSticker(account: account, userLocation: .other, file: stickerItem.file, small: true)) + self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: stickerItem.file, small: true)) } else { - self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: account.postbox, userLocation: .other, file: stickerItem.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)))) + self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: context.account.postbox, userLocation: .other, file: stickerItem.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)))) } if self.animationNode == nil { @@ -255,14 +255,14 @@ final class StickerPackPreviewGridItemNode: GridItemNode { } } let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)) - self.animationNode?.setup(source: AnimatedStickerResourceSource(account: account, resource: stickerItem.file.resource, isVideo: stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached) + self.animationNode?.setup(source: AnimatedStickerResourceSource(account: context.account, resource: stickerItem.file.resource, isVideo: stickerItem.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached) self.animationNode?.visibility = visibility - self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, userLocation: .other, fileReference: stickerPackFileReference(stickerItem.file), resource: stickerItem.file.resource).start()) + self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(stickerItem.file), resource: stickerItem.file.resource).start()) if stickerItem.file.isPremiumSticker, let effect = stickerItem.file.videoThumbnails.first { - self.effectFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, userLocation: .other, fileReference: stickerPackFileReference(stickerItem.file), resource: effect.resource).start()) + self.effectFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(stickerItem.file), resource: effect.resource).start()) } } else { if let animationNode = self.animationNode { @@ -270,8 +270,8 @@ final class StickerPackPreviewGridItemNode: GridItemNode { self.animationNode = nil animationNode.removeFromSupernode() } - self.imageNode.setSignal(chatMessageSticker(account: account, userLocation: .other, file: stickerItem.file, small: true)) - self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, userLocation: .other, fileReference: stickerPackFileReference(stickerItem.file), resource: chatMessageStickerResource(file: stickerItem.file, small: true)).start()) + self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: stickerItem.file, small: true)) + self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(stickerItem.file), resource: chatMessageStickerResource(file: stickerItem.file, small: true)).start()) } } else { if isEmpty { @@ -287,7 +287,7 @@ final class StickerPackPreviewGridItemNode: GridItemNode { self.animationNode?.alpha = isLocked ? 0.5 : 1.0 self.imageNode.alpha = isLocked ? 0.5 : 1.0 - self.currentState = (account, stickerItem) + self.currentState = (context, stickerItem) self.setNeedsLayout() } self.isEmpty = isEmpty @@ -322,8 +322,8 @@ final class StickerPackPreviewGridItemNode: GridItemNode { let placeholderFrame = imageFrame self.placeholderNode.frame = imageFrame - if let theme = self.theme, let (_, stickerItem) = self.currentState, let item = stickerItem { - self.placeholderNode.update(backgroundColor: theme.list.itemBlocksBackgroundColor, foregroundColor: theme.list.mediaPlaceholderColor, shimmeringColor: theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), data: item.file.immediateThumbnailData, size: placeholderFrame.size) + if let theme = self.theme, let (context, stickerItem) = self.currentState, let item = stickerItem { + self.placeholderNode.update(backgroundColor: theme.list.itemBlocksBackgroundColor, foregroundColor: theme.list.mediaPlaceholderColor, shimmeringColor: theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), data: item.file.immediateThumbnailData, size: placeholderFrame.size, enableEffect: context.sharedContext.energyUsageSettings.fullTranslucency) } if let lockBackground = self.lockBackground, let lockTintView = self.lockTintView, let lockIconNode = self.lockIconNode { diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift index 2deeaa2e96..fc15348b78 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift @@ -52,7 +52,7 @@ private enum StickerPackPreviewGridEntry: Comparable, Identifiable { func item(context: AccountContext, interaction: StickerPackPreviewInteraction, theme: PresentationTheme, strings: PresentationStrings, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer) -> GridItem { switch self { case let .sticker(_, _, stickerItem, isEmpty, isPremium, isLocked): - return StickerPackPreviewGridItem(account: context.account, stickerItem: stickerItem, interaction: interaction, theme: theme, isPremium: isPremium, isLocked: isLocked, isEmpty: isEmpty) + return StickerPackPreviewGridItem(context: context, stickerItem: stickerItem, interaction: interaction, theme: theme, isPremium: isPremium, isLocked: isLocked, isEmpty: isEmpty) case let .emojis(_, _, info, items, title, isInstalled): return StickerPackEmojisItem(context: context, animationCache: animationCache, animationRenderer: animationRenderer, interaction: interaction, info: info, items: items, theme: theme, strings: strings, title: title, isInstalled: isInstalled, isEmpty: false) } diff --git a/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift b/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift index 99ef0900e6..201dc83001 100644 --- a/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift +++ b/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift @@ -192,6 +192,7 @@ public final class ChatControllerInteraction { public var updatedPresentationData: (initial: PresentationData, signal: Signal)? public let presentationContext: ChatPresentationContext public var playNextOutgoingGift: Bool = false + public var enableFullTranslucency: Bool = true public init( openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool, diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift index 621cc090f1..b3bcbf66d3 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift @@ -3650,7 +3650,7 @@ public final class EmojiPagerContentComponent: Component { override init(frame: CGRect) { self.backgroundView = BlurredBackgroundView(color: nil) - if ProcessInfo.processInfo.processorCount > 2 { + if ProcessInfo.processInfo.processorCount > 4 { self.shimmerHostView = PortalSourceView() self.standaloneShimmerEffect = StandaloneShimmerEffect() } else { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index f1af62e80b..c6167ec70f 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -598,7 +598,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } self.presentationData = context.sharedContext.currentPresentationData.with { $0 } - self.automaticMediaDownloadSettings = context.sharedContext.currentAutomaticMediaDownloadSettings.with { $0 } + self.automaticMediaDownloadSettings = context.sharedContext.currentAutomaticMediaDownloadSettings self.stickerSettings = ChatInterfaceStickerSettings(loopAnimatedStickers: false) @@ -4281,6 +4281,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }, scrollToMessageId: { [weak self] index in self?.chatDisplayNode.historyNode.scrollToMessage(index: index) }, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: self.stickerSettings, presentationContext: ChatPresentationContext(context: context, backgroundNode: self.chatBackgroundNode)) + controllerInteraction.enableFullTranslucency = context.sharedContext.energyUsageSettings.fullTranslucency self.controllerInteraction = controllerInteraction diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 84cbfe1a68..799933d8ba 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -447,7 +447,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { onTransitionEventImpl?(transition) }) - self.loadingNode = ChatLoadingNode(theme: self.chatPresentationInterfaceState.theme, chatWallpaper: self.chatPresentationInterfaceState.chatWallpaper, bubbleCorners: self.chatPresentationInterfaceState.bubbleCorners) + self.loadingNode = ChatLoadingNode(context: context, theme: self.chatPresentationInterfaceState.theme, chatWallpaper: self.chatPresentationInterfaceState.chatWallpaper, bubbleCorners: self.chatPresentationInterfaceState.bubbleCorners) self.inputPanelContainerNode = ChatInputPanelContainer() self.inputPanelOverlayNode = SparseNode() diff --git a/submodules/TelegramUI/Sources/ChatEmptyNode.swift b/submodules/TelegramUI/Sources/ChatEmptyNode.swift index b3f8e89fee..e0d552b062 100644 --- a/submodules/TelegramUI/Sources/ChatEmptyNode.swift +++ b/submodules/TelegramUI/Sources/ChatEmptyNode.swift @@ -960,7 +960,7 @@ final class ChatEmptyNode: ASDisplayNode { self.currentTheme = interfaceState.theme self.currentStrings = interfaceState.strings - self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: interfaceState.theme, wallpaper: interfaceState.chatWallpaper), enableBlur: dateFillNeedsBlur(theme: interfaceState.theme, wallpaper: interfaceState.chatWallpaper), transition: .immediate) + self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: interfaceState.theme, wallpaper: interfaceState.chatWallpaper), enableBlur: self.context.sharedContext.energyUsageSettings.fullTranslucency && dateFillNeedsBlur(theme: interfaceState.theme, wallpaper: interfaceState.chatWallpaper), transition: .immediate) } var isScheduledMessages = false diff --git a/submodules/TelegramUI/Sources/ChatLoadingNode.swift b/submodules/TelegramUI/Sources/ChatLoadingNode.swift index 72f4edf623..d63280e7b2 100644 --- a/submodules/TelegramUI/Sources/ChatLoadingNode.swift +++ b/submodules/TelegramUI/Sources/ChatLoadingNode.swift @@ -15,8 +15,8 @@ final class ChatLoadingNode: ASDisplayNode { private let activityIndicator: ActivityIndicator private let offset: CGPoint - init(theme: PresentationTheme, chatWallpaper: TelegramWallpaper, bubbleCorners: PresentationChatBubbleCorners) { - self.backgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: theme, wallpaper: chatWallpaper), enableBlur: dateFillNeedsBlur(theme: theme, wallpaper: chatWallpaper)) + init(context: AccountContext, theme: PresentationTheme, chatWallpaper: TelegramWallpaper, bubbleCorners: PresentationChatBubbleCorners) { + self.backgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: theme, wallpaper: chatWallpaper), enableBlur: context.sharedContext.energyUsageSettings.fullTranslucency && dateFillNeedsBlur(theme: theme, wallpaper: chatWallpaper)) let serviceColor = serviceMessageColorComponents(theme: theme, wallpaper: chatWallpaper) self.activityIndicator = ActivityIndicator(type: .custom(serviceColor.primaryText, 22.0, 2.0, false), speed: .regular) diff --git a/submodules/TelegramUI/Sources/ChatMediaInputStickerGridItem.swift b/submodules/TelegramUI/Sources/ChatMediaInputStickerGridItem.swift index cbbb53a35f..253d3006ea 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputStickerGridItem.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputStickerGridItem.swift @@ -383,7 +383,7 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode { } let theme = item.theme - placeholderNode.update(backgroundColor: theme.chat.inputMediaPanel.stickersBackgroundColor.withAlphaComponent(1.0), foregroundColor: theme.chat.inputMediaPanel.stickersSectionTextColor.blitOver(theme.chat.inputMediaPanel.stickersBackgroundColor, alpha: 0.15), shimmeringColor: theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.3), data: item.stickerItem.file.immediateThumbnailData, size: placeholderFrame.size) + placeholderNode.update(backgroundColor: theme.chat.inputMediaPanel.stickersBackgroundColor.withAlphaComponent(1.0), foregroundColor: theme.chat.inputMediaPanel.stickersSectionTextColor.blitOver(theme.chat.inputMediaPanel.stickersBackgroundColor, alpha: 0.15), shimmeringColor: theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.3), data: item.stickerItem.file.immediateThumbnailData, size: placeholderFrame.size, enableEffect: true) } if let lockBackground = self.lockBackground, let lockTintView = self.lockTintView, let lockIconNode = self.lockIconNode { diff --git a/submodules/TelegramUI/Sources/ChatMediaInputStickerPackItem.swift b/submodules/TelegramUI/Sources/ChatMediaInputStickerPackItem.swift index 3c2ee14df6..3a9c2fcea4 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputStickerPackItem.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputStickerPackItem.swift @@ -269,7 +269,7 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode { immediateThumbnailData = data } - placeholderNode.update(backgroundColor: nil, foregroundColor: theme.chat.inputMediaPanel.stickersSectionTextColor.blitOver(theme.chat.inputPanel.panelBackgroundColor, alpha: 0.4), shimmeringColor: theme.chat.inputMediaPanel.panelHighlightedIconBackgroundColor.withMultipliedAlpha(0.2), data: immediateThumbnailData, size: boundingImageSize, imageSize: imageSize.cgSize) + placeholderNode.update(backgroundColor: nil, foregroundColor: theme.chat.inputMediaPanel.stickersSectionTextColor.blitOver(theme.chat.inputPanel.panelBackgroundColor, alpha: 0.4), shimmeringColor: theme.chat.inputMediaPanel.panelHighlightedIconBackgroundColor.withMultipliedAlpha(0.2), data: immediateThumbnailData, size: boundingImageSize, enableEffect: true, imageSize: imageSize.cgSize) } self.containerNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: expandedBoundingSize) diff --git a/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift b/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift index 90b4f99192..297747e22c 100644 --- a/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift @@ -181,7 +181,7 @@ private final class ChatMessageActionButtonNode: ASDisplayNode { animation.animator.updateFrame(layer: node.backgroundBlurNode.layer, frame: CGRect(origin: CGPoint(), size: CGSize(width: max(0.0, width), height: 42.0)), completion: nil) node.backgroundBlurNode.update(size: node.backgroundBlurNode.bounds.size, cornerRadius: 0.0, animator: animation.animator) - node.backgroundBlurNode.updateColor(color: selectDateFillStaticColor(theme: theme.theme, wallpaper: theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: theme.theme, wallpaper: theme.wallpaper), transition: .immediate) + node.backgroundBlurNode.updateColor(color: selectDateFillStaticColor(theme: theme.theme, wallpaper: theme.wallpaper), enableBlur: context.sharedContext.energyUsageSettings.fullTranslucency && dateFillNeedsBlur(theme: theme.theme, wallpaper: theme.wallpaper), transition: .immediate) if backgroundNode?.hasExtraBubbleBackground() == true { if node.backgroundContent == nil, let backgroundContent = backgroundNode?.makeBubbleBackground(for: .free) { diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 04b9b9f034..bc3c09a19e 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -125,7 +125,7 @@ class ChatMessageShareButton: HighlightableButtonNode { } else { updatedIconImage = PresentationResourcesChat.chatFreeShareButtonIcon(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) } - self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) + self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) self.iconNode.image = updatedIconImage self.iconOffset = updatedIconOffset } @@ -1444,7 +1444,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let foregroundColor = bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.stickerPlaceholderColor, wallpaper: item.presentationData.theme.wallpaper) let shimmeringColor = bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.stickerPlaceholderShimmerColor, wallpaper: item.presentationData.theme.wallpaper) - strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: foregroundColor, shimmeringColor: shimmeringColor, data: immediateThumbnailData, size: animationNodeFrame.size, imageSize: file.dimensions?.cgSize ?? CGSize(width: 512.0, height: 512.0)) + strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: foregroundColor, shimmeringColor: shimmeringColor, data: immediateThumbnailData, size: animationNodeFrame.size, enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency, imageSize: file.dimensions?.cgSize ?? CGSize(width: 512.0, height: 512.0)) strongSelf.placeholderNode.frame = animationNodeFrame } @@ -1488,9 +1488,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if needsReplyBackground { if let replyBackgroundNode = strongSelf.replyBackgroundNode { - replyBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) + replyBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) } else { - let replyBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)) + let replyBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)) strongSelf.replyBackgroundNode = replyBackgroundNode strongSelf.contextSourceNode.contentNode.addSubnode(replyBackgroundNode) } @@ -2442,7 +2442,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } if let item = self.item, self.swipeToReplyNode == nil { - let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) + let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) self.swipeToReplyNode = swipeToReplyNode self.insertSubnode(swipeToReplyNode, at: 0) } diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index ab1ec32a4f..c7994c9d71 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -4240,7 +4240,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } if let item = self.item, self.swipeToReplyNode == nil { - let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) + let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) self.swipeToReplyNode = swipeToReplyNode self.insertSubnode(swipeToReplyNode, at: 0) } diff --git a/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift b/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift index 534a948e28..d89b74c366 100644 --- a/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift @@ -474,7 +474,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { let serviceColor = serviceMessageColorComponents(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper) dateColor = serviceColor.primaryText - blurredBackgroundColor = (selectDateFillStaticColor(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper), dateFillNeedsBlur(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper)) + blurredBackgroundColor = (selectDateFillStaticColor(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper), arguments.context.sharedContext.energyUsageSettings.fullTranslucency && dateFillNeedsBlur(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper)) leftInset = 0.0 loadedCheckFullImage = PresentationResourcesChat.chatFreeFullCheck(arguments.presentationData.theme.theme, size: checkSize, isDefaultWallpaper: isDefaultWallpaper) loadedCheckPartialImage = PresentationResourcesChat.chatFreePartialCheck(arguments.presentationData.theme.theme, size: checkSize, isDefaultWallpaper: isDefaultWallpaper) @@ -492,7 +492,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { let serviceColor = serviceMessageColorComponents(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper) dateColor = serviceColor.primaryText outgoingStatus = status - blurredBackgroundColor = (selectDateFillStaticColor(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper), dateFillNeedsBlur(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper)) + blurredBackgroundColor = (selectDateFillStaticColor(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper), arguments.context.sharedContext.energyUsageSettings.fullTranslucency && dateFillNeedsBlur(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper)) leftInset = 0.0 loadedCheckFullImage = PresentationResourcesChat.chatFreeFullCheck(arguments.presentationData.theme.theme, size: checkSize, isDefaultWallpaper: isDefaultWallpaper) loadedCheckPartialImage = PresentationResourcesChat.chatFreePartialCheck(arguments.presentationData.theme.theme, size: checkSize, isDefaultWallpaper: isDefaultWallpaper) diff --git a/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift b/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift index fd59f31b10..a183dc02d6 100644 --- a/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift +++ b/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift @@ -200,7 +200,9 @@ final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { let graphics = PresentationResourcesChat.principalGraphics(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) - self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) + let fullTranslucency: Bool = controllerInteraction?.enableFullTranslucency ?? true + + self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: fullTranslucency && dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) self.stickBackgroundNode.image = graphics.dateFloatingBackground self.stickBackgroundNode.alpha = 0.0 @@ -236,8 +238,10 @@ final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { self.presentationData = presentationData let graphics = PresentationResourcesChat.principalGraphics(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) + + let fullTranslucency: Bool = self.controllerInteraction?.enableFullTranslucency ?? true - self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) + self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: fullTranslucency && dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) self.stickBackgroundNode.image = graphics.dateFloatingBackground let titleFont = Font.medium(min(18.0, floor(presentationData.fontSize.baseDisplaySize * 13.0 / 17.0))) diff --git a/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift index 8718d4588b..7d1778faf4 100644 --- a/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift @@ -236,7 +236,7 @@ class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { let mediaBackgroundFrame = imageFrame.insetBy(dx: -2.0, dy: -2.0) strongSelf.mediaBackgroundNode.frame = mediaBackgroundFrame - strongSelf.mediaBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) + strongSelf.mediaBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) strongSelf.mediaBackgroundNode.update(size: mediaBackgroundFrame.size, transition: .immediate) strongSelf.buttonNode.backgroundColor = item.presentationData.theme.theme.overallDarkAppearance ? UIColor(rgb: 0xffffff, alpha: 0.12) : UIColor(rgb: 0x000000, alpha: 0.12) diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index ab652a3aab..df4a0c4d5f 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -525,10 +525,10 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD if let currentReplyBackgroundNode = currentReplyBackgroundNode { updatedReplyBackgroundNode = currentReplyBackgroundNode } else { - updatedReplyBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)) + updatedReplyBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)) } - updatedReplyBackgroundNode?.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) + updatedReplyBackgroundNode?.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) } var maxContentWidth = normalDisplaySize.width @@ -1009,7 +1009,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD translation.x = max(-80.0, min(0.0, translation.x)) if let item = self.item, self.swipeToReplyNode == nil { - let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) + let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) self.swipeToReplyNode = swipeToReplyNode self.insertSubnode(swipeToReplyNode, at: 0) } diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift index 1f69e1a1b3..c0a447dbc7 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift @@ -561,10 +561,10 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { if let currentReplyBackgroundNode = currentReplyBackgroundNode { updatedReplyBackgroundNode = currentReplyBackgroundNode } else { - updatedReplyBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)) + updatedReplyBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)) } - updatedReplyBackgroundNode?.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) + updatedReplyBackgroundNode?.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) } return (result, { [weak self] layoutData, animation in @@ -625,7 +625,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { case .free: let serviceColor = serviceMessageColorComponents(theme: theme.theme, wallpaper: theme.wallpaper) durationTextColor = serviceColor.primaryText - durationBlurColor = (selectDateFillStaticColor(theme: theme.theme, wallpaper: theme.wallpaper), dateFillNeedsBlur(theme: theme.theme, wallpaper: theme.wallpaper)) + durationBlurColor = (selectDateFillStaticColor(theme: theme.theme, wallpaper: theme.wallpaper), item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: theme.theme, wallpaper: theme.wallpaper)) case .bubble: durationBlurColor = nil if incoming { diff --git a/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift index 12030c1a59..213d5c2789 100644 --- a/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift @@ -254,7 +254,7 @@ class ChatMessageProfilePhotoSuggestionContentNode: ChatMessageBubbleContentNode let mediaBackgroundFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((backgroundSize.width - width) / 2.0), y: 0.0), size: backgroundSize) strongSelf.mediaBackgroundNode.frame = mediaBackgroundFrame - strongSelf.mediaBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) + strongSelf.mediaBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) strongSelf.mediaBackgroundNode.update(size: mediaBackgroundFrame.size, transition: .immediate) strongSelf.buttonNode.backgroundColor = item.presentationData.theme.theme.overallDarkAppearance ? UIColor(rgb: 0xffffff, alpha: 0.12) : UIColor(rgb: 0x000000, alpha: 0.12) diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index d1740be7a9..bcf70a8601 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -894,7 +894,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { let shimmeringColor = bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.stickerPlaceholderShimmerColor, wallpaper: item.presentationData.theme.wallpaper) let placeholderFrame = updatedImageFrame.insetBy(dx: innerImageInset, dy: innerImageInset) - strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: foregroundColor, shimmeringColor: shimmeringColor, data: immediateThumbnailData, size: placeholderFrame.size) + strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: foregroundColor, shimmeringColor: shimmeringColor, data: immediateThumbnailData, size: placeholderFrame.size, enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency) strongSelf.placeholderNode.frame = placeholderFrame } @@ -927,9 +927,9 @@ class ChatMessageStickerItemNode: ChatMessageItemView { if needsReplyBackground { if let replyBackgroundNode = strongSelf.replyBackgroundNode { - replyBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) + replyBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) } else { - let replyBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)) + let replyBackgroundNode = NavigationBackgroundNode(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)) strongSelf.replyBackgroundNode = replyBackgroundNode strongSelf.contextSourceNode.contentNode.addSubnode(replyBackgroundNode) } @@ -1412,7 +1412,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { } if let item = self.item, self.swipeToReplyNode == nil { - let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) + let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) self.swipeToReplyNode = swipeToReplyNode self.insertSubnode(swipeToReplyNode, at: 0) } diff --git a/submodules/TelegramUI/Sources/ChatMessageThreadInfoNode.swift b/submodules/TelegramUI/Sources/ChatMessageThreadInfoNode.swift index e761792d15..4f610e79a9 100644 --- a/submodules/TelegramUI/Sources/ChatMessageThreadInfoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageThreadInfoNode.swift @@ -447,7 +447,7 @@ class ChatMessageThreadInfoNode: ASDisplayNode { backgroundNode.frame = backgroundFrame backgroundNode.update(size: backgroundNode.bounds.size, cornerRadius: 0.0, transition: .immediate) - backgroundNode.updateColor(color: selectDateFillStaticColor(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper), transition: .immediate) + backgroundNode.updateColor(color: selectDateFillStaticColor(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper), enableBlur: arguments.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: arguments.presentationData.theme.theme, wallpaper: arguments.presentationData.theme.wallpaper), transition: .immediate) } } else { node.contentBackgroundNode.frame = CGRect(origin: CGPoint(x: -1.0, y: -3.0), size: image.size) diff --git a/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift b/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift index c510117192..0966ca7f17 100644 --- a/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift +++ b/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift @@ -516,7 +516,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode { strongSelf.stickerFetchedDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)).start()) let thumbnailDimensions = PixelDimensions(width: 512, height: 512) - strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, imageSize: thumbnailDimensions.cgSize) + strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency, imageSize: thumbnailDimensions.cgSize) strongSelf.placeholderNode.frame = emojiFrame } diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift index cf39be1715..5208ce3c18 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift @@ -107,7 +107,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { self.presentController = presentController self.getNavigationController = getNavigationController - self.automaticMediaDownloadSettings = context.sharedContext.currentAutomaticMediaDownloadSettings.with { $0 } + self.automaticMediaDownloadSettings = context.sharedContext.currentAutomaticMediaDownloadSettings self.backgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true) self.backgroundNode.isUserInteractionEnabled = false @@ -125,7 +125,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { return presentationData.strings.VoiceOver_ScrollStatus(row, count).string } - self.loadingNode = ChatLoadingNode(theme: self.presentationData.theme, chatWallpaper: self.presentationData.chatWallpaper, bubbleCorners: self.presentationData.chatBubbleCorners) + self.loadingNode = ChatLoadingNode(context: context, theme: self.presentationData.theme, chatWallpaper: self.presentationData.chatWallpaper, bubbleCorners: self.presentationData.chatBubbleCorners) self.emptyNode = ChatRecentActionsEmptyNode(theme: self.presentationData.theme, chatWallpaper: self.presentationData.chatWallpaper, chatBubbleCorners: self.presentationData.chatBubbleCorners) self.emptyNode.alpha = 0.0 diff --git a/submodules/TelegramUI/Sources/ChatThemeScreen.swift b/submodules/TelegramUI/Sources/ChatThemeScreen.swift index 2575e6baae..294f931eb1 100644 --- a/submodules/TelegramUI/Sources/ChatThemeScreen.swift +++ b/submodules/TelegramUI/Sources/ChatThemeScreen.swift @@ -496,7 +496,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode { strongSelf.stickerFetchedDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)).start()) let thumbnailDimensions = PixelDimensions(width: 512, height: 512) - strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, imageSize: thumbnailDimensions.cgSize) + strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency, imageSize: thumbnailDimensions.cgSize) strongSelf.placeholderNode.frame = emojiFrame } diff --git a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift index 5e442b9b78..0346088900 100644 --- a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift @@ -499,7 +499,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode placeholderNode.bounds = CGRect(origin: CGPoint(), size: CGSize(width: croppedImageDimensions.width, height: croppedImageDimensions.height)) placeholderNode.position = CGPoint(x: height / 2.0, y: (nodeLayout.contentSize.height - sideInset) / 2.0 + sideInset) - placeholderNode.update(backgroundColor: item.theme.list.plainBackgroundColor, foregroundColor: item.theme.list.mediaPlaceholderColor.mixedWith(item.theme.list.plainBackgroundColor, alpha: 0.4), shimmeringColor: item.theme.list.mediaPlaceholderColor.withAlphaComponent(0.3), data: immediateThumbnailData, size: CGSize(width: croppedImageDimensions.width, height: croppedImageDimensions.height)) + placeholderNode.update(backgroundColor: item.theme.list.plainBackgroundColor, foregroundColor: item.theme.list.mediaPlaceholderColor.mixedWith(item.theme.list.plainBackgroundColor, alpha: 0.4), shimmeringColor: item.theme.list.mediaPlaceholderColor.withAlphaComponent(0.3), data: immediateThumbnailData, size: CGSize(width: croppedImageDimensions.width, height: croppedImageDimensions.height), enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency) } } }) diff --git a/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift b/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift index 82a28606dd..ff842a3761 100755 --- a/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift +++ b/submodules/TelegramUI/Sources/HorizontalStickerGridItem.swift @@ -11,9 +11,10 @@ import AnimatedStickerNode import TelegramAnimatedStickerNode import ShimmerEffect import TelegramPresentationData +import AccountContext final class HorizontalStickerGridItem: GridItem { - let account: Account + let context: AccountContext let file: TelegramMediaFile let theme: PresentationTheme let isPreviewed: (HorizontalStickerGridItem) -> Bool @@ -21,8 +22,8 @@ final class HorizontalStickerGridItem: GridItem { let section: GridSection? = nil - init(account: Account, file: TelegramMediaFile, theme: PresentationTheme, isPreviewed: @escaping (HorizontalStickerGridItem) -> Bool, sendSticker: @escaping (FileMediaReference, UIView, CGRect) -> Void) { - self.account = account + init(context: AccountContext, file: TelegramMediaFile, theme: PresentationTheme, isPreviewed: @escaping (HorizontalStickerGridItem) -> Bool, sendSticker: @escaping (FileMediaReference, UIView, CGRect) -> Void) { + self.context = context self.file = file self.theme = theme self.isPreviewed = isPreviewed @@ -31,7 +32,7 @@ final class HorizontalStickerGridItem: GridItem { func node(layout: GridNodeLayout, synchronousLoad: Bool) -> GridItemNode { let node = HorizontalStickerGridItemNode() - node.setup(account: self.account, item: self) + node.setup(context: self.context, item: self) node.sendSticker = self.sendSticker return node } @@ -41,13 +42,13 @@ final class HorizontalStickerGridItem: GridItem { assertionFailure() return } - node.setup(account: self.account, item: self) + node.setup(context: self.context, item: self) node.sendSticker = self.sendSticker } } final class HorizontalStickerGridItemNode: GridItemNode { - private var currentState: (Account, HorizontalStickerGridItem, CGSize)? + private var currentState: (AccountContext, HorizontalStickerGridItem, CGSize)? let imageNode: TransformImageNode private(set) var animationNode: AnimatedStickerNode? private(set) var placeholderNode: StickerShimmerEffectNode? @@ -137,8 +138,8 @@ final class HorizontalStickerGridItemNode: GridItemNode { self.imageNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.imageNodeTap(_:)))) } - func setup(account: Account, item: HorizontalStickerGridItem) { - if self.currentState == nil || self.currentState!.0 !== account || self.currentState!.1.file.id != item.file.id { + func setup(context: AccountContext, item: HorizontalStickerGridItem) { + if self.currentState == nil || self.currentState!.0 !== context || self.currentState!.1.file.id != item.file.id { if let dimensions = item.file.dimensions { if item.file.isAnimatedSticker || item.file.isVideoSticker { let animationNode: AnimatedStickerNode @@ -161,9 +162,9 @@ final class HorizontalStickerGridItemNode: GridItemNode { let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)) if item.file.isVideoSticker { - self.imageNode.setSignal(chatMessageSticker(postbox: account.postbox, userLocation: .other, file: item.file, small: true, synchronousLoad: false)) + self.imageNode.setSignal(chatMessageSticker(postbox: context.account.postbox, userLocation: .other, file: item.file, small: true, synchronousLoad: false)) } else { - self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: account.postbox, userLocation: .other, file: item.file, small: true, size: fittedDimensions, synchronousLoad: false)) + self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: context.account.postbox, userLocation: .other, file: item.file, small: true, size: fittedDimensions, synchronousLoad: false)) } animationNode.started = { [weak self] in guard let strongSelf = self else { @@ -181,19 +182,19 @@ final class HorizontalStickerGridItemNode: GridItemNode { strongSelf.removePlaceholder(animated: false) } } - animationNode.setup(source: AnimatedStickerResourceSource(account: account, resource: item.file.resource, isVideo: item.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached) + animationNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: item.file.resource, isVideo: item.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .cached) - self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, userLocation: .other, fileReference: stickerPackFileReference(item.file), resource: item.file.resource).start()) + self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(item.file), resource: item.file.resource).start()) } else { self.imageNode.alpha = 1.0 - self.imageNode.setSignal(chatMessageSticker(account: account, userLocation: .other, file: item.file, small: true)) + self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: item.file, small: true)) if let currentAnimationNode = self.animationNode { self.animationNode = nil currentAnimationNode.removeFromSupernode() } - self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, userLocation: .other, fileReference: stickerPackFileReference(item.file), resource: chatMessageStickerResource(file: item.file, small: true)).start()) + self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: stickerPackFileReference(item.file), resource: chatMessageStickerResource(file: item.file, small: true)).start()) } if item.file.isPremiumSticker { @@ -237,7 +238,7 @@ final class HorizontalStickerGridItemNode: GridItemNode { lockIconNode.removeFromSupernode() } - self.currentState = (account, item, dimensions.cgSize) + self.currentState = (context, item, dimensions.cgSize) self.setNeedsLayout() } } @@ -254,8 +255,8 @@ final class HorizontalStickerGridItemNode: GridItemNode { if let placeholderNode = self.placeholderNode { placeholderNode.frame = bounds - if let theme = self.currentState?.1.theme, let file = self.currentState?.1.file { - placeholderNode.update(backgroundColor: theme.list.plainBackgroundColor, foregroundColor: theme.list.mediaPlaceholderColor.mixedWith(theme.list.plainBackgroundColor, alpha: 0.4), shimmeringColor: theme.list.mediaPlaceholderColor.withAlphaComponent(0.3), data: file.immediateThumbnailData, size: bounds.size) + if let context = self.currentState?.0, let theme = self.currentState?.1.theme, let file = self.currentState?.1.file { + placeholderNode.update(backgroundColor: theme.list.plainBackgroundColor, foregroundColor: theme.list.mediaPlaceholderColor.mixedWith(theme.list.plainBackgroundColor, alpha: 0.4), shimmeringColor: theme.list.mediaPlaceholderColor.withAlphaComponent(0.3), data: file.immediateThumbnailData, size: bounds.size, enableEffect: context.sharedContext.energyUsageSettings.fullTranslucency) } } diff --git a/submodules/TelegramUI/Sources/HorizontalStickersChatContextPanelNode.swift b/submodules/TelegramUI/Sources/HorizontalStickersChatContextPanelNode.swift index 5a2baa934c..7b5e7c96d7 100755 --- a/submodules/TelegramUI/Sources/HorizontalStickersChatContextPanelNode.swift +++ b/submodules/TelegramUI/Sources/HorizontalStickersChatContextPanelNode.swift @@ -70,8 +70,8 @@ private struct StickerEntry: Identifiable, Comparable { return lhs.index < rhs.index } - func item(account: Account, stickersInteraction: HorizontalStickersChatContextPanelInteraction, interfaceInteraction: ChatPanelInterfaceInteraction, theme: PresentationTheme) -> GridItem { - return HorizontalStickerGridItem(account: account, file: self.file, theme: theme, isPreviewed: { item in + func item(context: AccountContext, stickersInteraction: HorizontalStickersChatContextPanelInteraction, interfaceInteraction: ChatPanelInterfaceInteraction, theme: PresentationTheme) -> GridItem { + return HorizontalStickerGridItem(context: context, file: self.file, theme: theme, isPreviewed: { item in return false//stickersInteraction.previewedStickerItem == item }, sendSticker: { file, node, rect in let _ = interfaceInteraction.sendSticker(file, true, node, rect, nil, []) @@ -88,15 +88,15 @@ private struct StickerEntryTransition { let scrollToItem: GridNodeScrollToItem? } -private func preparedGridEntryTransition(account: Account, from fromEntries: [StickerEntry], to toEntries: [StickerEntry], stickersInteraction: HorizontalStickersChatContextPanelInteraction, interfaceInteraction: ChatPanelInterfaceInteraction, theme: PresentationTheme) -> StickerEntryTransition { +private func preparedGridEntryTransition(context: AccountContext, from fromEntries: [StickerEntry], to toEntries: [StickerEntry], stickersInteraction: HorizontalStickersChatContextPanelInteraction, interfaceInteraction: ChatPanelInterfaceInteraction, theme: PresentationTheme) -> StickerEntryTransition { let stationaryItems: GridNodeStationaryItems = .none let scrollToItem: GridNodeScrollToItem? = nil let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices - let insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(account: account, stickersInteraction: stickersInteraction, interfaceInteraction: interfaceInteraction, theme: theme), previousIndex: $0.2) } - let updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, stickersInteraction: stickersInteraction, interfaceInteraction: interfaceInteraction, theme: theme)) } + let insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(context: context, stickersInteraction: stickersInteraction, interfaceInteraction: interfaceInteraction, theme: theme), previousIndex: $0.2) } + let updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, stickersInteraction: stickersInteraction, interfaceInteraction: interfaceInteraction, theme: theme)) } return StickerEntryTransition(deletions: deletions, insertions: insertions, updates: updates, updateFirstIndexInSectionOffset: nil, stationaryItems: stationaryItems, scrollToItem: scrollToItem) } @@ -290,7 +290,7 @@ final class HorizontalStickersChatContextPanelNode: ChatInputContextPanelNode { self.updateLayout(size: validLayout.0, leftInset: validLayout.1, rightInset: validLayout.2, bottomInset: validLayout.3, transition: .immediate, interfaceState: validLayout.4) } - let transition = preparedGridEntryTransition(account: self.context.account, from: previousEntries, to: entries, stickersInteraction: self.stickersInteraction, interfaceInteraction: self.interfaceInteraction!, theme: self.theme) + let transition = preparedGridEntryTransition(context: self.context, from: previousEntries, to: entries, stickersInteraction: self.stickersInteraction, interfaceInteraction: self.interfaceInteraction!, theme: self.theme) self.enqueueTransition(transition) } diff --git a/submodules/TelegramUI/Sources/InChatPrefetchManager.swift b/submodules/TelegramUI/Sources/InChatPrefetchManager.swift index 5902e70362..2323bf66de 100644 --- a/submodules/TelegramUI/Sources/InChatPrefetchManager.swift +++ b/submodules/TelegramUI/Sources/InChatPrefetchManager.swift @@ -31,7 +31,7 @@ final class InChatPrefetchManager { init(context: AccountContext) { self.context = context - self.settings = context.sharedContext.currentAutomaticMediaDownloadSettings.with { $0 } + self.settings = context.sharedContext.currentAutomaticMediaDownloadSettings } func updateAutoDownloadSettings(_ settings: MediaAutoDownloadSettings) { diff --git a/submodules/TelegramUI/Sources/InlineReactionSearchPanel.swift b/submodules/TelegramUI/Sources/InlineReactionSearchPanel.swift index 7363d6ac1d..206ab2bfd2 100644 --- a/submodules/TelegramUI/Sources/InlineReactionSearchPanel.swift +++ b/submodules/TelegramUI/Sources/InlineReactionSearchPanel.swift @@ -431,7 +431,7 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, UIScrollVie itemNode = current } else { let item = HorizontalStickerGridItem( - account: self.context.account, + context: self.context, file: item.file, theme: self.theme, isPreviewed: { [weak self] item in diff --git a/submodules/TelegramUI/Sources/LargeEmojiActionSheetItem.swift b/submodules/TelegramUI/Sources/LargeEmojiActionSheetItem.swift index cc385e6282..8be374d62a 100644 --- a/submodules/TelegramUI/Sources/LargeEmojiActionSheetItem.swift +++ b/submodules/TelegramUI/Sources/LargeEmojiActionSheetItem.swift @@ -131,7 +131,7 @@ private final class LargeEmojiActionSheetItemNode: ActionSheetItemNode { } if let immediateThumbnailData = file.immediateThumbnailData { - self.placeholderNode.update(backgroundColor: nil, foregroundColor: theme.secondaryTextColor.blitOver(theme.itemBackgroundColor, alpha: 0.55), shimmeringColor: theme.itemBackgroundColor.withAlphaComponent(0.4), data: immediateThumbnailData, size: CGSize(width: 96.0, height: 96.0), imageSize: dimensions.cgSize) + self.placeholderNode.update(backgroundColor: nil, foregroundColor: theme.secondaryTextColor.blitOver(theme.itemBackgroundColor, alpha: 0.55), shimmeringColor: theme.itemBackgroundColor.withAlphaComponent(0.4), data: immediateThumbnailData, size: CGSize(width: 96.0, height: 96.0), enableEffect: context.sharedContext.energyUsageSettings.fullTranslucency, imageSize: dimensions.cgSize) } } diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index bf6ef37eb3..7324e9ae08 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -146,14 +146,14 @@ public final class SharedAccountContextImpl: SharedAccountContext { public let currentInAppNotificationSettings: Atomic private var inAppNotificationSettingsDisposable: Disposable? - public let currentAutomaticMediaDownloadSettings: Atomic + public var currentAutomaticMediaDownloadSettings: MediaAutoDownloadSettings private let _automaticMediaDownloadSettings = Promise() public var automaticMediaDownloadSettings: Signal { return self._automaticMediaDownloadSettings.get() } public var energyUsageSettings: EnergyUsageSettings { - return self.currentAutomaticMediaDownloadSettings.with({ $0 }).energyUsageSettings + return self.currentAutomaticMediaDownloadSettings.energyUsageSettings } public let currentAutodownloadSettings: Atomic @@ -234,7 +234,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { } self._currentPresentationData = Atomic(value: initialPresentationDataAndSettings.presentationData) - self.currentAutomaticMediaDownloadSettings = Atomic(value: initialPresentationDataAndSettings.automaticMediaDownloadSettings) + self.currentAutomaticMediaDownloadSettings = initialPresentationDataAndSettings.automaticMediaDownloadSettings self.currentAutodownloadSettings = Atomic(value: initialPresentationDataAndSettings.autodownloadSettings) self.currentMediaInputSettings = Atomic(value: initialPresentationDataAndSettings.mediaInputSettings) self.currentInAppNotificationSettings = Atomic(value: initialPresentationDataAndSettings.inAppNotificationSettings) @@ -367,7 +367,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { self.automaticMediaDownloadSettingsDisposable.set(self._automaticMediaDownloadSettings.get().start(next: { [weak self] next in if let strongSelf = self { - let _ = strongSelf.currentAutomaticMediaDownloadSettings.swap(next) + strongSelf.currentAutomaticMediaDownloadSettings = next } })) diff --git a/submodules/TelegramUI/Sources/StickerPaneTrendingListGridItem.swift b/submodules/TelegramUI/Sources/StickerPaneTrendingListGridItem.swift index 243473a3be..15021188dd 100644 --- a/submodules/TelegramUI/Sources/StickerPaneTrendingListGridItem.swift +++ b/submodules/TelegramUI/Sources/StickerPaneTrendingListGridItem.swift @@ -328,7 +328,7 @@ private final class FeaturedPackItemNode: ListViewItemNode { immediateThumbnailData = data } - placeholderNode.update(backgroundColor: theme.chat.inputMediaPanel.stickersBackgroundColor.withAlphaComponent(1.0), foregroundColor: theme.chat.inputMediaPanel.stickersSectionTextColor.blitOver(theme.chat.inputMediaPanel.stickersBackgroundColor, alpha: 0.15), shimmeringColor: theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.3), data: immediateThumbnailData, size: boundingImageSize, imageSize: imageSize.cgSize) + placeholderNode.update(backgroundColor: theme.chat.inputMediaPanel.stickersBackgroundColor.withAlphaComponent(1.0), foregroundColor: theme.chat.inputMediaPanel.stickersSectionTextColor.blitOver(theme.chat.inputMediaPanel.stickersBackgroundColor, alpha: 0.15), shimmeringColor: theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.3), data: immediateThumbnailData, size: boundingImageSize, enableEffect: true, imageSize: imageSize.cgSize) } self.containerNode.frame = CGRect(origin: CGPoint(), size: boundingSize)