diff --git a/Config/wallet_configs.bzl b/Config/wallet_configs.bzl index 50b9fe9d17..6bee7a1e94 100644 --- a/Config/wallet_configs.bzl +++ b/Config/wallet_configs.bzl @@ -24,10 +24,11 @@ def app_binary_configs(): config = { "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES": "YES", "DEVELOPMENT_LANGUAGE": DEVELOPMENT_LANGUAGE, + "EXECUTABLE_NAME": "Wallet", "PRODUCT_BUNDLE_IDENTIFIER": bundle_identifier(suffix=""), "CODE_SIGN_ENTITLEMENTS": get_codesign_entitlements("app"), "DEVELOPMENT_TEAM": get_development_team(), - "ASSETCATALOG_COMPILER_APPICON_NAME": "AppIconLLC", + "ASSETCATALOG_COMPILER_APPICON_NAME": "AppIconWallet", "BUILD_NUMBER": get_build_number(), "PRODUCT_BUNDLE_SHORT_VERSION": get_short_version(), "APP_NAME": "TON Wallet", @@ -45,14 +46,14 @@ def app_binary_configs(): def app_info_plist_substitutions(): substitutions = { "DEVELOPMENT_LANGUAGE": DEVELOPMENT_LANGUAGE, - "EXECUTABLE_NAME": "TON Wallet", + "EXECUTABLE_NAME": "Wallet", "PRODUCT_BUNDLE_IDENTIFIER": bundle_identifier(suffix=""), "PRODUCT_NAME": "TON Wallet", "APP_NAME": "TON Wallet", "CURRENT_PROJECT_VERSION": "1", "BUILD_NUMBER": get_build_number(), "PRODUCT_BUNDLE_SHORT_VERSION": get_short_version(), - "ASSETCATALOG_COMPILER_APPICON_NAME": "AppIconLLC", + "ASSETCATALOG_COMPILER_APPICON_NAME": "AppIconWallet", "TARGETED_DEVICE_FAMILY": "1,2", } return substitutions diff --git a/Makefile b/Makefile index 0f4fcc01df..d97e9d1106 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,6 @@ .PHONY : check_env build build_arm64 build_debug_arm64 package package_arm64 app app_arm64 app_debug_arm64 build_buckdebug build_verbose kill_xcode clean project project_buckdebug temp - -BUCK_DEBUG_OPTIONS=\ - --config custom.other_cflags="-O0 -D DEBUG" \ - --config custom.other_cxxflags="-O0 -D DEBUG" \ - --config custom.optimization="-Onone" \ - --config custom.config_swift_compiler_flags="-DDEBUG" - -BUCK_RELEASE_OPTIONS=\ - --config custom.other_cflags="-Os" \ - --config custom.other_cxxflags="-Os" \ - --config custom.optimization="-O" \ - --config custom.config_swift_compiler_flags="-whole-module-optimization" +include Utils.makefile BUCK_OPTIONS=\ --config custom.appVersion="5.12" \ @@ -50,43 +39,6 @@ BUCK_OPTIONS=\ --config custom.developmentProvisioningProfileWatchExtension="${DEVELOPMENT_PROVISIONING_PROFILE_WATCH_EXTENSION}" \ --config custom.distributionProvisioningProfileWatchExtension="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" -WALLET_BUCK_OPTIONS=\ - --config custom.appVersion="1.0" \ - --config custom.developmentCodeSignIdentity="${DEVELOPMENT_CODE_SIGN_IDENTITY}" \ - --config custom.distributionCodeSignIdentity="${DISTRIBUTION_CODE_SIGN_IDENTITY}" \ - --config custom.developmentTeam="${DEVELOPMENT_TEAM}" \ - --config custom.baseApplicationBundleId="${WALLET_BUNDLE_ID}" \ - --config custom.buildNumber="${BUILD_NUMBER}" \ - --config custom.entitlementsApp="${WALLET_ENTITLEMENTS_APP}" \ - --config custom.developmentProvisioningProfileApp="${WALLET_DEVELOPMENT_PROVISIONING_PROFILE_APP}" \ - --config custom.distributionProvisioningProfileApp="${WALLET_DISTRIBUTION_PROVISIONING_PROFILE_APP}" \ - --config custom.apiId="${API_ID}" \ - --config custom.apiHash="${API_HASH}" \ - --config custom.hockeyAppId="${HOCKEYAPP_ID}" \ - --config custom.isInternalBuild="${IS_INTERNAL_BUILD}" \ - --config custom.isAppStoreBuild="${IS_APPSTORE_BUILD}" \ - --config custom.appStoreId="${APPSTORE_ID}" \ - --config custom.appSpecificUrlScheme="${APP_SPECIFIC_URL_SCHEME}" - -BUCK_THREADS_OPTIONS=--config build.threads=$(shell sysctl -n hw.logicalcpu) - -BUCK_CACHE_OPTIONS= - -ifneq ($(BUCK_HTTP_CACHE),) - ifeq ($(BUCK_CACHE_MODE),) - BUCK_CACHE_MODE=readwrite - endif - BUCK_CACHE_OPTIONS=\ - --config cache.mode=http \ - --config cache.http_url="$(BUCK_HTTP_CACHE)" \ - --config cache.http_mode="$(BUCK_CACHE_MODE)" -endif - -check_env: -ifndef BUCK - $(error BUCK is not set) -endif - sh check_env.sh build_arm64: check_env $(BUCK) build \ @@ -148,10 +100,6 @@ build_wallet_debug_arm64: check_env //submodules/MtProtoKit:MtProtoKit#shared,iphoneos-arm64 \ //submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#dwarf-and-dsym,shared,iphoneos-arm64 \ //submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared,iphoneos-arm64 \ - //submodules/Postbox:Postbox#dwarf-and-dsym,shared,iphoneos-arm64 \ - //submodules/Postbox:Postbox#shared,iphoneos-arm64 \ - //submodules/TelegramCore:TelegramCore#dwarf-and-dsym,shared,iphoneos-arm64 \ - //submodules/TelegramCore:TelegramCore#shared,iphoneos-arm64 \ //submodules/AsyncDisplayKit:AsyncDisplayKit#dwarf-and-dsym,shared,iphoneos-arm64 \ //submodules/AsyncDisplayKit:AsyncDisplayKit#shared,iphoneos-arm64 \ //submodules/Display:Display#dwarf-and-dsym,shared,iphoneos-arm64 \ @@ -228,7 +176,7 @@ package_arm64: PACKAGE_PROVISIONING_PROFILE_WATCH_APP="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_APP}" \ PACKAGE_PROVISIONING_PROFILE_WATCH_EXTENSION="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" \ PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \ - sh package_app.sh iphoneos-arm64 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} + sh package_app.sh iphoneos-arm64 $(BUCK) "telegram" $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} package_armv7: PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \ @@ -248,7 +196,7 @@ package_armv7: PACKAGE_PROVISIONING_PROFILE_WATCH_APP="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_APP}" \ PACKAGE_PROVISIONING_PROFILE_WATCH_EXTENSION="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" \ PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \ - sh package_app.sh iphoneos-armv7 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} + sh package_app.sh iphoneos-armv7 $(BUCK) "telegram" $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} package_debug_arm64: PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \ @@ -270,7 +218,7 @@ package_debug_arm64: PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \ ENABLE_GET_TASK_ALLOW=0 \ CODESIGNING_PROFILES_VARIANT="development" \ - sh package_app.sh iphoneos-arm64 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} + sh package_app.sh iphoneos-arm64 $(BUCK) "telegram" $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} package_debug_armv7: PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \ @@ -292,7 +240,7 @@ package_debug_armv7: PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \ ENABLE_GET_TASK_ALLOW=0 \ CODESIGNING_PROFILES_VARIANT="development" \ - sh package_app.sh iphoneos-armv7 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} + sh package_app.sh iphoneos-armv7 $(BUCK) "telegram" $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} package: PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \ @@ -312,7 +260,7 @@ package: PACKAGE_PROVISIONING_PROFILE_WATCH_APP="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_APP}" \ PACKAGE_PROVISIONING_PROFILE_WATCH_EXTENSION="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" \ PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \ - sh package_app.sh iphoneos-arm64,iphoneos-armv7 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} + sh package_app.sh iphoneos-arm64,iphoneos-armv7 $(BUCK) "telegram" $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} app: build package @@ -400,9 +348,6 @@ build_ton: check_env //submodules/ton:ton#iphoneos-arm64 \ --verbose 7 ${BUCK_OPTIONS} ${BUCK_THREADS_OPTIONS} ${BUCK_DEBUG_OPTIONS} -kill_xcode: - killall Xcode || true - clean: kill_xcode sh clean.sh @@ -410,14 +355,6 @@ project: check_env kill_xcode $(BUCK) project //:workspace --config custom.mode=project ${BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS} open Telegram_Buck.xcworkspace -wallet_deps: check_env - $(BUCK) query "deps(//Wallet:AppPackage)" \ - ${WALLET_BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS} - -wallet_project: check_env kill_xcode - $(BUCK) project //Wallet:workspace --config custom.mode=project ${WALLET_BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS} - open Wallet/WalletWorkspace.xcworkspace - project_opt: check_env kill_xcode $(BUCK) project //:workspace --config custom.mode=project ${BUCK_OPTIONS} ${BUCK_RELEASE_OPTIONS} open Telegram_Buck.xcworkspace diff --git a/Telegram-iOS/en.lproj/Localizable.strings b/Telegram-iOS/en.lproj/Localizable.strings index cf153361c0..dc13556de5 100644 --- a/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram-iOS/en.lproj/Localizable.strings @@ -4756,7 +4756,7 @@ Any member of this group will be able to see messages in the channel."; "ChatSearch.ResultsTooltip" = "Tap to view as a list."; -"Wallet.Updated.JustNow" = "just now"; +"Wallet.Updated.JustNow" = "updated just now"; "Wallet.Updated.MinutesAgo_0" = "%@ minutes ago"; //three to ten "Wallet.Updated.MinutesAgo_1" = "1 minute ago"; //one "Wallet.Updated.MinutesAgo_2" = "2 minutes ago"; //two @@ -4778,6 +4778,7 @@ Any member of this group will be able to see messages in the channel."; "Wallet.Info.Address" = "Your wallet address"; "Wallet.Info.YourBalance" = "your balance"; "Wallet.Info.Receive" = "Receive"; +"Wallet.Info.ReceiveGrams" = "Receive Grams"; "Wallet.Info.Send" = "Send"; "Wallet.Info.RefreshErrorTitle" = "No network"; "Wallet.Info.RefreshErrorText" = "Couldn't refresh balance. Please make sure your internet connection is working and try again."; diff --git a/Utils.makefile b/Utils.makefile new file mode 100644 index 0000000000..30dabc7c73 --- /dev/null +++ b/Utils.makefile @@ -0,0 +1,40 @@ + +export BUCK_DEBUG_OPTIONS=\ + --config custom.other_cflags="-O0 -D DEBUG" \ + --config custom.other_cxxflags="-O0 -D DEBUG" \ + --config custom.optimization="-Onone" \ + --config custom.config_swift_compiler_flags="-DDEBUG" + +export BUCK_RELEASE_OPTIONS=\ + --config custom.other_cflags="-Os" \ + --config custom.other_cxxflags="-Os" \ + --config custom.optimization="-O" \ + --config custom.config_swift_compiler_flags="-whole-module-optimization" + +export BUCK_THREADS_OPTIONS=--config build.threads=$(shell sysctl -n hw.logicalcpu) + +ifneq ($(BUCK_HTTP_CACHE),) + ifeq ($(BUCK_CACHE_MODE),) + BUCK_CACHE_MODE=readwrite + endif + export BUCK_CACHE_OPTIONS=\ + --config cache.mode=http \ + --config cache.http_url="$(BUCK_HTTP_CACHE)" \ + --config cache.http_mode="$(BUCK_CACHE_MODE)" +endif + +ifneq ($(BUCK_DIR_CACHE),) + export BUCK_CACHE_OPTIONS=\ + --config cache.mode=dir \ + --config cache.dir="$(BUCK_DIR_CACHE)" \ + --config cache.dir_mode="readwrite" +endif + +check_env: +ifndef BUCK + $(error BUCK is not set) +endif + sh check_env.sh + +kill_xcode: + killall Xcode || true diff --git a/Wallet.makefile b/Wallet.makefile new file mode 100644 index 0000000000..80e5656d9b --- /dev/null +++ b/Wallet.makefile @@ -0,0 +1,52 @@ +include Utils.makefile + +WALLET_BUCK_OPTIONS=\ + --config custom.appVersion="1.0" \ + --config custom.developmentCodeSignIdentity="${DEVELOPMENT_CODE_SIGN_IDENTITY}" \ + --config custom.distributionCodeSignIdentity="${DISTRIBUTION_CODE_SIGN_IDENTITY}" \ + --config custom.developmentTeam="${DEVELOPMENT_TEAM}" \ + --config custom.baseApplicationBundleId="${WALLET_BUNDLE_ID}" \ + --config custom.buildNumber="${BUILD_NUMBER}" \ + --config custom.entitlementsApp="${WALLET_ENTITLEMENTS_APP}" \ + --config custom.developmentProvisioningProfileApp="${WALLET_DEVELOPMENT_PROVISIONING_PROFILE_APP}" \ + --config custom.distributionProvisioningProfileApp="${WALLET_DISTRIBUTION_PROVISIONING_PROFILE_APP}" \ + --config custom.apiId="${API_ID}" \ + --config custom.apiHash="${API_HASH}" \ + --config custom.hockeyAppId="${HOCKEYAPP_ID}" \ + --config custom.isInternalBuild="${IS_INTERNAL_BUILD}" \ + --config custom.isAppStoreBuild="${IS_APPSTORE_BUILD}" \ + --config custom.appStoreId="${APPSTORE_ID}" \ + --config custom.appSpecificUrlScheme="${APP_SPECIFIC_URL_SCHEME}" + +wallet_deps: check_env + $(BUCK) query "deps(//Wallet:AppPackage)" --output-attribute buck.type \ + ${WALLET_BUCK_OPTIONS} ${BUCK_RELEASE_OPTIONS} + +wallet_project: check_env kill_xcode + $(BUCK) project //Wallet:workspace --config custom.mode=project ${WALLET_BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS} + open Wallet/WalletWorkspace.xcworkspace + +build_wallet: check_env + $(BUCK) build \ + //Wallet:AppPackage#iphoneos-arm64,iphoneos-armv7 \ + //Wallet:Wallet#dwarf-and-dsym,iphoneos-arm64,iphoneos-armv7 \ + //submodules/MtProtoKit:MtProtoKit#dwarf-and-dsym,shared,iphoneos-arm64,iphoneos-armv7 \ + //submodules/MtProtoKit:MtProtoKit#shared,iphoneos-arm64,iphoneos-armv7 \ + //submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#dwarf-and-dsym,shared,iphoneos-arm64,iphoneos-armv7 \ + //submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared,iphoneos-arm64,iphoneos-armv7 \ + //submodules/AsyncDisplayKit:AsyncDisplayKit#dwarf-and-dsym,shared,iphoneos-arm64,iphoneos-armv7 \ + //submodules/AsyncDisplayKit:AsyncDisplayKit#shared,iphoneos-arm64,iphoneos-armv7 \ + //submodules/Display:Display#dwarf-and-dsym,shared,iphoneos-arm64,iphoneos-armv7 \ + //submodules/Display:Display#shared,iphoneos-arm64,iphoneos-armv7 \ + ${WALLET_BUCK_OPTIONS} ${BUCK_RELEASE_OPTIONS} ${BUCK_THREADS_OPTIONS} ${BUCK_CACHE_OPTIONS} + +wallet_package: + PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \ + PACKAGE_CODE_SIGN_IDENTITY="${DISTRIBUTION_CODE_SIGN_IDENTITY}" \ + PACKAGE_PROVISIONING_PROFILE_APP="${WALLET_DISTRIBUTION_PROVISIONING_PROFILE_APP}" \ + PACKAGE_ENTITLEMENTS_APP="Wallet/${WALLET_ENTITLEMENTS_APP}" \ + PACKAGE_BUNDLE_ID="${WALLET_BUNDLE_ID}" \ + sh package_app.sh iphoneos-arm64,iphoneos-armv7 $(BUCK) "wallet" $(WALLET_BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS} + +wallet_app: build_wallet wallet_package + diff --git a/Wallet/BUCK b/Wallet/BUCK index 907d1ded34..bfe4922b65 100644 --- a/Wallet/BUCK +++ b/Wallet/BUCK @@ -52,7 +52,7 @@ apple_asset_catalog( dirs = [ "Icons.xcassets", ], - app_icon = "AppIconLLC", + app_icon = "AppIconWallet", visibility = ["PUBLIC"], ) diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIcon@2x.png b/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIcon@2x.png deleted file mode 100644 index 2e502e7dab..0000000000 Binary files a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIcon@2x.png and /dev/null differ diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIcon@3x.png b/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIcon@3x.png deleted file mode 100644 index c47aeed4b1..0000000000 Binary files a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIcon@3x.png and /dev/null differ diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIcon@2x-1.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIcon@2x-1.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIcon@2x-1.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIcon@2x-1.png diff --git a/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIcon@2x.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIcon@2x.png new file mode 100644 index 0000000000..7879f15b47 Binary files /dev/null and b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIcon@2x.png differ diff --git a/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIcon@3x.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIcon@3x.png new file mode 100644 index 0000000000..a367fff3af Binary files /dev/null and b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIcon@3x.png differ diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIconIpad.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIconIpad.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIconIpad.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIconIpad.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIconIpad@2x.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIconIpad@2x.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIconIpad@2x.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIconIpad@2x.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIconLargeIpad@2x.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIconLargeIpad@2x.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueIconLargeIpad@2x.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIconLargeIpad@2x.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueNotificationIcon.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueNotificationIcon.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueNotificationIcon.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueNotificationIcon.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueNotificationIcon@2x-1.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueNotificationIcon@2x-1.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueNotificationIcon@2x-1.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueNotificationIcon@2x-1.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueNotificationIcon@2x.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueNotificationIcon@2x.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueNotificationIcon@2x.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueNotificationIcon@2x.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueNotificationIcon@3x.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueNotificationIcon@3x.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/BlueNotificationIcon@3x.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueNotificationIcon@3x.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/Contents.json b/Wallet/Icons.xcassets/AppIconWallet.appiconset/Contents.json similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/Contents.json rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/Contents.json diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple-iTunesArtwork.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple-iTunesArtwork.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple-iTunesArtwork.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple-iTunesArtwork.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@29x29.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@29x29.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@29x29.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@29x29.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@40x40-1.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@40x40-1.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@40x40-1.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@40x40-1.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@58x58-1.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@58x58-1.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@58x58-1.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@58x58-1.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@58x58.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@58x58.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@58x58.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@58x58.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@80x80-1.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@80x80-1.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@80x80-1.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@80x80-1.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@80x80.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@80x80.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@80x80.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@80x80.png diff --git a/Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@87x87.png b/Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@87x87.png similarity index 100% rename from Wallet/Icons.xcassets/AppIconLLC.appiconset/Simple@87x87.png rename to Wallet/Icons.xcassets/AppIconWallet.appiconset/Simple@87x87.png diff --git a/Wallet/Info.plist b/Wallet/Info.plist index 1dcbb9f34b..394714dcc2 100644 --- a/Wallet/Info.plist +++ b/Wallet/Info.plist @@ -68,6 +68,10 @@ NSFaceIDUsageDescription For better security, please allow TON Wallet to use your Face ID to authenticate payments. + NSCameraUsageDescription + Please allow TON Wallet access to your camera for scanning QR codes. + NSPhotoLibraryUsageDescription + Please allow TON Wallet access to your Photo Stream in case you need to scan a QR code from a picture. UIDeviceFamily 1 diff --git a/Wallet/InfoPlistStrings/en.lproj/InfoPlist.strings b/Wallet/InfoPlistStrings/en.lproj/InfoPlist.strings index 1fc9a923ce..06f29d76f6 100644 --- a/Wallet/InfoPlistStrings/en.lproj/InfoPlist.strings +++ b/Wallet/InfoPlistStrings/en.lproj/InfoPlist.strings @@ -1,5 +1,5 @@ /* Localized versions of Info.plist keys */ -"NSCameraUsageDescription" = "We need this so that you can take and share photos and videos."; -"NSPhotoLibraryUsageDescription" = "We need this so that you can share photos and videos from your photo library."; +"NSCameraUsageDescription" = "Please allow TON Wallet access to your camera for scanning QR codes."; +"NSPhotoLibraryUsageDescription" = "Please allow TON Wallet access to your Photo Stream in case you need to scan a QR code from a picture."; "NSFaceIDUsageDescription" = "For better security, please allow TON Wallet to use your Face ID to authenticate payments."; diff --git a/Wallet/Sources/AppDelegate.swift b/Wallet/Sources/AppDelegate.swift index bcffbee986..b86d7acf78 100644 --- a/Wallet/Sources/AppDelegate.swift +++ b/Wallet/Sources/AppDelegate.swift @@ -4,6 +4,8 @@ import SwiftSignalKit import BuildConfig import WalletUI import WalletCore +import AVFoundation +import MtProtoKit private func encodeText(_ string: String, _ key: Int) -> String { var result = "" @@ -120,27 +122,173 @@ private class ApplicationStatusBarHost: StatusBarHost { } } -private let records = Atomic<[WalletStateRecord]>(value: []) - -private final class WalletStorageInterfaceImpl: WalletStorageInterface { - func watchWalletRecords() -> Signal<[WalletStateRecord], NoError> { - return .single(records.with { $0 }) +private final class FileBackedStorageImpl { + private let queue: Queue + private let path: String + private var data: Data? + private var subscribers = Bag<(Data?) -> Void>() + + init(queue: Queue, path: String) { + self.queue = queue + self.path = path } - func getWalletRecords() -> Signal<[WalletStateRecord], NoError> { - return .single(records.with { $0 }) + func get() -> Data? { + if let data = self.data { + return data + } else { + self.data = try? Data(contentsOf: URL(fileURLWithPath: self.path)) + return self.data + } } - func updateWalletRecords(_ f: @escaping ([WalletStateRecord]) -> [WalletStateRecord]) -> Signal<[WalletStateRecord], NoError> { - return .single(records.modify(f)) + func set(data: Data) { + self.data = data + do { + try data.write(to: URL(fileURLWithPath: self.path), options: .atomic) + } catch let error { + print("Error writng data: \(error)") + } + for f in self.subscribers.copyItems() { + f(data) + } + } + + func watch(_ f: @escaping (Data?) -> Void) -> Disposable { + f(self.get()) + let index = self.subscribers.add(f) + let queue = self.queue + return ActionDisposable { [weak self] in + queue.async { + guard let strongSelf = self else { + return + } + strongSelf.subscribers.remove(index) + } + } } } -private final class WalletContextImpl: WalletContext { +private final class FileBackedStorage { + private let queue = Queue() + private let impl: QueueLocalObject + + init(path: String) { + let queue = self.queue + self.impl = QueueLocalObject(queue: queue, generate: { + return FileBackedStorageImpl(queue: queue, path: path) + }) + } + + func get() -> Signal { + return Signal { subscriber in + self.impl.with { impl in + subscriber.putNext(impl.get()) + subscriber.putCompletion() + } + return EmptyDisposable + } + } + + func set(data: Data) -> Signal { + return Signal { subscriber in + self.impl.with { impl in + impl.set(data: data) + subscriber.putCompletion() + } + return EmptyDisposable + } + } + + func update(_ f: @escaping (Data?) -> (Data, T)) -> Signal { + return Signal { subscriber in + self.impl.with { impl in + let (data, result) = f(impl.get()) + impl.set(data: data) + subscriber.putNext(result) + subscriber.putCompletion() + } + return EmptyDisposable + } + } + + func watch() -> Signal { + return Signal { subscriber in + let disposable = MetaDisposable() + self.impl.with { impl in + disposable.set(impl.watch({ data in + subscriber.putNext(data) + })) + } + return disposable + } + } +} + +private let records = Atomic<[WalletStateRecord]>(value: []) + +private final class WalletStorageInterfaceImpl: WalletStorageInterface { + private let storage: FileBackedStorage + + init(path: String) { + self.storage = FileBackedStorage(path: path) + } + + func watchWalletRecords() -> Signal<[WalletStateRecord], NoError> { + return self.storage.watch() + |> map { data -> [WalletStateRecord] in + guard let data = data else { + return [] + } + do { + return try JSONDecoder().decode(Array.self, from: data) + } catch let error { + print("Error deserializing data: \(error)") + return [] + } + } + } + + func getWalletRecords() -> Signal<[WalletStateRecord], NoError> { + return self.storage.get() + |> map { data -> [WalletStateRecord] in + guard let data = data else { + return [] + } + do { + return try JSONDecoder().decode(Array.self, from: data) + } catch let error { + print("Error deserializing data: \(error)") + return [] + } + } + } + + func updateWalletRecords(_ f: @escaping ([WalletStateRecord]) -> [WalletStateRecord]) -> Signal<[WalletStateRecord], NoError> { + return self.storage.update { data -> (Data, [WalletStateRecord]) in + let records: [WalletStateRecord] = data.flatMap { + try? JSONDecoder().decode(Array.self, from: $0) + } ?? [] + let updatedRecords = f(records) + do { + let updatedData = try JSONEncoder().encode(updatedRecords) + return (updatedData, updatedRecords) + } catch let error { + print("Error serializing data: \(error)") + return (Data(), updatedRecords) + } + } + } +} + +private final class WalletContextImpl: NSObject, WalletContext, UIImagePickerControllerDelegate, UINavigationControllerDelegate { let storage: WalletStorageInterface let tonInstance: TonInstance let keychain: TonKeychain let presentationData: WalletPresentationData + let window: Window1 + + private var currentImagePickerCompletion: ((UIImage) -> Void)? var inForeground: Signal { return .single(true) @@ -151,7 +299,7 @@ private final class WalletContextImpl: WalletContext { } func presentNativeController(_ controller: UIViewController) { - + self.window.presentNative(controller) } func idleTimerExtension() -> Disposable { @@ -159,32 +307,75 @@ private final class WalletContextImpl: WalletContext { } func openUrl(_ url: String) { - + if let parsedUrl = URL(string: url) { + UIApplication.shared.openURL(parsedUrl) + } } func shareUrl(_ url: String) { - + if let parsedUrl = URL(string: url) { + self.presentNativeController(UIActivityViewController(activityItems: [parsedUrl], applicationActivities: nil)) + } } func openPlatformSettings() { - + if let url = URL(string: UIApplication.openSettingsURLString) { + UIApplication.shared.openURL(url) + } } func authorizeAccessToCamera(completion: @escaping () -> Void) { - completion() + AVCaptureDevice.requestAccess(for: AVMediaType.video) { response in + Queue.mainQueue().async { + if response { + completion() + } + } + } } func pickImage(completion: @escaping (UIImage) -> Void) { + self.currentImagePickerCompletion = completion + + let pickerController = UIImagePickerController() + pickerController.delegate = self + pickerController.allowsEditing = false + pickerController.mediaTypes = ["public.image"] + pickerController.sourceType = .photoLibrary + self.presentNativeController(pickerController) } - init(basePath: String, config: String, blockchainName: String, navigationBarTheme: NavigationBarTheme) { - self.storage = WalletStorageInterfaceImpl() + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { + let currentImagePickerCompletion = self.currentImagePickerCompletion + self.currentImagePickerCompletion = nil + if let image = info[.editedImage] as? UIImage { + currentImagePickerCompletion?(image) + } else if let image = info[.originalImage] as? UIImage { + currentImagePickerCompletion?(image) + } + picker.presentingViewController?.dismiss(animated: true, completion: nil) + } + + func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { + self.currentImagePickerCompletion = nil + picker.presentingViewController?.dismiss(animated: true, completion: nil) + } + + init(basePath: String, config: String, blockchainName: String, navigationBarTheme: NavigationBarTheme, window: Window1) { + let _ = try? FileManager.default.createDirectory(at: URL(fileURLWithPath: basePath + "/keys"), withIntermediateDirectories: true, attributes: nil) + + self.storage = WalletStorageInterfaceImpl(path: basePath + "/data") + self.window = window self.tonInstance = TonInstance( - basePath: basePath, + basePath: basePath + "/keys", config: config, blockchainName: blockchainName, - proxy: nil + proxy: nil /*TonProxyImpl()*/ ) + + let baseAppBundleId = Bundle.main.bundleIdentifier! + + #if targetEnvironment(simulator) self.keychain = TonKeychain(encryptionPublicKey: { return .single(Data()) }, encrypt: { data in @@ -192,6 +383,47 @@ private final class WalletContextImpl: WalletContext { }, decrypt: { data in return .single(data.data) }) + #else + self.keychain = TonKeychain(encryptionPublicKey: { + return Signal { subscriber in + BuildConfig.getHardwareEncryptionAvailable(withBaseAppBundleId: baseAppBundleId, completion: { value in + subscriber.putNext(value) + subscriber.putCompletion() + }) + return EmptyDisposable + } + }, encrypt: { data in + return Signal { subscriber in + BuildConfig.encryptApplicationSecret(data, baseAppBundleId: baseAppBundleId, completion: { result, publicKey in + if let result = result, let publicKey = publicKey { + subscriber.putNext(TonKeychainEncryptedData(publicKey: publicKey, data: result)) + subscriber.putCompletion() + } else { + subscriber.putError(.generic) + } + }) + return EmptyDisposable + } + }, decrypt: { encryptedData in + return Signal { subscriber in + BuildConfig.decryptApplicationSecret(encryptedData.data, publicKey: encryptedData.publicKey, baseAppBundleId: baseAppBundleId, completion: { result, cancelled in + if let result = result { + subscriber.putNext(result) + } else { + let error: TonKeychainDecryptDataError + if cancelled { + error = .cancelled + } else { + error = .generic + } + subscriber.putError(error) + } + subscriber.putCompletion() + }) + return EmptyDisposable + } + }) + #endif let accentColor = UIColor(rgb: 0x007ee5) self.presentationData = WalletPresentationData( theme: WalletTheme( @@ -271,6 +503,8 @@ private final class WalletContextImpl: WalletContext { groupingSeparator: " " ) ) + + super.init() } } @@ -284,18 +518,20 @@ final class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { let statusBarHost = ApplicationStatusBarHost() let (window, hostView) = nativeWindowHostView() - self.mainWindow = Window1(hostView: hostView, statusBarHost: statusBarHost) + let mainWindow = Window1(hostView: hostView, statusBarHost: statusBarHost) + self.mainWindow = mainWindow hostView.containerView.backgroundColor = UIColor.white self.window = window + let accentColor = UIColor(rgb: 0x007ee5) let navigationBarTheme = NavigationBarTheme( - buttonColor: .blue, - disabledButtonColor: .gray, + buttonColor: accentColor, + disabledButtonColor: UIColor(rgb: 0xd0d0d0), primaryTextColor: .black, - backgroundColor: .lightGray, - separatorColor: .black, - badgeBackgroundColor: .red, - badgeStrokeColor: .red, + backgroundColor: UIColor(rgb: 0xf7f7f7), + separatorColor: UIColor(rgb: 0xb1b1b1), + badgeBackgroundColor: UIColor(rgb: 0xff3b30), + badgeStrokeColor: UIColor(rgb: 0xff3b30), badgeTextColor: .white ) @@ -309,6 +545,7 @@ final class AppDelegate: NSObject, UIApplicationDelegate { ) let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + print("Starting with \(documentsPath)") let config = """ @@ -336,16 +573,230 @@ final class AppDelegate: NSObject, UIApplicationDelegate { } """ - let walletContext = WalletContextImpl(basePath: documentsPath, config: config, blockchainName: "testnet", navigationBarTheme: navigationBarTheme) + let walletContext = WalletContextImpl(basePath: documentsPath, config: config, blockchainName: "testnet", navigationBarTheme: navigationBarTheme, window: mainWindow) self.walletContext = walletContext - let splashScreen = WalletSplashScreen(context: walletContext, mode: .intro, walletCreatedPreloadState: nil) - - navigationController.setViewControllers([splashScreen], animated: false) - self.mainWindow?.viewController = navigationController + let _ = (combineLatest(queue: .mainQueue(), + walletContext.storage.getWalletRecords(), + walletContext.keychain.encryptionPublicKey() + ) + |> deliverOnMainQueue).start(next: { records, publicKey in + if let record = records.first { + if let publicKey = publicKey { + print("publicKey = \(publicKey.base64EncodedString())") + if record.info.encryptedSecret.publicKey == publicKey { + if record.exportCompleted { + let _ = (walletAddress(publicKey: record.info.publicKey, tonInstance: walletContext.tonInstance) + |> deliverOnMainQueue).start(next: { address in + let infoScreen = WalletInfoScreen(context: walletContext, walletInfo: record.info, address: address, enableDebugActions: false) + + navigationController.setViewControllers([infoScreen], animated: false) + }) + } else { + let createdScreen = WalletSplashScreen(context: walletContext, mode: .created(record.info, nil), walletCreatedPreloadState: nil) + + navigationController.setViewControllers([createdScreen], animated: false) + } + } else { + let splashScreen = WalletSplashScreen(context: walletContext, mode: .secureStorageReset(.changed), walletCreatedPreloadState: nil) + + navigationController.setViewControllers([splashScreen], animated: false) + } + } else { + let splashScreen = WalletSplashScreen(context: walletContext, mode: WalletSplashMode.secureStorageReset(.notAvailable), walletCreatedPreloadState: nil) + + navigationController.setViewControllers([splashScreen], animated: false) + } + } else { + if publicKey != nil { + let splashScreen = WalletSplashScreen(context: walletContext, mode: .intro, walletCreatedPreloadState: nil) + + navigationController.setViewControllers([splashScreen], animated: false) + } else { + let splashScreen = WalletSplashScreen(context: walletContext, mode: .secureStorageNotAvailable, walletCreatedPreloadState: nil) + + navigationController.setViewControllers([splashScreen], animated: false) + } + } + }) + mainWindow.viewController = navigationController self.window?.makeKeyAndVisible() return true } } + +private final class Serialization: NSObject, MTSerialization { + func currentLayer() -> UInt { + return 106 + } + + func parseMessage(_ data: Data!) -> Any! { + return nil + } + + func exportAuthorization(_ datacenterId: Int32, data: AutoreleasingUnsafeMutablePointer!) -> MTExportAuthorizationResponseParser! { + return nil + } + + func importAuthorization(_ authId: Int32, bytes: Data!) -> Data! { + return Data() + } + + func requestDatacenterAddress(with data: AutoreleasingUnsafeMutablePointer!) -> MTRequestDatacenterAddressListParser! { + return { _ in + return nil + } + } + + func requestNoop(_ data: AutoreleasingUnsafeMutablePointer!) -> MTRequestNoopParser! { + return { _ in + return nil + } + } +} + +private final class Keychain: NSObject, MTKeychain { + let get: (String) -> Data? + let set: (String, Data) -> Void + let remove: (String) -> Void + + init(get: @escaping (String) -> Data?, set: @escaping (String, Data) -> Void, remove: @escaping (String) -> Void) { + self.get = get + self.set = set + self.remove = remove + } + + func setObject(_ object: Any!, forKey aKey: String!, group: String!) { + if let object = object { + let data = NSKeyedArchiver.archivedData(withRootObject: object) + self.set(group + ":" + aKey, data) + } else { + self.remove(group + ":" + aKey) + } + } + + func object(forKey aKey: String!, group: String!) -> Any! { + if let data = self.get(group + ":" + aKey) { + return NSKeyedUnarchiver.unarchiveObject(with: data as Data) + } + return nil + } + + func removeObject(forKey aKey: String!, group: String!) { + self.remove(group + ":" + aKey) + } + + func dropGroup(_ group: String!) { + + } +} + +private final class TonProxyImpl: TonNetworkProxy { + private let context: MTContext + private let mtProto: MTProto + private let requestService: MTRequestMessageService + + init() { + let serialization = Serialization() + + var apiEnvironment = MTApiEnvironment() + + apiEnvironment.apiId = 8 + apiEnvironment.langPack = "ios" + apiEnvironment.layer = serialization.currentLayer() as NSNumber + apiEnvironment.disableUpdates = true + apiEnvironment = apiEnvironment.withUpdatedLangPackCode("en") + + self.context = MTContext(serialization: serialization, apiEnvironment: apiEnvironment, isTestingEnvironment: false, useTempAuthKeys: false) + + let seedAddressList: [Int: [String]] + + seedAddressList = [ + 1: ["149.154.175.50", "2001:b28:f23d:f001::a"], + 2: ["149.154.167.50", "2001:67c:4e8:f002::a"], + 3: ["149.154.175.100", "2001:b28:f23d:f003::a"], + 4: ["149.154.167.91", "2001:67c:4e8:f004::a"], + 5: ["149.154.171.5", "2001:b28:f23f:f005::a"] + ] + + for (id, ips) in seedAddressList { + self.context.setSeedAddressSetForDatacenterWithId(id, seedAddressSet: MTDatacenterAddressSet(addressList: ips.map { MTDatacenterAddress(ip: $0, port: 443, preferForMedia: false, restrictToTcp: false, cdn: false, preferForProxy: false, secret: nil)! })) + } + + let keychainDict = Atomic<[String: Data]>(value: [:]) + self.context.keychain = Keychain(get: { key in + return keychainDict.with { dict -> Data? in + return dict[key] + } + }, set: { key, value in + let _ = keychainDict.modify { dict in + var dict = dict + dict[key] = value + return dict + } + }, remove: { key in + let _ = keychainDict.modify { dict in + var dict = dict + dict.removeValue(forKey: key) + return dict + } + }) + + let mtProto = MTProto(context: self.context, datacenterId: 2, usageCalculationInfo: nil)! + mtProto.useTempAuthKeys = self.context.useTempAuthKeys + mtProto.checkForProxyConnectionIssues = false + + self.mtProto = mtProto + + self.requestService = MTRequestMessageService(context: context)! + mtProto.add(self.requestService) + + self.mtProto.resume() + } + + func request(data: Data, timeout: Double, completion: @escaping (TonNetworkProxyResult) -> Void) -> Disposable { + let request = MTRequest() + let outputStream = MTOutputStream() + + //wallet.sendLiteRequest#e2c9d33e body:bytes = wallet.LiteResponse; + outputStream.write(Int32(bitPattern: 0xe2c9d33e as UInt32)) + outputStream.writeBytes(data) + + request.setPayload(outputStream.currentBytes(), metadata: "wallet.sendLiteRequest", shortMetadata: "wallet.sendLiteRequest", responseParser: { response in + guard let response = response else { + return nil + } + let inputStream = MTInputStream(data: response)! + //wallet.liteResponse#764386d7 response:bytes = wallet.LiteResponse; + let signature = inputStream.readInt32() + if (signature != 0x764386d7 as Int32) { + return nil + } + return inputStream.readBytes() + }) + + request.dependsOnPasswordEntry = false + request.shouldContinueExecutionWithErrorContext = { _ in + return true + }; + + request.completed = { response, _, error in + if let response = response as? Data { + completion(.reponse(response)) + } else { + completion(.error(error?.errorDescription ?? "UNKNOWN ERROR")) + } + } + + let requestId = request.internalId + + self.requestService.add(request) + + return ActionDisposable { [weak self] in + self?.requestService.removeRequest(byInternalId: requestId) + } + } +} + diff --git a/Wallet/Strings/en.lproj/Localizable.strings b/Wallet/Strings/en.lproj/Localizable.strings index 9697a8a2ba..3ed4f0ab7b 100644 --- a/Wallet/Strings/en.lproj/Localizable.strings +++ b/Wallet/Strings/en.lproj/Localizable.strings @@ -1,4 +1,4 @@ -"Wallet.Updated.JustNow" = "just now"; +"Wallet.Updated.JustNow" = "updated just now"; "Wallet.Updated.MinutesAgo_0" = "%@ minutes ago"; //three to ten "Wallet.Updated.MinutesAgo_1" = "1 minute ago"; //one "Wallet.Updated.MinutesAgo_2" = "2 minutes ago"; //two @@ -19,6 +19,7 @@ "Wallet.Info.Address" = "Your wallet address"; "Wallet.Info.YourBalance" = "your balance"; "Wallet.Info.Receive" = "Receive"; +"Wallet.Info.ReceiveGrams" = "Receive Grams"; "Wallet.Info.Send" = "Send"; "Wallet.Info.RefreshErrorTitle" = "No network"; "Wallet.Info.RefreshErrorText" = "Couldn't refresh balance. Please make sure your internet connection is working and try again."; diff --git a/extract_wallet_source.py b/extract_wallet_source.py new file mode 100644 index 0000000000..7af4b94a34 --- /dev/null +++ b/extract_wallet_source.py @@ -0,0 +1,66 @@ +import sys +import os +import json +import re +import shutil + +def get_file_list(dir): + result_files = [] + result_dirs = [] + for root, dirs, files in os.walk(dir, topdown=False): + for name in files: + result_files.append(os.path.relpath(os.path.join(root, name), dir)) + for name in dirs: + result_dirs.append(os.path.relpath(os.path.join(root, name), dir)) + return set(result_dirs), set(result_files) + +def clean_files(base_dir, dirs, files): + for file in files: + if file == '.DS_Store': + os.remove(base_dir + '/' + file) + for dir in dirs: + if re.match('.*\\.xcodeproj', dir) or re.match('.*\\.xcworkspace', dir): + shutil.rmtree(base_dir + '/' + dir, ignore_errors=True) + +if len(sys.argv) != 2: + print('Usage: extract_wallet_source.py destination') + sys.exit(1) + +destination = sys.argv[1] + +deps_data = os.popen('make -f Wallet.makefile --silent wallet_deps').read() + +deps = json.loads(deps_data) + +paths = [] +for dep in deps: + dep_type = deps[dep]['buck.type'] + if dep_type == 'genrule': + continue + match = re.search('//(.+?):', dep) + if match: + dep_path = match.group(1) + if dep_path not in paths: + paths.append(dep_path) + +for dep_path in paths: + shutil.copytree(dep_path, destination + '/' + dep_path) + +result_dirs, result_files = get_file_list(destination) +clean_files(destination, result_dirs, result_files) + +with open(destination + '/BUCK', 'w+b') as file: + pass + +shutil.copytree('Config', destination + '/' + 'Config') + +copy_files = [ + '.buckconfig', + 'Utils.makefile', + 'Wallet.makefile', + 'check_env.sh', + 'package_app.sh', +] + +for file in copy_files: + shutil.copy(file, destination + '/' + file) diff --git a/package_app.sh b/package_app.sh index f33b70dcaa..80734899d5 100644 --- a/package_app.sh +++ b/package_app.sh @@ -3,13 +3,24 @@ #set -x set -e +if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then + echo "Usage: sh package_app.sh path/to/buck platform-flavors type" + exit 1 +fi + PLATFORM_FLAVORS="$1" BUCK="$2" +APP_TYPE="$3" +shift shift shift BUILD_PATH="build" -APP_NAME="Telegram" +if [ "$APP_TYPE" == "wallet" ]; then + APP_NAME="TONWallet" +else + APP_NAME="Telegram" +fi IPA_PATH="$BUILD_PATH/$APP_NAME.ipa" DSYMS_FOLDER_NAME="DSYMs" @@ -41,7 +52,11 @@ rm -rf "$TEMP_PATH" mkdir -p "$TEMP_PATH" mkdir -p "$TEMP_ENTITLEMENTS_PATH" -cp "buck-out/gen/AppPackage#$PLATFORM_FLAVORS.ipa" "$IPA_PATH.original" +if [ "$APP_TYPE" == "wallet" ]; then + cp "buck-out/gen/Wallet/AppPackage#$PLATFORM_FLAVORS.ipa" "$IPA_PATH.original" +else + cp "buck-out/gen/AppPackage#$PLATFORM_FLAVORS.ipa" "$IPA_PATH.original" +fi rm -rf "$IPA_PATH.original.unpacked" rm -f "$BUILD_PATH/${APP_NAME}_signed.ipa" mkdir -p "$IPA_PATH.original.unpacked" @@ -51,18 +66,18 @@ unzip "$IPA_PATH.original" -d "$IPA_PATH.original.unpacked/" 1>/dev/null rm "$IPA_PATH.original" UNPACKED_PATH="$IPA_PATH.original.unpacked" -APP_PATH="$UNPACKED_PATH/Payload/Telegram.app" +if [ "$APP_TYPE" == "wallet" ]; then + APP_PATH="$UNPACKED_PATH/Payload/Wallet.app" +else + APP_PATH="$UNPACKED_PATH/Payload/Telegram.app" +fi + FRAMEWORKS_DIR="$APP_PATH/Frameworks" rm -rf "$IPA_PATH.original.unpacked/SwiftSupport/iphoneos/"* rm -rf "$IPA_PATH.original.unpacked/Symbols/"* rm -rf "$FRAMEWORKS_DIR/"* -if [ -z "$1" ] || [ -z "$2" ]; then - echo "Usage: sh package_app.sh path/to/buck platform-flavors" - exit 1 -fi - if [ -z "$PACKAGE_METHOD" ]; then echo "PACKAGE_METHOD is not set" exit 1 @@ -111,14 +126,15 @@ if [ ! -d "$PROFILES_PATH" ]; then exit 1 fi -#security delete-keychain "$KEYCHAIN_PATH" || true rm -f "$KEYCHAIN_PATH" -#security create-keychain -p "password" "$KEYCHAIN_PATH" -#security unlock-keychain -p "password" "$KEYCHAIN_PATH" -#KEYCHAIN_FLAG="--keychain '$KEYCHAIN_PATH'" -APP_ITEMS_WITH_PROVISIONING_PROFILE="APP EXTENSION_Share EXTENSION_Widget EXTENSION_NotificationService EXTENSION_NotificationContent EXTENSION_Intents WATCH_APP WATCH_EXTENSION" -APP_ITEMS_WITH_ENTITLEMENTS="APP EXTENSION_Share EXTENSION_Widget EXTENSION_NotificationService EXTENSION_NotificationContent EXTENSION_Intents" +if [ "$APP_TYPE" == "wallet" ]; then + APP_ITEMS_WITH_PROVISIONING_PROFILE="APP" + APP_ITEMS_WITH_ENTITLEMENTS="APP" +else + APP_ITEMS_WITH_PROVISIONING_PROFILE="APP EXTENSION_Share EXTENSION_Widget EXTENSION_NotificationService EXTENSION_NotificationContent EXTENSION_Intents WATCH_APP WATCH_EXTENSION" + APP_ITEMS_WITH_ENTITLEMENTS="APP EXTENSION_Share EXTENSION_Widget EXTENSION_NotificationService EXTENSION_NotificationContent EXTENSION_Intents" +fi COMMON_IDENTITY_HASH="" @@ -255,8 +271,14 @@ COPY_PLIST_KEYS=(\ ) APP_PLIST="$APP_PATH/Info.plist" +if [ "$APP_TYPE" == "wallet" ]; then + APP_BINARY_TARGET="//Wallet:Wallet" +else + APP_BINARY_TARGET="//:Telegram" +fi + echo "Repacking frameworks..." -for DEPENDENCY in $(${BUCK} query "kind('apple_library', deps('//:Telegram#$PLATFORM_FLAVORS', 1))" "$@"); do +for DEPENDENCY in $(${BUCK} query "kind('apple_library', deps('${APP_BINARY_TARGET}#$PLATFORM_FLAVORS', 1))" "$@"); do DEPENDENCY_PATH=$(echo "$DEPENDENCY" | sed -e "s#^//##" | sed -e "s#:#/#") DEPENDENCY_NAME=$(echo "$DEPENDENCY" | sed -e "s/#.*//" | sed -e "s/^.*\://") DYLIB_PATH="buck-out/gen/$DEPENDENCY_PATH/lib$DEPENDENCY_NAME.dylib" @@ -283,23 +305,40 @@ for DEPENDENCY in $(${BUCK} query "kind('apple_library', deps('//:Telegram#$PLAT cp -r "$DSYM_PATH" "$DSYMS_DIR/" done -APP_BINARY_DSYM_PATH="buck-out/gen/Telegram#dwarf-and-dsym,$PLATFORM_FLAVORS,no-include-frameworks/Telegram.app.dSYM" +if [ "$APP_TYPE" == "wallet" ]; then + APP_BINARY_DSYM_PATH="buck-out/gen/Wallet/Wallet#dwarf-and-dsym,$PLATFORM_FLAVORS,no-include-frameworks/Wallet.app.dSYM" +else + APP_BINARY_DSYM_PATH="buck-out/gen/Telegram#dwarf-and-dsym,$PLATFORM_FLAVORS,no-include-frameworks/Telegram.app.dSYM" +fi cp -r "$APP_BINARY_DSYM_PATH" "$DSYMS_DIR/" -EXTENSIONS="Share Widget Intents NotificationContent NotificationService" +if [ "$APP_TYPE" == "wallet" ]; then + EXTENSIONS="" +else + EXTENSIONS="Share Widget Intents NotificationContent NotificationService" +fi + for EXTENSION in $EXTENSIONS; do EXTENSION_DSYM_PATH="buck-out/gen/${EXTENSION}Extension#dwarf-and-dsym,$PLATFORM_FLAVORS,no-include-frameworks/${EXTENSION}Extension.appex.dSYM" cp -r "$EXTENSION_DSYM_PATH" "$DSYMS_DIR/" done -WATCH_EXTENSION_DSYM_PATH="buck-out/gen/WatchAppExtension#dwarf-and-dsym,no-include-frameworks,watchos-arm64_32,watchos-armv7k/WatchAppExtension.appex.dSYM" -cp -r "$WATCH_EXTENSION_DSYM_PATH" "$DSYMS_DIR/" +if [ "$APP_TYPE" != "wallet" ]; then + WATCH_EXTENSION_DSYM_PATH="buck-out/gen/WatchAppExtension#dwarf-and-dsym,no-include-frameworks,watchos-arm64_32,watchos-armv7k/WatchAppExtension.appex.dSYM" + cp -r "$WATCH_EXTENSION_DSYM_PATH" "$DSYMS_DIR/" +fi TEMP_DYLIB_DIR="$TEMP_PATH/SwiftSupport" rm -rf "$TEMP_DYLIB_DIR" mkdir -p "$TEMP_DYLIB_DIR" mkdir -p "$TEMP_DYLIB_DIR/out" +if [ "$APP_TYPE" == "wallet" ]; then + EXECUTABLE_NAME="Wallet" +else + EXECUTABLE_NAME="Telegram" +fi + echo "Copying swift support files..." xcrun swift-stdlib-tool \ --copy \ @@ -307,7 +346,7 @@ xcrun swift-stdlib-tool \ --platform iphoneos \ --toolchain "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain" \ --source-libraries "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos" \ - --scan-executable "$APP_PATH/Telegram" \ + --scan-executable "$APP_PATH/$EXECUTABLE_NAME" \ --scan-folder "$APP_PATH/Frameworks" \ --scan-folder "$APP_PATH/PlugIns" \ --destination "$TEMP_DYLIB_DIR" @@ -348,7 +387,12 @@ done echo "Signing..." -PLUGINS="Share Widget Intents NotificationService NotificationContent" +if [ "$APP_TYPE" == "wallet" ]; then + PLUGINS="" +else + PLUGINS="Share Widget Intents NotificationService NotificationContent" +fi + for PLUGIN in $PLUGINS; do PLUGIN_PATH="$APP_PATH/PlugIns/${PLUGIN}Extension.appex" if [ ! -d "$PLUGIN_PATH" ]; then @@ -377,52 +421,54 @@ for PLUGIN in $PLUGINS; do /usr/bin/codesign ${VERBOSE} -f -s "$COMMON_IDENTITY_HASH" --entitlements "${!ENTITLEMENTS_PATH_VAR}" "$PLUGIN_PATH" done -WATCH_APP_PATH="$APP_PATH/Watch/WatchApp.app" -WATCH_EXTENSION_PATH="$WATCH_APP_PATH/PlugIns/WatchAppExtension.appex" +if [ "$APP_TYPE" != "wallet" ]; then + WATCH_APP_PATH="$APP_PATH/Watch/WatchApp.app" + WATCH_EXTENSION_PATH="$WATCH_APP_PATH/PlugIns/WatchAppExtension.appex" -WATCH_EXTENSION_PROFILE_PATH_VAR="PROFILE_PATH_WATCH_EXTENSION" -if [ -z "${!WATCH_EXTENSION_PROFILE_PATH_VAR}" ]; then - echo "$WATCH_EXTENSION_PROFILE_PATH_VAR is not defined" - exit 1 -fi -if [ ! -f "${!WATCH_EXTENSION_PROFILE_PATH_VAR}" ]; then - echo "${!WATCH_EXTENSION_PROFILE_PATH_VAR} does not exist" - exit 1 -fi -WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR="ENTITLEMENTS_PATH_WATCH_EXTENSION" -if [ -z "${!WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR}" ]; then - echo "$WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR is not defined" - exit 1 -fi -if [ ! -f "${!WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR}" ]; then - echo "${!WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR} does not exist" - exit 1 -fi + WATCH_EXTENSION_PROFILE_PATH_VAR="PROFILE_PATH_WATCH_EXTENSION" + if [ -z "${!WATCH_EXTENSION_PROFILE_PATH_VAR}" ]; then + echo "$WATCH_EXTENSION_PROFILE_PATH_VAR is not defined" + exit 1 + fi + if [ ! -f "${!WATCH_EXTENSION_PROFILE_PATH_VAR}" ]; then + echo "${!WATCH_EXTENSION_PROFILE_PATH_VAR} does not exist" + exit 1 + fi + WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR="ENTITLEMENTS_PATH_WATCH_EXTENSION" + if [ -z "${!WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR}" ]; then + echo "$WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR is not defined" + exit 1 + fi + if [ ! -f "${!WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR}" ]; then + echo "${!WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR} does not exist" + exit 1 + fi -cp "${!WATCH_EXTENSION_PROFILE_PATH_VAR}" "$WATCH_EXTENSION_PATH/embedded.mobileprovision" -/usr/bin/codesign ${VERBOSE} -f -s "$COMMON_IDENTITY_HASH" --entitlements "${!WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR}" "$WATCH_EXTENSION_PATH" 2>/dev/null + cp "${!WATCH_EXTENSION_PROFILE_PATH_VAR}" "$WATCH_EXTENSION_PATH/embedded.mobileprovision" + /usr/bin/codesign ${VERBOSE} -f -s "$COMMON_IDENTITY_HASH" --entitlements "${!WATCH_EXTENSION_ENTITLEMENTS_PATH_VAR}" "$WATCH_EXTENSION_PATH" 2>/dev/null -WATCH_APP_PROFILE_PATH_VAR="PROFILE_PATH_WATCH_APP" -if [ -z "${!WATCH_APP_PROFILE_PATH_VAR}" ]; then - echo "$WATCH_APP_PROFILE_PATH_VAR is not defined" - exit 1 -fi -if [ ! -f "${!WATCH_APP_PROFILE_PATH_VAR}" ]; then - echo "${!WATCH_APP_PROFILE_PATH_VAR} does not exist" - exit 1 -fi -WATCH_APP_ENTITLEMENTS_PATH_VAR="ENTITLEMENTS_PATH_WATCH_APP" -if [ -z "${!WATCH_APP_ENTITLEMENTS_PATH_VAR}" ]; then - echo "$WATCH_APP_ENTITLEMENTS_PATH_VAR is not defined" - exit 1 -fi -if [ ! -f "${!WATCH_APP_ENTITLEMENTS_PATH_VAR}" ]; then - echo "${!WATCH_APP_ENTITLEMENTS_PATH_VAR} does not exist" - exit 1 -fi + WATCH_APP_PROFILE_PATH_VAR="PROFILE_PATH_WATCH_APP" + if [ -z "${!WATCH_APP_PROFILE_PATH_VAR}" ]; then + echo "$WATCH_APP_PROFILE_PATH_VAR is not defined" + exit 1 + fi + if [ ! -f "${!WATCH_APP_PROFILE_PATH_VAR}" ]; then + echo "${!WATCH_APP_PROFILE_PATH_VAR} does not exist" + exit 1 + fi + WATCH_APP_ENTITLEMENTS_PATH_VAR="ENTITLEMENTS_PATH_WATCH_APP" + if [ -z "${!WATCH_APP_ENTITLEMENTS_PATH_VAR}" ]; then + echo "$WATCH_APP_ENTITLEMENTS_PATH_VAR is not defined" + exit 1 + fi + if [ ! -f "${!WATCH_APP_ENTITLEMENTS_PATH_VAR}" ]; then + echo "${!WATCH_APP_ENTITLEMENTS_PATH_VAR} does not exist" + exit 1 + fi -cp "${!WATCH_APP_PROFILE_PATH_VAR}" "$WATCH_APP_PATH/embedded.mobileprovision" -/usr/bin/codesign ${VERBOSE} -f -s "$COMMON_IDENTITY_HASH" --entitlements "${!WATCH_APP_ENTITLEMENTS_PATH_VAR}" "$WATCH_APP_PATH" 2>/dev/null + cp "${!WATCH_APP_PROFILE_PATH_VAR}" "$WATCH_APP_PATH/embedded.mobileprovision" + /usr/bin/codesign ${VERBOSE} -f -s "$COMMON_IDENTITY_HASH" --entitlements "${!WATCH_APP_ENTITLEMENTS_PATH_VAR}" "$WATCH_APP_PATH" 2>/dev/null +fi APP_PROFILE_PATH_VAR="PROFILE_PATH_APP" if [ -z "${!APP_PROFILE_PATH_VAR}" ]; then diff --git a/submodules/Display/Display/NativeWindowHostView.swift b/submodules/Display/Display/NativeWindowHostView.swift index ea84cb3b6a..c0e68cfef4 100644 --- a/submodules/Display/Display/NativeWindowHostView.swift +++ b/submodules/Display/Display/NativeWindowHostView.swift @@ -389,6 +389,10 @@ public func nativeWindowHostView() -> (UIWindow & WindowHost, WindowHostView) { hostView?.presentNative?(controller) } + hostView.nativeController = { [weak rootViewController] in + return rootViewController + } + window.hitTestImpl = { [weak hostView] point, event in return hostView?.hitTest?(point, event) } diff --git a/submodules/Display/Display/WindowContent.swift b/submodules/Display/Display/WindowContent.swift index 7f24fb5b8e..df2db57107 100644 --- a/submodules/Display/Display/WindowContent.swift +++ b/submodules/Display/Display/WindowContent.swift @@ -211,6 +211,7 @@ public final class WindowHostView { var present: ((ContainableController, PresentationSurfaceLevel, Bool, @escaping () -> Void) -> Void)? var presentInGlobalOverlay: ((_ controller: ContainableController) -> Void)? var presentNative: ((UIViewController) -> Void)? + var nativeController: (() -> UIViewController?)? var updateSize: ((CGSize, Double) -> Void)? var layoutSubviews: (() -> Void)? var updateToInterfaceOrientation: ((UIInterfaceOrientation) -> Void)? @@ -1109,7 +1110,9 @@ public class Window1 { } public func presentNative(_ controller: UIViewController) { - + if let nativeController = self.hostView.nativeController?() { + nativeController.present(controller, animated: true, completion: nil) + } } private func panGestureBegan(location: CGPoint) { diff --git a/submodules/TelegramPresentationData/Sources/PresentationStrings.swift b/submodules/TelegramPresentationData/Sources/PresentationStrings.swift index 5d1721dfd9..aa4deb30b8 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationStrings.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationStrings.swift @@ -4408,604 +4408,605 @@ public final class PresentationStrings: Equatable { return formatWithArgumentRanges(self._s[3882]!, self._r[3882]!, [_0]) } public var Channel_MessagePhotoRemoved: String { return self._s[3883]! } - public var Common_edit: String { return self._s[3884]! } - public var PrivacySettings_AuthSessions: String { return self._s[3885]! } - public var Month_ShortJune: String { return self._s[3886]! } - public var PrivacyLastSeenSettings_AlwaysShareWith_Placeholder: String { return self._s[3887]! } - public var Call_ReportSend: String { return self._s[3888]! } - public var Watch_LastSeen_JustNow: String { return self._s[3889]! } - public var Notifications_MessageNotifications: String { return self._s[3890]! } - public var WallpaperSearch_ColorGreen: String { return self._s[3891]! } - public var BroadcastListInfo_AddRecipient: String { return self._s[3893]! } - public var Group_Status: String { return self._s[3894]! } + public var Wallet_Info_ReceiveGrams: String { return self._s[3884]! } + public var Common_edit: String { return self._s[3885]! } + public var PrivacySettings_AuthSessions: String { return self._s[3886]! } + public var Month_ShortJune: String { return self._s[3887]! } + public var PrivacyLastSeenSettings_AlwaysShareWith_Placeholder: String { return self._s[3888]! } + public var Call_ReportSend: String { return self._s[3889]! } + public var Watch_LastSeen_JustNow: String { return self._s[3890]! } + public var Notifications_MessageNotifications: String { return self._s[3891]! } + public var WallpaperSearch_ColorGreen: String { return self._s[3892]! } + public var BroadcastListInfo_AddRecipient: String { return self._s[3894]! } + public var Group_Status: String { return self._s[3895]! } public func AutoNightTheme_LocationHelp(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3895]!, self._r[3895]!, [_0, _1]) + return formatWithArgumentRanges(self._s[3896]!, self._r[3896]!, [_0, _1]) } - public var TextFormat_AddLinkTitle: String { return self._s[3896]! } - public var ShareMenu_ShareTo: String { return self._s[3897]! } - public var Conversation_Moderate_Ban: String { return self._s[3898]! } + public var TextFormat_AddLinkTitle: String { return self._s[3897]! } + public var ShareMenu_ShareTo: String { return self._s[3898]! } + public var Conversation_Moderate_Ban: String { return self._s[3899]! } public func Conversation_DeleteMessagesFor(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3899]!, self._r[3899]!, [_0]) + return formatWithArgumentRanges(self._s[3900]!, self._r[3900]!, [_0]) } - public var SharedMedia_ViewInChat: String { return self._s[3900]! } - public var Map_LiveLocationFor8Hours: String { return self._s[3901]! } + public var SharedMedia_ViewInChat: String { return self._s[3901]! } + public var Map_LiveLocationFor8Hours: String { return self._s[3902]! } public func PUSH_PINNED_PHOTO(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3902]!, self._r[3902]!, [_1]) + return formatWithArgumentRanges(self._s[3903]!, self._r[3903]!, [_1]) } public func PUSH_PINNED_POLL(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3903]!, self._r[3903]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3904]!, self._r[3904]!, [_1, _2]) } public func Map_AccurateTo(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3905]!, self._r[3905]!, [_0]) + return formatWithArgumentRanges(self._s[3906]!, self._r[3906]!, [_0]) } - public var Map_OpenInHereMaps: String { return self._s[3906]! } - public var Appearance_ReduceMotion: String { return self._s[3907]! } + public var Map_OpenInHereMaps: String { return self._s[3907]! } + public var Appearance_ReduceMotion: String { return self._s[3908]! } public func PUSH_MESSAGE_TEXT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3908]!, self._r[3908]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3909]!, self._r[3909]!, [_1, _2]) } - public var Channel_Setup_TypePublicHelp: String { return self._s[3909]! } - public var Passport_Identity_EditInternalPassport: String { return self._s[3910]! } - public var PhotoEditor_Skip: String { return self._s[3911]! } - public func StickerPack_RemoveMaskCount(_ value: Int32) -> String { + public var Channel_Setup_TypePublicHelp: String { return self._s[3910]! } + public var Passport_Identity_EditInternalPassport: String { return self._s[3911]! } + public var PhotoEditor_Skip: String { return self._s[3912]! } + public func Call_Minutes(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, stringValue) } - public func MuteExpires_Hours(_ value: Int32) -> String { + public func AttachmentMenu_SendGif(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue) } - public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String { + public func Watch_UserInfo_Mute(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[2 * 6 + Int(form.rawValue)]!, stringValue) } - public func LiveLocation_MenuChatsCount(_ value: Int32) -> String { + public func ForwardedMessages(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[3 * 6 + Int(form.rawValue)]!, stringValue) } - public func Notification_GameScoreSelfExtended(_ value: Int32) -> String { + public func StickerPack_StickerCount(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[4 * 6 + Int(form.rawValue)]!, stringValue) } - public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String { + public func VoiceOver_Chat_ContactEmailCount(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[5 * 6 + Int(form.rawValue)]!, stringValue) } - public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String { + public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[6 * 6 + Int(form.rawValue)]!, stringValue) } - public func ForwardedAudios(_ value: Int32) -> String { + public func Passport_Scans(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[7 * 6 + Int(form.rawValue)]!, stringValue) } - public func PUSH_CHANNEL_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, _1, _2) + public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, stringValue) } - public func MessageTimer_Minutes(_ value: Int32) -> String { + public func MuteExpires_Hours(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[9 * 6 + Int(form.rawValue)]!, stringValue) } - public func Call_ShortSeconds(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortHours(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Wallet_Updated_MinutesAgo(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, stringValue) - } - public func GroupInfo_ParticipantCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_AddMaskCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedVideoMessages(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ChatList_SelectedChats(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_StatusOnline(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_Photo(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedGifs(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Months(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortSeconds(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_ContactPhoneNumberCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedPolls(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + public func PUSH_CHAT_MESSAGES(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func ChatList_DeleteConfirmation(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MuteFor_Hours(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func PUSH_CHANNEL_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func MuteExpires_Days(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MuteExpires_Minutes(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Hours(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, stringValue) - } - public func UserCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func MessageTimer_ShortDays(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func ForwardedLocations(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notification_GameScoreSelfSimple(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Call_Minutes(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_PollOptionCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, stringValue) - } - public func QuickSend_Photos(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedAuthorsOthers(_ selector: Int32, _ _0: String, _ _1: String) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, _0, _1) - } - public func SharedMedia_Generic(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_StickerCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_StatusMembers(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Media_SharePhoto(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, stringValue) - } - public func AttachmentMenu_SendVideo(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Chat_DeleteMessagesConfirmation(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, stringValue) - } - public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedMessages(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, stringValue) - } - public func AttachmentMenu_SendItem(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MuteFor_Days(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Seconds(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Days(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedContacts(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Watch_UserInfo_Mute(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Passport_Scans(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_SelectedMessages(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Invitation_Members(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Call_ShortMinutes(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedPhotos(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notifications_Exceptions(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Map_ETAMinutes(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortMinutes(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Media_ShareVideo(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_RemoveStickerCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGE_VIDEOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func StickerPack_AddStickerCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, stringValue) - } - public func LastSeen_HoursAgo(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, stringValue) - } - public func InviteText_ContactsCountText(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGE_PHOTOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func SharedMedia_Video(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGE_ROUNDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func PUSH_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Media_ShareItem(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Years(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessagePoll_VotedCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Contacts_ImportersCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, _2, _1, _3) } public func SharedMedia_Link(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, stringValue) } - public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String { + public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, stringValue) } - public func MessageTimer_ShortWeeks(_ value: Int32) -> String { + public func AttachmentMenu_SendItem(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, stringValue) } - public func Notification_GameScoreExtended(_ value: Int32) -> String { + public func Conversation_StatusMembers(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, stringValue) } - public func ForwardedFiles(_ value: Int32) -> String { + public func MessageTimer_Years(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, stringValue) } - public func ForwardedVideos(_ value: Int32) -> String { + public func Conversation_SelectedMessages(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, stringValue) } - public func Notification_GameScoreSimple(_ value: Int32) -> String { + public func MuteExpires_Minutes(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, stringValue) } - public func Call_Seconds(_ value: Int32) -> String { + public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGE_FWDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func LastSeen_MinutesAgo(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_File(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, stringValue) - } - public func CreatePoll_AddMoreOptions(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[99 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGES(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[100 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func ForwardedStickers(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[101 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Map_ETAHours(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[102 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Wallet_Updated_HoursAgo(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[103 * 6 + Int(form.rawValue)]!, stringValue) - } - public func AttachmentMenu_SendGif(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[104 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[105 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func MessageTimer_Weeks(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[106 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_ContactEmailCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[107 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Theme_UsersCount(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[108 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_PollVotes(_ value: Int32) -> String { - let form = getPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[109 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[110 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func PUSH_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = getPluralizationForm(self.lc, selector) - return String(format: self._ps[111 * 6 + Int(form.rawValue)]!, _1, _2) + return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, stringValue) } public func Wallpaper_DeleteConfirmation(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[112 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, stringValue) } - public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String { + public func ForwardedLocations(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[113 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHAT_MESSAGE_ROUNDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func PUSH_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreSelfExtended(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteFor_Hours(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Map_ETAHours(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, stringValue) } public func Conversation_StatusSubscribers(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[114 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortSeconds(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func SharedMedia_Generic(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteExpires_Days(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedVideoMessages(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, stringValue) + } + public func LastSeen_MinutesAgo(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Chat_DeleteMessagesConfirmation(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedFiles(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortHours(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, stringValue) + } + public func VoiceOver_Chat_ContactPhoneNumberCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func PUSH_CHANNEL_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func StickerPack_AddMaskCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, stringValue) + } + public func VoiceOver_Chat_PollVotes(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, stringValue) + } + public func StickerPack_AddStickerCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHAT_MESSAGE_VIDEOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func Theme_UsersCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedContacts(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Days(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Weeks(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Wallet_Updated_HoursAgo(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, stringValue) + } + public func QuickSend_Photos(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, stringValue) + } + public func LastSeen_HoursAgo(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedVideos(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortDays(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, stringValue) + } + public func StickerPack_RemoveMaskCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Wallet_Updated_MinutesAgo(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, stringValue) + } + public func AttachmentMenu_SendVideo(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_File(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedPhotos(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func Invitation_Members(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Contacts_ImportersCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreExtended(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func Notification_GameScoreSimple(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notifications_Exceptions(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, stringValue) + } + public func VoiceOver_Chat_PollOptionCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Map_ETAMinutes(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func Media_ShareItem(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHAT_MESSAGE_FWDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func Media_SharePhoto(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, stringValue) + } + public func UserCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func GroupInfo_ParticipantCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_Photo(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedAudios(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortMinutes(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHAT_MESSAGE_PHOTOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func PUSH_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func MessageTimer_Months(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteFor_Days(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, stringValue) } public func AttachmentMenu_SendPhoto(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, stringValue) + } + public func StickerPack_RemoveStickerCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedAuthorsOthers(_ selector: Int32, _ _0: String, _ _1: String) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, _0, _1) + } + public func SharedMedia_Video(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ChatList_SelectedChats(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Call_Seconds(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, stringValue) + } + public func CreatePoll_AddMoreOptions(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedStickers(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Call_ShortMinutes(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Call_ShortSeconds(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedGifs(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[99 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedPolls(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[100 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[101 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Minutes(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[102 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[103 * 6 + Int(form.rawValue)]!, stringValue) + } + public func LiveLocation_MenuChatsCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[104 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Media_ShareVideo(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[105 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortWeeks(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[106 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[107 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = getPluralizationForm(self.lc, selector) + return String(format: self._ps[108 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func Conversation_StatusOnline(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[109 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Seconds(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[110 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessagePoll_VotedCount(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[111 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Hours(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[112 * 6 + Int(form.rawValue)]!, stringValue) + } + public func InviteText_ContactsCountText(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[113 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreSelfSimple(_ value: Int32) -> String { + let form = getPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[114 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ChatList_DeleteConfirmation(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[115 * 6 + Int(form.rawValue)]!, stringValue) diff --git a/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping b/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping index e8a787649d..5672627924 100644 Binary files a/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping and b/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping differ diff --git a/submodules/WalletCore/Sources/WalletCore.swift b/submodules/WalletCore/Sources/WalletCore.swift index 01f2131409..b376a546ec 100644 --- a/submodules/WalletCore/Sources/WalletCore.swift +++ b/submodules/WalletCore/Sources/WalletCore.swift @@ -477,7 +477,7 @@ public struct CombinedWalletState: Codable, Equatable { public var pendingTransactions: [PendingWalletTransaction] } -public struct WalletStateRecord: Equatable { +public struct WalletStateRecord: Codable, Equatable { public let info: WalletInfo public var exportCompleted: Bool public var state: CombinedWalletState? diff --git a/submodules/WalletUI/BUCK b/submodules/WalletUI/BUCK index 670e2185ab..5194a2e218 100644 --- a/submodules/WalletUI/BUCK +++ b/submodules/WalletUI/BUCK @@ -11,7 +11,7 @@ apple_resource( apple_asset_catalog( name = 'WalletUIAssets', dirs = [ - "Images.xcassets", + "WalletImages.xcassets", ], visibility = ["PUBLIC"], ) diff --git a/submodules/WalletUI/Resources/WalletStrings.mapping b/submodules/WalletUI/Resources/WalletStrings.mapping index 696b14c5b8..4479b5ec98 100644 Binary files a/submodules/WalletUI/Resources/WalletStrings.mapping and b/submodules/WalletUI/Resources/WalletStrings.mapping differ diff --git a/submodules/WalletUI/Sources/WalletInfoScreen.swift b/submodules/WalletUI/Sources/WalletInfoScreen.swift index 8426eeea1d..4d0ad468eb 100644 --- a/submodules/WalletUI/Sources/WalletInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletInfoScreen.swift @@ -201,6 +201,7 @@ private final class WalletInfoHeaderNode: ASDisplayNode { private let refreshNode: WalletRefreshNode private let balanceSubtitleNode: ImmediateTextNode private let receiveButtonNode: SolidRoundedButtonNode + private let receiveGramsButtonNode: SolidRoundedButtonNode private let sendButtonNode: SolidRoundedButtonNode private let headerBackgroundNode: ASDisplayNode private let headerCornerNode: ASImageNode @@ -229,6 +230,7 @@ private final class WalletInfoHeaderNode: ASDisplayNode { })?.stretchableImage(withLeftCapWidth: 10, topCapHeight: 1) self.receiveButtonNode = SolidRoundedButtonNode(title: presentationData.strings.Wallet_Info_Receive, icon: UIImage(bundleImageName: "Wallet/ReceiveButtonIcon"), theme: SolidRoundedButtonTheme(backgroundColor: .white, foregroundColor: .black), height: 50.0, cornerRadius: 10.0, gloss: false) + self.receiveGramsButtonNode = SolidRoundedButtonNode(title: presentationData.strings.Wallet_Info_ReceiveGrams, icon: UIImage(bundleImageName: "Wallet/ReceiveButtonIcon"), theme: SolidRoundedButtonTheme(backgroundColor: .white, foregroundColor: .black), height: 50.0, cornerRadius: 10.0, gloss: false) self.sendButtonNode = SolidRoundedButtonNode(title: presentationData.strings.Wallet_Info_Send, icon: UIImage(bundleImageName: "Wallet/SendButtonIcon"), theme: SolidRoundedButtonTheme(backgroundColor: .white, foregroundColor: .black), height: 50.0, cornerRadius: 10.0, gloss: false) self.refreshNode = WalletRefreshNode(strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat) @@ -239,6 +241,7 @@ private final class WalletInfoHeaderNode: ASDisplayNode { self.addSubnode(self.headerCornerNode) if hasActions { self.addSubnode(self.receiveButtonNode) + self.addSubnode(self.receiveGramsButtonNode) self.addSubnode(self.sendButtonNode) } self.addSubnode(self.balanceNode) @@ -248,6 +251,9 @@ private final class WalletInfoHeaderNode: ASDisplayNode { self.receiveButtonNode.pressed = { receiveAction() } + self.receiveGramsButtonNode.pressed = { + receiveAction() + } self.sendButtonNode.pressed = { sendAction() } @@ -332,18 +338,18 @@ private final class WalletInfoHeaderNode: ASDisplayNode { let sendButtonFrame = CGRect(origin: CGPoint(x: leftButtonFrame.maxX + sideInset, y: leftButtonFrame.minY), size: CGSize(width: size.width - leftButtonFrame.maxX - sideInset * 2.0, height: buttonHeight)) let fullButtonFrame = CGRect(origin: CGPoint(x: sideInset, y: buttonOffset - sideInset - buttonHeight), size: CGSize(width: size.width - sideInset * 2.0, height: buttonHeight)) - var receiveButtonFrame: CGRect if let balance = self.balance, balance > 0 { - receiveButtonFrame = leftButtonFrame + self.receiveGramsButtonNode.isHidden = true self.receiveButtonNode.isHidden = false self.sendButtonNode.isHidden = false } else { - receiveButtonFrame = fullButtonFrame if self.balance == nil { + self.receiveGramsButtonNode.isHidden = true self.receiveButtonNode.isHidden = true self.sendButtonNode.isHidden = true } else { - self.receiveButtonNode.isHidden = false + self.receiveGramsButtonNode.isHidden = false + self.receiveButtonNode.isHidden = true self.sendButtonNode.isHidden = true } } @@ -357,9 +363,12 @@ private final class WalletInfoHeaderNode: ASDisplayNode { self.refreshNode.isHidden = false } - transition.updateFrame(node: self.receiveButtonNode, frame: receiveButtonFrame) + transition.updateFrame(node: self.receiveGramsButtonNode, frame: fullButtonFrame) + transition.updateAlpha(node: self.receiveGramsButtonNode, alpha: buttonAlpha) + transition.updateFrame(node: self.receiveButtonNode, frame: leftButtonFrame) transition.updateAlpha(node: self.receiveButtonNode, alpha: buttonAlpha) - self.receiveButtonNode.updateLayout(width: receiveButtonFrame.width, transition: transition) + self.receiveGramsButtonNode.updateLayout(width: fullButtonFrame.width, transition: transition) + self.receiveButtonNode.updateLayout(width: leftButtonFrame.width, transition: transition) transition.updateFrame(node: self.sendButtonNode, frame: sendButtonFrame) transition.updateAlpha(node: self.sendButtonNode, alpha: buttonAlpha) self.sendButtonNode.updateLayout(width: sendButtonFrame.width, transition: transition) @@ -372,12 +381,16 @@ private final class WalletInfoHeaderNode: ASDisplayNode { if let result = self.receiveButtonNode.hitTest(self.view.convert(point, to: self.receiveButtonNode.view), with: event) { return result } + if let result = self.receiveGramsButtonNode.hitTest(self.view.convert(point, to: self.receiveGramsButtonNode.view), with: event) { + return result + } return nil } func becameReady(animated: Bool) { if animated { self.sendButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + self.receiveGramsButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) self.receiveButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) self.balanceNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) self.balanceSubtitleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) diff --git a/submodules/WalletUI/Sources/WalletPresentationData.swift b/submodules/WalletUI/Sources/WalletPresentationData.swift index 0e892b1b17..c1c3cad772 100644 --- a/submodules/WalletUI/Sources/WalletPresentationData.swift +++ b/submodules/WalletUI/Sources/WalletPresentationData.swift @@ -242,7 +242,7 @@ func cornersImage(_ theme: WalletTheme, top: Bool, bottom: Bool) -> UIImage? { func itemListClearInputIcon(_ theme: WalletTheme) -> UIImage? { return theme.image(WalletThemeResourceKey.itemListClearInputIcon.rawValue, { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Components/Search Bar/Clear"), color: theme.list.inputClearButtonColor) + return generateTintedImage(image: UIImage(bundleImageName: "Wallet/ClearInput"), color: theme.list.inputClearButtonColor) }) } diff --git a/submodules/WalletUI/Sources/WalletSplashScreen.swift b/submodules/WalletUI/Sources/WalletSplashScreen.swift index cea1d38ede..b78fd147fe 100644 --- a/submodules/WalletUI/Sources/WalletSplashScreen.swift +++ b/submodules/WalletUI/Sources/WalletSplashScreen.swift @@ -71,7 +71,7 @@ public final class WalletSplashScreen: ViewController { self.walletCreatedPreloadState = nil } - super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: navigationBarTheme, strings: NavigationBarStrings(back: self.presentationData.strings.Wallet_Navigation_Back, close: self.presentationData.strings.Wallet_Navigation_Close))) + super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: navigationBarTheme, strings: NavigationBarStrings(back: self.presentationData.strings.Wallet_Intro_NotNow, close: self.presentationData.strings.Wallet_Navigation_Close))) self.statusBar.statusBarStyle = self.presentationData.theme.statusBarStyle self.navigationPresentation = .modalInLargeLayout @@ -79,9 +79,7 @@ public final class WalletSplashScreen: ViewController { self.navigationBar?.intrinsicCanTransitionInline = false switch self.mode { - case .intro: - self.navigationItem.setLeftBarButton(UIBarButtonItem(title: self.presentationData.strings.Wallet_Intro_NotNow, style: .plain, target: self, action: #selector(self.backPressed)), animated: false) - self.navigationItem.setRightBarButton(UIBarButtonItem(title: self.presentationData.strings.Wallet_Intro_ImportExisting, style: .plain, target: self, action: #selector(self.importPressed)), animated: false) + case let .intro: self.navigationItem.setRightBarButton(UIBarButtonItem(title: self.presentationData.strings.Wallet_Intro_ImportExisting, style: .plain, target: self, action: #selector(self.importPressed)), animated: false) case let .sending(walletInfo, address, amount, textMessage, randomId, serverSalt): self.navigationItem.setLeftBarButton(UIBarButtonItem(customDisplayNode: ASDisplayNode())!, animated: false) let _ = (self.context.keychain.decrypt(walletInfo.encryptedSecret) diff --git a/submodules/WalletUI/Sources/WalletStrings.swift b/submodules/WalletUI/Sources/WalletStrings.swift index c8ffa7e9bf..e3fd2c85e3 100644 --- a/submodules/WalletUI/Sources/WalletStrings.swift +++ b/submodules/WalletUI/Sources/WalletStrings.swift @@ -414,12 +414,13 @@ public final class WalletStrings: Equatable { public var Wallet_Info_RefreshErrorText: String { return self._s[188]! } public var Wallet_SecureStorageReset_Title: String { return self._s[189]! } public var Wallet_Receive_CommentHeader: String { return self._s[190]! } - public func Wallet_Updated_MinutesAgo(_ value: Int32) -> String { + public var Wallet_Info_ReceiveGrams: String { return self._s[191]! } + public func Wallet_Updated_HoursAgo(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, stringValue) } - public func Wallet_Updated_HoursAgo(_ value: Int32) -> String { + public func Wallet_Updated_MinutesAgo(_ value: Int32) -> String { let form = getPluralizationForm(self.lc, value) let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue) diff --git a/submodules/WalletUI/Sources/WalletWordCheckScreen.swift b/submodules/WalletUI/Sources/WalletWordCheckScreen.swift index 282f0e2fcb..5058ae767d 100644 --- a/submodules/WalletUI/Sources/WalletWordCheckScreen.swift +++ b/submodules/WalletUI/Sources/WalletWordCheckScreen.swift @@ -2248,7 +2248,7 @@ public final class WalletWordCheckScreen: ViewController { } private func generateClearIcon(color: UIColor) -> UIImage? { - return generateTintedImage(image: UIImage(bundleImageName: "Components/Search Bar/Clear"), color: color) + return generateTintedImage(image: UIImage(bundleImageName: "Wallet/ClearInput"), color: color) } private final class WordCheckInputNode: ASDisplayNode, UITextFieldDelegate { diff --git a/submodules/WalletUI/Sources/WalletWordDisplayScreen.swift b/submodules/WalletUI/Sources/WalletWordDisplayScreen.swift index 2c4d4b68be..2c986e5eb0 100644 --- a/submodules/WalletUI/Sources/WalletWordDisplayScreen.swift +++ b/submodules/WalletUI/Sources/WalletWordDisplayScreen.swift @@ -77,9 +77,9 @@ public final class WalletWordDisplayScreen: ViewController { let deltaTime = Date().timeIntervalSince1970 - strongSelf.startTime let minimalTimeout: Double #if DEBUG - minimalTimeout = 60.0 + minimalTimeout = 5.0 #else - minimalTimeout = 60.0 + minimalTimeout = 30.0 #endif if deltaTime < minimalTimeout { strongSelf.present(standardTextAlertController(theme: strongSelf.presentationData.theme.alert, title: strongSelf.presentationData.strings.Wallet_Words_NotDoneTitle, text: strongSelf.presentationData.strings.Wallet_Words_NotDoneText, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Wallet_Words_NotDoneOk, action: { diff --git a/submodules/WalletUI/Images.xcassets/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/BalanceGem.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/BalanceGem.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/BalanceGem.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/BalanceGem.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/BalanceGem.imageset/gem.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/BalanceGem.imageset/gem.pdf similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/BalanceGem.imageset/gem.pdf rename to submodules/WalletUI/WalletImages.xcassets/Wallet/BalanceGem.imageset/gem.pdf diff --git a/submodules/WalletUI/Images.xcassets/Wallet/CameraFlashIcon.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/CameraFlashIcon.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/CameraFlashIcon.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/CameraFlashIcon.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/CameraFlashIcon.imageset/ic_flash.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/CameraFlashIcon.imageset/ic_flash.pdf similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/CameraFlashIcon.imageset/ic_flash.pdf rename to submodules/WalletUI/WalletImages.xcassets/Wallet/CameraFlashIcon.imageset/ic_flash.pdf diff --git a/submodules/WalletUI/Images.xcassets/Wallet/CameraGalleryIcon.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/CameraGalleryIcon.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/CameraGalleryIcon.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/CameraGalleryIcon.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/CameraGalleryIcon.imageset/ic_gallery (3).pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/CameraGalleryIcon.imageset/ic_gallery (3).pdf similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/CameraGalleryIcon.imageset/ic_gallery (3).pdf rename to submodules/WalletUI/WalletImages.xcassets/Wallet/CameraGalleryIcon.imageset/ic_gallery (3).pdf diff --git a/submodules/WalletUI/WalletImages.xcassets/Wallet/ClearInput.imageset/Clear.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/ClearInput.imageset/Clear.pdf new file mode 100644 index 0000000000..f597a23849 Binary files /dev/null and b/submodules/WalletUI/WalletImages.xcassets/Wallet/ClearInput.imageset/Clear.pdf differ diff --git a/submodules/WalletUI/WalletImages.xcassets/Wallet/ClearInput.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/ClearInput.imageset/Contents.json new file mode 100644 index 0000000000..0ba85044f4 --- /dev/null +++ b/submodules/WalletUI/WalletImages.xcassets/Wallet/ClearInput.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Clear.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/submodules/WalletUI/Images.xcassets/Wallet/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/DuckIcon.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/DuckIcon.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/DuckIcon.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/DuckIcon.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/DuckIcon.imageset/duck.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/DuckIcon.imageset/duck.pdf similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/DuckIcon.imageset/duck.pdf rename to submodules/WalletUI/WalletImages.xcassets/Wallet/DuckIcon.imageset/duck.pdf diff --git a/submodules/WalletUI/Images.xcassets/Wallet/NavigationSettingsIcon.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationSettingsIcon.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/NavigationSettingsIcon.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationSettingsIcon.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/NavigationSettingsIcon.imageset/NavigationSettingsIcon.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationSettingsIcon.imageset/NavigationSettingsIcon.pdf similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/NavigationSettingsIcon.imageset/NavigationSettingsIcon.pdf rename to submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationSettingsIcon.imageset/NavigationSettingsIcon.pdf diff --git a/submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationShareIcon.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationShareIcon.imageset/Contents.json new file mode 100644 index 0000000000..bbeea7231a --- /dev/null +++ b/submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationShareIcon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_share.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationShareIcon.imageset/ic_share.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationShareIcon.imageset/ic_share.pdf new file mode 100644 index 0000000000..c372a213f7 Binary files /dev/null and b/submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationShareIcon.imageset/ic_share.pdf differ diff --git a/submodules/WalletUI/Images.xcassets/Wallet/QrGem.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/QrGem.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/QrGem.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/QrGem.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/QrGem.imageset/QrGem@2x.png b/submodules/WalletUI/WalletImages.xcassets/Wallet/QrGem.imageset/QrGem@2x.png similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/QrGem.imageset/QrGem@2x.png rename to submodules/WalletUI/WalletImages.xcassets/Wallet/QrGem.imageset/QrGem@2x.png diff --git a/submodules/WalletUI/Images.xcassets/Wallet/QrGem.imageset/QrGem@3x.png b/submodules/WalletUI/WalletImages.xcassets/Wallet/QrGem.imageset/QrGem@3x.png similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/QrGem.imageset/QrGem@3x.png rename to submodules/WalletUI/WalletImages.xcassets/Wallet/QrGem.imageset/QrGem@3x.png diff --git a/submodules/WalletUI/Images.xcassets/Wallet/QrIcon.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/QrIcon.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/QrIcon.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/QrIcon.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/QrIcon.imageset/ic_qrcode.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/QrIcon.imageset/ic_qrcode.pdf similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/QrIcon.imageset/ic_qrcode.pdf rename to submodules/WalletUI/WalletImages.xcassets/Wallet/QrIcon.imageset/ic_qrcode.pdf diff --git a/submodules/WalletUI/Images.xcassets/Wallet/ReceiveButtonIcon.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/ReceiveButtonIcon.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/ReceiveButtonIcon.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/ReceiveButtonIcon.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/ReceiveButtonIcon.imageset/Group2.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/ReceiveButtonIcon.imageset/Group2.pdf similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/ReceiveButtonIcon.imageset/Group2.pdf rename to submodules/WalletUI/WalletImages.xcassets/Wallet/ReceiveButtonIcon.imageset/Group2.pdf diff --git a/submodules/WalletUI/Images.xcassets/Wallet/RefreshIcon.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/RefreshIcon.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/RefreshIcon.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/RefreshIcon.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/RefreshIcon.imageset/ic_walletupdate.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/RefreshIcon.imageset/ic_walletupdate.pdf similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/RefreshIcon.imageset/ic_walletupdate.pdf rename to submodules/WalletUI/WalletImages.xcassets/Wallet/RefreshIcon.imageset/ic_walletupdate.pdf diff --git a/submodules/WalletUI/Images.xcassets/Wallet/SendButtonIcon.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/SendButtonIcon.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/SendButtonIcon.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/SendButtonIcon.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/SendButtonIcon.imageset/Group.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/SendButtonIcon.imageset/Group.pdf similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/SendButtonIcon.imageset/Group.pdf rename to submodules/WalletUI/WalletImages.xcassets/Wallet/SendButtonIcon.imageset/Group.pdf diff --git a/submodules/WalletUI/Images.xcassets/Wallet/TransactionGem.imageset/Contents.json b/submodules/WalletUI/WalletImages.xcassets/Wallet/TransactionGem.imageset/Contents.json similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/TransactionGem.imageset/Contents.json rename to submodules/WalletUI/WalletImages.xcassets/Wallet/TransactionGem.imageset/Contents.json diff --git a/submodules/WalletUI/Images.xcassets/Wallet/TransactionGem.imageset/SmallGem.pdf b/submodules/WalletUI/WalletImages.xcassets/Wallet/TransactionGem.imageset/SmallGem.pdf similarity index 100% rename from submodules/WalletUI/Images.xcassets/Wallet/TransactionGem.imageset/SmallGem.pdf rename to submodules/WalletUI/WalletImages.xcassets/Wallet/TransactionGem.imageset/SmallGem.pdf