mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-05 19:28:46 +02:00
Merge commit '2cb0c7f147' into beta
This commit is contained in:
commit
f97eca0172
1642 changed files with 847925 additions and 2906 deletions
6
.bazelrc
6
.bazelrc
|
|
@ -22,3 +22,9 @@ build --spawn_strategy=standalone
|
|||
build --strategy=SwiftCompile=standalone
|
||||
build --define RULES_SWIFT_BUILD_DUMMY_WORKER=1
|
||||
|
||||
common:index_build --experimental_convenience_symlinks=ignore
|
||||
common:index_build --bes_backend= --bes_results_url=
|
||||
common:index_build --nolegacy_important_outputs
|
||||
common:index_build --show_result=0
|
||||
common:index_build --define=buildNumber=10000
|
||||
common:index_build --define=telegramVersion=12.2.2
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -74,3 +74,4 @@ buildServer.json
|
|||
Telegram.LSP.json
|
||||
**/.build/**
|
||||
spm-files
|
||||
.bsp/**
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -35,3 +35,6 @@ url=../tgcalls.git
|
|||
[submodule "third-party/XcodeGen"]
|
||||
path = third-party/XcodeGen
|
||||
url = https://github.com/yonaskolb/XcodeGen.git
|
||||
[submodule "build-system/bazel-rules/sourcekit-bazel-bsp"]
|
||||
path = build-system/bazel-rules/sourcekit-bazel-bsp
|
||||
url=https://github.com/ali-fareed/sourcekit-bazel-bsp.git
|
||||
|
|
|
|||
9
.sourcekit-lsp/config.json
Normal file
9
.sourcekit-lsp/config.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"backgroundIndexing": true,
|
||||
"backgroundPreparationMode": "build",
|
||||
"defaultWorkspaceType": "buildServer",
|
||||
"logging": {
|
||||
"level": "error",
|
||||
"privacyLevel": "sensitive"
|
||||
}
|
||||
}
|
||||
59
.vscode/launch.json
vendored
59
.vscode/launch.json
vendored
|
|
@ -1,44 +1,31 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "swift",
|
||||
"request": "launch",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:telegram-ios}",
|
||||
"name": "Debug Telegram",
|
||||
"program": "${workspaceFolder:telegram-ios}/.build/debug/Telegram",
|
||||
"preLaunchTask": "swift: Build Debug Telegram"
|
||||
"type": "lldb-dap",
|
||||
"request": "attach",
|
||||
"preLaunchTask": "_launch_telegram",
|
||||
"debuggerRoot": "${workspaceFolder}",
|
||||
"attachCommands": [
|
||||
"process connect connect://localhost:6667"
|
||||
],
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"timeout": 1000
|
||||
},
|
||||
{
|
||||
"type": "swift",
|
||||
"request": "launch",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:telegram-ios}",
|
||||
"name": "Release Telegram",
|
||||
"program": "${workspaceFolder:telegram-ios}/.build/release/Telegram",
|
||||
"preLaunchTask": "swift: Build Release Telegram"
|
||||
"name": "Restart Debug Telegram",
|
||||
"type": "lldb-dap",
|
||||
"request": "attach",
|
||||
"preLaunchTask": "Restart Telegram Debug",
|
||||
"debuggerRoot": "${workspaceFolder}",
|
||||
"attachCommands": [
|
||||
"process connect connect://localhost:6667"
|
||||
],
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"timeout": 1000
|
||||
},
|
||||
{
|
||||
"type": "swift",
|
||||
"request": "launch",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:telegram-ios}",
|
||||
"name": "Debug telegram-ios",
|
||||
"program": "${workspaceFolder:telegram-ios}/.build/debug/telegram-ios",
|
||||
"preLaunchTask": "swift: Build Debug telegram-ios"
|
||||
},
|
||||
{
|
||||
"type": "swift",
|
||||
"request": "launch",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:telegram-ios}",
|
||||
"name": "Release telegram-ios",
|
||||
"program": "${workspaceFolder:telegram-ios}/.build/release/telegram-ios",
|
||||
"preLaunchTask": "swift: Build Release telegram-ios"
|
||||
}
|
||||
]
|
||||
],
|
||||
"options": {
|
||||
"console": "integratedTerminal",
|
||||
}
|
||||
}
|
||||
17
.vscode/settings.json
vendored
17
.vscode/settings.json
vendored
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
"sweetpad.build.xcodeWorkspacePath": "Telegram/Telegram.xcodeproj/project.xcworkspace",
|
||||
"lldb.library": "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB",
|
||||
"lldb.launch.expressions": "native",
|
||||
"search.followSymlinks": false,
|
||||
"files.exclude": {
|
||||
".git/**": true
|
||||
|
|
@ -13,5 +10,17 @@
|
|||
".git/**": true
|
||||
},
|
||||
"files.associations": {
|
||||
}
|
||||
},
|
||||
"swift.sourcekit-lsp.backgroundIndexing": "on",
|
||||
"swift.sourcekit-lsp.trace.server": "messages",
|
||||
"terminal.integrated.profiles.osx": {
|
||||
"zsh": {
|
||||
"path": "/bin/zsh",
|
||||
"args": [
|
||||
"-l",
|
||||
"-i"
|
||||
]
|
||||
}
|
||||
},
|
||||
"swift.sourcekit-lsp.serverPath": "${workspaceFolder}/build-input/sourcekit-lsp",
|
||||
}
|
||||
|
|
|
|||
105
.vscode/tasks.json
vendored
105
.vscode/tasks.json
vendored
|
|
@ -1,6 +1,101 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
]
|
||||
}
|
||||
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Build Telegram",
|
||||
"type": "shell",
|
||||
"command": "${workspaceFolder}/build-input/bazel-8.4.2-darwin-arm64",
|
||||
"args": [
|
||||
"build",
|
||||
"Telegram/Telegram",
|
||||
"--features=swift.use_global_module_cache",
|
||||
"--verbose_failures",
|
||||
"--remote_cache_async",
|
||||
"--features=swift.skip_function_bodies_for_derived_files",
|
||||
"--jobs=16",
|
||||
"--define=buildNumber=10000",
|
||||
"--define=telegramVersion=12.2.2",
|
||||
"--disk_cache=${HOME}/telegram-bazel-cache",
|
||||
"-c",
|
||||
"dbg",
|
||||
"--ios_multi_cpus=sim_arm64",
|
||||
"--watchos_cpus=arm64_32",
|
||||
"--features=swift.enable_batch_mode"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"runOptions": {
|
||||
"instanceLimit": 1
|
||||
}
|
||||
},
|
||||
// Hidden never-ending task that handles the launch / debugging bits for Cmd+Shift+D.
|
||||
// The problemMatcher field defines when the task is effectively ready to be debugged
|
||||
// by the attach task in launch.json.
|
||||
{
|
||||
"label": "_launch_telegram",
|
||||
"type": "shell",
|
||||
"command": "./scripts/launch_and_debug.sh",
|
||||
"presentation": {
|
||||
"reveal": "always"
|
||||
},
|
||||
"hide": true,
|
||||
"isBackground": true,
|
||||
"problemMatcher": [
|
||||
{
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "\\b\\B",
|
||||
"file": 1,
|
||||
"location": 2,
|
||||
"message": 3
|
||||
}
|
||||
],
|
||||
"background": {
|
||||
"activeOnStart": true,
|
||||
"beginsPattern": "^.*Building....*",
|
||||
"endsPattern": "^.*Listening to port 6667 for a connection from .*"
|
||||
}
|
||||
}
|
||||
],
|
||||
"runOptions": {
|
||||
"instanceLimit": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Stream SourceKitBazelBSP Logs",
|
||||
"type": "shell",
|
||||
"command": "log stream --process sourcekit-bazel-bsp --debug",
|
||||
"problemMatcher": [],
|
||||
"isBackground": false,
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "dedicated"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Stop Telegram Debug Session",
|
||||
"type": "shell",
|
||||
"command": "pkill -f 'launch_and_debug.sh' || true; lsof -ti:6667 | xargs kill -9 2>/dev/null || true",
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"reveal": "silent",
|
||||
"close": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Restart Telegram Debug",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn": [
|
||||
"Stop Telegram Debug Session",
|
||||
"_launch_telegram"
|
||||
],
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"reveal": "always"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
15
BUILD.bazel
Normal file
15
BUILD.bazel
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
load("@sourcekit_bazel_bsp//rules:setup_sourcekit_bsp.bzl", "setup_sourcekit_bsp")
|
||||
|
||||
setup_sourcekit_bsp(
|
||||
name = "setup_sourcekit_bsp_telegram_project",
|
||||
bazel_wrapper = "./build-input/bazel-8.4.2-darwin-arm64",
|
||||
files_to_watch = [
|
||||
"**/*.swift",
|
||||
],
|
||||
index_flags = [
|
||||
"config=index_build",
|
||||
],
|
||||
targets = [
|
||||
"//Telegram:Telegram",
|
||||
],
|
||||
)
|
||||
10
MODULE.bazel
10
MODULE.bazel
|
|
@ -30,8 +30,8 @@ local_path_override(
|
|||
|
||||
http_file(
|
||||
name = "cmake_tar_gz",
|
||||
urls = ["https://github.com/Kitware/CMake/releases/download/v3.23.1/cmake-3.23.1-macos-universal.tar.gz"],
|
||||
sha256 = "f794ed92ccb4e9b6619a77328f313497d7decf8fb7e047ba35a348b838e0e1e2",
|
||||
urls = ["https://github.com/Kitware/CMake/releases/download/v4.1.2/cmake-4.1.2-macos-universal.tar.gz"],
|
||||
sha256 = "3be85f5b999e327b1ac7d804cbc9acd767059e9f603c42ec2765f6ab68fbd367",
|
||||
)
|
||||
|
||||
http_file(
|
||||
|
|
@ -62,3 +62,9 @@ local_path_override(
|
|||
module_name = "build_configuration",
|
||||
path = "./build-input/configuration-repository",
|
||||
)
|
||||
|
||||
bazel_dep(name = "sourcekit_bazel_bsp", version = "0.3.0")
|
||||
local_path_override(
|
||||
module_name = "sourcekit_bazel_bsp",
|
||||
path = "build-system/bazel-rules/sourcekit-bazel-bsp",
|
||||
)
|
||||
10
MODULE.bazel.lock
generated
10
MODULE.bazel.lock
generated
|
|
@ -98,8 +98,8 @@
|
|||
"https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
|
||||
"https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
|
||||
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.12.0/MODULE.bazel": "8e6590b961f2defdfc2811c089c75716cb2f06c8a4edeb9a8d85eaa64ee2a761",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.12.0/source.json": "cbd5d55d9d38d4008a7d00bee5b5a5a4b6031fcd4a56515c9accbcd42c7be2ba",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939",
|
||||
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
|
||||
|
|
@ -156,7 +156,7 @@
|
|||
"moduleExtensions": {
|
||||
"@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "hUTp2w+RUVdL7ma5esCXZJAFnX7vLbVfLd7FwnQI6bU=",
|
||||
"bzlTransitiveDigest": "OlvsB0HsvxbR8ZN+J9Vf00X/+WVz/Y/5Xrq2LgcVfdo=",
|
||||
"usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
|
|
@ -256,7 +256,7 @@
|
|||
},
|
||||
"@@rules_xcodeproj+//xcodeproj:extensions.bzl%internal": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "/r7IWMTdpceHqqiSh7G9bQLHvIkfqE/cesswbkTSJZw=",
|
||||
"bzlTransitiveDigest": "hsJI1bzu5CX3ZE+NX8jnNWEOh1pNDT650SbTSBnF5jA=",
|
||||
"usagesDigest": "fvsnMonVwKDYnBfww4bXuYie3WU0d9VSqT2gePSdQco=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
|
|
@ -278,7 +278,7 @@
|
|||
},
|
||||
"@@rules_xcodeproj+//xcodeproj:extensions.bzl%non_module_deps": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "/r7IWMTdpceHqqiSh7G9bQLHvIkfqE/cesswbkTSJZw=",
|
||||
"bzlTransitiveDigest": "hsJI1bzu5CX3ZE+NX8jnNWEOh1pNDT650SbTSBnF5jA=",
|
||||
"usagesDigest": "jzxYhnOC9BE0dJ0biFLfxWXi/+R19uAAZkJ0p9CY0JI=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
|
|
|
|||
|
|
@ -495,6 +495,8 @@ associated_domains_fragment = "" if telegram_bundle_id not in official_bundle_id
|
|||
<string>applinks:telegram.me</string>
|
||||
<string>applinks:t.me</string>
|
||||
<string>applinks:*.t.me</string>
|
||||
<string>webcredentials:t.me</string>
|
||||
<string>webcredentials:telegram.org</string>
|
||||
</array>
|
||||
"""
|
||||
|
||||
|
|
|
|||
|
|
@ -15432,3 +15432,194 @@ Error: %8$@";
|
|||
|
||||
"LiveStream.ErrorMaxAllowedEmoji.Text_1" = "You can send up to %d emoji.";
|
||||
"LiveStream.ErrorMaxAllowedEmoji.Text_any" = "You can send up to %d emoji.";
|
||||
|
||||
"Stars.Purchase.StarGiftOfferInfo" = "Buy Stars to make a gift buy offer.";
|
||||
|
||||
"Notification.StarsGiftOffer.Offer" = "%1$@ offered you %2$@ for your gift %3$@";
|
||||
"Notification.StarsGiftOffer.Offer.Stars_1" = "%@ Star";
|
||||
"Notification.StarsGiftOffer.Offer.Stars_any" = "%@ Stars";
|
||||
"Notification.StarsGiftOffer.OfferYou" = "You offered %1$@ %2$@ for their gift %3$@";
|
||||
"Notification.StarsGiftOffer.OfferYou.Stars_1" = "%@ Star";
|
||||
"Notification.StarsGiftOffer.OfferYou.Stars_any" = "%@ Stars";
|
||||
|
||||
"Notification.StarsGiftOffer.Accepted" = "%1$@ accepted your offer and sold you %2$@ for %3$@";
|
||||
"Notification.StarsGiftOffer.Accepted.Stars_1" = "%@ Star";
|
||||
"Notification.StarsGiftOffer.Accepted.Stars_any" = "%@ Stars";
|
||||
"Notification.StarsGiftOffer.AcceptedYou" = "You sold %1$@ to %2$@ for %3$@";
|
||||
"Notification.StarsGiftOffer.AcceptedYou.Stars_1" = "%@ Star";
|
||||
"Notification.StarsGiftOffer.AcceptedYou.Stars_any" = "%@ Stars";
|
||||
|
||||
"Notification.StarsGiftOffer.Rejected" = "%1$@ rejected your offer for %2$@ – your %3$@ have been refunded";
|
||||
"Notification.StarsGiftOffer.Rejected.Stars_1" = "%@ Star";
|
||||
"Notification.StarsGiftOffer.Rejected.Stars_any" = "%@ Stars";
|
||||
"Notification.StarsGiftOffer.RejectedYou" = "You rejected %1$@'s offer";
|
||||
"Notification.StarsGiftOffer.RejectedYou.Stars_1" = "%@ Star";
|
||||
"Notification.StarsGiftOffer.RejectedYou.Stars_any" = "%@ Stars";
|
||||
|
||||
"Notification.StarsGiftOffer.Expired" = "%1$@ didn't respond to your offer for %2$@ within %3$@ – your %4$@ have been refunded";
|
||||
"Notification.StarsGiftOffer.Expired.Stars_1" = "%@ Star";
|
||||
"Notification.StarsGiftOffer.Expired.Stars_any" = "%@ Stars";
|
||||
"Notification.StarsGiftOffer.ExpiredYou" = "The offer from %1$@ to buy your %2$@ for %3$@ has expired";
|
||||
"Notification.StarsGiftOffer.ExpiredYou.Stars_1" = "%@ Star";
|
||||
"Notification.StarsGiftOffer.ExpiredYou.Stars_any" = "%@ Stars";
|
||||
|
||||
"CreateExternalStream.RevokeStreamKey" = "Revoke Stream Key";
|
||||
"CreateExternalStream.Revoke.Text" = "Do you want to revoke the stream key?";
|
||||
"CreateExternalStream.Revoke.Revoke" = "Revoke";
|
||||
|
||||
"Gift.AuctionBid.UntilEnd" = "until the end";
|
||||
"Gift.AuctionBid.BeforeStart" = "before start";
|
||||
"Gift.AuctionBid.RoundSubtitle" = "Round %@ of %@";
|
||||
"Gift.AuctionBid.TopWinnersTotal" = "Top 3 of %@ Winners";
|
||||
|
||||
"Gift.Acquired.GiftRound" = "%1$@ in round %2$@";
|
||||
|
||||
"Gift.Options.Gift.Soon" = "soon";
|
||||
|
||||
"Chat.Auction.StartsIn" = "starts in ";
|
||||
"Chat.Auction.View" = "VIEW";
|
||||
"Chat.Auction.Upcoming" = "Upcoming Auction";
|
||||
|
||||
"Gift.Auction.Start" = "Start";
|
||||
"Gift.Auction.End" = "End";
|
||||
"Gift.Auction.Quantity" = "Quantity";
|
||||
"Gift.Auction.TotalRounds" = "Rounds";
|
||||
"Gift.Auction.TimeRound" = "Round %@";
|
||||
"Gift.Auction.TimeRounds" = "Rounds %@";
|
||||
"Gift.Auction.StartsInHours" = "auction starts in {h}:{m}:{s}";
|
||||
"Gift.Auction.StartsInMinutes" = "auction starts in {m}:{s}";
|
||||
"Gift.Auction.EarlyBid" = "Place an Early Bid";
|
||||
"Gift.Auction.ViewVariants" = "View";
|
||||
"Gift.Auction.Variants_1" = "%@ Variant";
|
||||
"Gift.Auction.Variants_any" = "%@ Variants";
|
||||
|
||||
"Gift.Auction.Hours_1" = "%@ hour";
|
||||
"Gift.Auction.Hours_any" = "%@ hours";
|
||||
"Gift.Auction.Minutes_1" = "%@ minute";
|
||||
"Gift.Auction.Minutes_any" = "%@ minutes";
|
||||
"Gift.Auction.Seconds_1" = "%@ second";
|
||||
"Gift.Auction.Seconds_any" = "%@ seconds";
|
||||
"Gift.Auction.HoursEach_1" = "%@ hour each";
|
||||
"Gift.Auction.HoursEach_any" = "%@ hours each";
|
||||
"Gift.Auction.MinutesEach_1" = "%@ minute each";
|
||||
"Gift.Auction.MinutesEach_any" = "%@ minutes each";
|
||||
"Gift.Auction.Extension" = "+ %1$@ for late bids in top %2$@";
|
||||
|
||||
"ChatList.Auctions.UpcomingAuction" = "Upcoming Auction";
|
||||
|
||||
"Gift.AuctionBid.UpcomingBid" = "You've placed an early bid";
|
||||
"ChatList.Auctions.Status.UpcomingBid" = "You've placed an early bid.";
|
||||
"Gift.ActiveAuctions.UpcomingBid" = "You've placed an early bid";
|
||||
|
||||
"Login.PhoneWithPasskeySubtitle" = "Enter your phone number\nor [log in using Passkey >](passkey)";
|
||||
"PrivacySettings.Passkey" = "Passkey";
|
||||
"Attachment.SharedAudio" = "SHARED AUDIO";
|
||||
"Attachment.FilesSearchPlaceholder" = "Search shared audio";
|
||||
"Chat.GiftPurchaseOffer.Reject" = "Reject";
|
||||
"Chat.GiftPurchaseOffer.Accept" = "Accept";
|
||||
"Chat.GiftPurchaseOffer.RejectConfirmation.Title" = "Reject Offer";
|
||||
"Chat.GiftPurchaseOffer.RejectConfirmation.Text" = "Are you sure you want to reject the offer from **%@**?";
|
||||
"Chat.GiftPurchaseOffer.RejectConfirmation.Reject" = "Reject";
|
||||
|
||||
"Passkeys.DeleteAlert.Title" = "Delete Passkey?";
|
||||
"Passkeys.DeleteAlert.Text" = "Once deleted, this passkey can't be used to log in.\n\nDon't forget to remove it from your password manager too.";
|
||||
"Passkeys.DeleteAlert.Action" = "Delete";
|
||||
"Passkeys.Into.Title" = "Protect your account";
|
||||
"Passkeys.Subtitle" = "Log in safely and keep your account secure.";
|
||||
"Passkeys.Into.Title0" = "Create a Passkey";
|
||||
"Passkeys.Into.Text0" = "Make a passkey to sign in easily and safely.";
|
||||
"Passkeys.Into.Title1" = "Log in with Face ID";
|
||||
"Passkeys.Into.Text1" = "Use Face ID, Touch ID, or your passcode to sign in.";
|
||||
"Passkeys.Into.Title2" = "Store Passkey Securely";
|
||||
"Passkeys.Into.Text2" = "Your passkey is safely kept in your iCloud Keychain.";
|
||||
"Passkeys.ButtonCreate" = "Create Passkey";
|
||||
"Passkeys.ButtonSkip" = "Skip";
|
||||
"Passkeys.Title" = "Passkeys";
|
||||
"Passkeys.Subtitle" = "Log in safely and keep your account secure.";
|
||||
"Passkeys.EmptyName" = "Passkey";
|
||||
"Passkeys.PasskeyCreatedPattern" = "created %@";
|
||||
"Passkeys.PasskeyCreatedAndUsedPattern" = "created %1$@ • used %2$@";
|
||||
"Passkeys.AddPasskey" = "Create Passkey";
|
||||
"Passkeys.ListFooter" = "Your passkeys are stored securely in your password manager.";
|
||||
|
||||
"Gift.Demo.Title" = "Unique Collectibles";
|
||||
"Gift.Demo.Description" = "Telegram Gifts are collectible items you can trade or showcase on your profile.";
|
||||
"Gift.Demo.Unique.Title" = "Unique";
|
||||
"Gift.Demo.Unique.Text" = "Upgrade your gifts to get a unique number, model, backdrop and symbol.";
|
||||
"Gift.Demo.Tradable.Title" = "Tradable";
|
||||
"Gift.Demo.Tradable.Text" = "Sell your gift on Telegram or on third-party NFT marketplaces.";
|
||||
"Gift.Demo.Wearable.Title" = "Wearable";
|
||||
"Gift.Demo.Wearable.Text" = "Display gifts on your page and set them as profile covers or statuses.";
|
||||
"Gift.Demo.Understood" = "Understood";
|
||||
|
||||
"Gift.Variants.RandomTraits" = "Random Traits";
|
||||
"Gift.Variants.SelectedTraits" = "Selected Traits";
|
||||
"Gift.Variants.Randomize" = "Randomize Traits";
|
||||
"Gift.Variants.Model" = "model";
|
||||
"Gift.Variants.Backdrop" = "backdrop";
|
||||
"Gift.Variants.Symbol" = "symbol";
|
||||
"Gift.Variants.Models" = "Models";
|
||||
"Gift.Variants.Backdrops" = "Backdrops";
|
||||
"Gift.Variants.Symbols" = "Symbols";
|
||||
|
||||
"Gift.Variants.CollectionInfo" = "This collection features %@";
|
||||
"Gift.Variants.CollectionInfo.Model_1" = "**%@** unique model";
|
||||
"Gift.Variants.CollectionInfo.Model_any" = "**%@** unique models";
|
||||
"Gift.Variants.CollectionInfo.Backdrop_1" = "**%@** unique backdrop";
|
||||
"Gift.Variants.CollectionInfo.Backdrop_any" = "**%@** unique backdrops";
|
||||
"Gift.Variants.CollectionInfo.Symbol_1" = "**%@** unique symbol";
|
||||
"Gift.Variants.CollectionInfo.Symbol_any" = "**%@** unique symbols";
|
||||
|
||||
"Gift.Auction.GiftAuction" = "Upcoming Auction";
|
||||
"Gift.Auction.UpcomingAuction" = "Upcoming Auction";
|
||||
"Gift.Auction.LearnMore" = "Learn more about Telegram Gifts >";
|
||||
|
||||
"Gift.AuctionBid.UpcomingTitle" = "Place an Early Bid";
|
||||
|
||||
"Gift.View.Context.BuyOffer" = "Offer to Buy";
|
||||
|
||||
"Gift.Offer.Title" = "Offer to Buy";
|
||||
"Gift.Offer.OfferStars" = "Offer Stars";
|
||||
"Gift.Offer.OfferTon" = "Offer TON";
|
||||
"Gift.Offer.PriceSectionStars" = "STARS TO OFFER";
|
||||
"Gift.Offer.PriceSectionTon" = "TON TO OFFER";
|
||||
"Gift.Offer.PricePlaceholder" = "Price";
|
||||
"Gift.Offer.PriceDescriptionStars" = "Enter the number of Stars you'd like to offer for **%@**.";
|
||||
"Gift.Offer.PriceDescriptionTon" = "Enter the number of TON you'd like to offer for **%@**.";
|
||||
"Gift.Offer.Duration" = "Offer Duration";
|
||||
"Gift.Offer.DurationDescriptionStars" = "Choose how long **%@** can accept your offer. When the time expires, your Stars will be automatically refunded.";
|
||||
"Gift.Offer.DurationDescriptionTon" = "Choose how long **%@** can accept your offer. When the time expires, your TON will be automatically refunded.";
|
||||
"Gift.Offer.Duration.Hours_1" = "%@ Hour";
|
||||
"Gift.Offer.Duration.Hours_any" = "%@ Hours";
|
||||
"Gift.Offer.Offer" = "Offer";
|
||||
"Gift.Offer.GiftMinAmountToast.Text" = "You cannot offer less than %@ for this gift";
|
||||
|
||||
"Gift.WearPreview.Limited" = "limited";
|
||||
"Gift.WearPreview.Upgraded" = "upgraded";
|
||||
"Gift.WearPreview.FreeUpgrade" = "Free\nUpgrade";
|
||||
"Gift.WearPreview.LearnMore" = "Learn more about wearing Telegram Gifts >";
|
||||
|
||||
"Notification.StarGift.Sold" = "sold";
|
||||
"Notification.StarGiftOffer.Offer" = "**%1$@** offered you **%2$@** for your gift **%3$@**.";
|
||||
"Notification.StarGiftOffer.OfferYou" = "You offered **%1$@** **%2$@** for their gift **%3$@**.";
|
||||
"Notification.StarGiftOffer.Offer.Stars_1" = "%@ Star";
|
||||
"Notification.StarGiftOffer.Offer.Stars_any" = "%@ Stars";
|
||||
|
||||
"Notification.StarGiftOffer.Status.Accepted" = "This offer was accepted.";
|
||||
"Notification.StarGiftOffer.Status.Expired" = "This offer has expired.";
|
||||
"Notification.StarGiftOffer.Status.Expires" = "This offer expires in %@";
|
||||
"Notification.StarGiftOffer.Status.Rejected" = "This offer was rejected.";
|
||||
|
||||
"Notification.StarGiftOffer.Expiration.Hours_1" = "%@ h";
|
||||
"Notification.StarGiftOffer.Expiration.Hours_any" = "%@ h";
|
||||
"Notification.StarGiftOffer.Expiration.Minutes_1" = "%@ m";
|
||||
"Notification.StarGiftOffer.Expiration.Minutes_any" = "%@ m";
|
||||
"Notification.StarGiftOffer.Expiration.Delimiter" = "";
|
||||
|
||||
"Chat.GiftPurchaseOffer.AcceptConfirmation.Title" = "Confirm Sale";
|
||||
"Chat.GiftPurchaseOffer.AcceptConfirmation.Text" = "Do you want to sell **%1$@** to %2$@ for **%3$@**? You'll receive **%4$@** after fees.";
|
||||
"Chat.GiftPurchaseOffer.AcceptConfirmation.Text.Stars_1" = "%@ Star";
|
||||
"Chat.GiftPurchaseOffer.AcceptConfirmation.Text.Stars_any" = "%@ Stars";
|
||||
"Chat.GiftPurchaseOffer.AcceptConfirmation.BadValue" = "The value of this gift is **%@** higher than the offer.";
|
||||
"Chat.GiftPurchaseOffer.AcceptConfirmation.Confirm" = "Confirm Sale";
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ class BazelCommandLine:
|
|||
self.additional_args = None
|
||||
self.build_number = None
|
||||
self.configuration_args = None
|
||||
self.configuration_path = None
|
||||
self.split_submodules = False
|
||||
self.custom_target = None
|
||||
self.continue_on_error = False
|
||||
|
|
@ -68,7 +67,7 @@ class BazelCommandLine:
|
|||
'--verbose_failures',
|
||||
|
||||
# Asynchronously upload cache artifacts
|
||||
'--experimental_remote_cache_async',
|
||||
'--remote_cache_async',
|
||||
]
|
||||
|
||||
self.common_build_args = [
|
||||
|
|
@ -89,12 +88,6 @@ class BazelCommandLine:
|
|||
# invoking a smaller number of frontend processes and passing them batches of
|
||||
# source files.
|
||||
'--features=swift.enable_batch_mode',
|
||||
|
||||
# https://docs.bazel.build/versions/master/command-line-reference.html
|
||||
# Set the number of parallel jobs per module to saturate the available CPU resources.
|
||||
#'--swiftcopt=-j{}'.format(os.cpu_count() - 1),
|
||||
'--@build_bazel_rules_swift//swift:copt="-j{}"'.format(os.cpu_count() - 1),
|
||||
'--@build_bazel_rules_swift//swift:copt="-whole-module-optimization"',
|
||||
]
|
||||
|
||||
self.common_release_args = [
|
||||
|
|
@ -147,9 +140,6 @@ class BazelCommandLine:
|
|||
def set_split_swiftmodules(self, value):
|
||||
self.split_submodules = value
|
||||
|
||||
def set_configuration_path(self, path):
|
||||
self.configuration_path = path
|
||||
|
||||
def set_disable_provisioning_profiles(self):
|
||||
self.disable_provisioning_profiles = True
|
||||
|
||||
|
|
@ -203,8 +193,6 @@ class BazelCommandLine:
|
|||
|
||||
# Require DSYM files as build output.
|
||||
'--output_groups=+dsyms',
|
||||
|
||||
#'--@build_bazel_rules_swift//swift:copt="-num-threads 0"',
|
||||
] + self.common_release_args
|
||||
else:
|
||||
raise Exception('Unknown configuration {}'.format(configuration))
|
||||
|
|
@ -296,13 +284,6 @@ class BazelCommandLine:
|
|||
if self.disable_provisioning_profiles:
|
||||
combined_arguments += ['--//Telegram:disableProvisioningProfiles']
|
||||
|
||||
if self.configuration_path is None:
|
||||
raise Exception('configuration_path is not defined')
|
||||
|
||||
combined_arguments += [
|
||||
'--override_repository=build_configuration={}'.format(self.configuration_path)
|
||||
]
|
||||
|
||||
combined_arguments += self.common_args
|
||||
combined_arguments += self.common_build_args
|
||||
combined_arguments += self.get_define_arguments()
|
||||
|
|
@ -336,13 +317,6 @@ class BazelCommandLine:
|
|||
|
||||
combined_arguments += ['Tests/AllTests']
|
||||
|
||||
if self.configuration_path is None:
|
||||
raise Exception('configuration_path is not defined')
|
||||
|
||||
combined_arguments += [
|
||||
'--override_repository=build_configuration={}'.format(self.configuration_path)
|
||||
]
|
||||
|
||||
combined_arguments += self.common_args
|
||||
combined_arguments += self.common_build_args
|
||||
combined_arguments += self.get_define_arguments()
|
||||
|
|
@ -371,13 +345,6 @@ class BazelCommandLine:
|
|||
combined_arguments += self.get_startup_bazel_arguments()
|
||||
combined_arguments += ['aquery']
|
||||
|
||||
if self.configuration_path is None:
|
||||
raise Exception('configuration_path is not defined')
|
||||
|
||||
combined_arguments += [
|
||||
'--override_repository=build_configuration={}'.format(self.configuration_path)
|
||||
]
|
||||
|
||||
combined_arguments += [
|
||||
'-c', 'dbg',
|
||||
'--ios_multi_cpus=sim_arm64',
|
||||
|
|
@ -425,13 +392,6 @@ class BazelCommandLine:
|
|||
if self.disable_provisioning_profiles:
|
||||
combined_arguments += ['--//Telegram:disableProvisioningProfiles']
|
||||
|
||||
if self.configuration_path is None:
|
||||
raise Exception('configuration_path is not defined')
|
||||
|
||||
combined_arguments += [
|
||||
'--override_repository=build_configuration={}'.format(self.configuration_path)
|
||||
]
|
||||
|
||||
combined_arguments += self.common_args
|
||||
combined_arguments += self.common_build_args
|
||||
combined_arguments += self.get_define_arguments()
|
||||
|
|
@ -562,9 +522,6 @@ def resolve_configuration(base_path, bazel_command_line: BazelCommandLine, argum
|
|||
file.write(' "{}",\n'.format(file_name))
|
||||
file.write('])\n')
|
||||
|
||||
if bazel_command_line is not None:
|
||||
bazel_command_line.set_configuration_path(configuration_repository_path)
|
||||
|
||||
|
||||
def generate_project(bazel, arguments):
|
||||
bazel_command_line = BazelCommandLine(
|
||||
|
|
@ -617,7 +574,6 @@ def generate_project(bazel, arguments):
|
|||
disable_provisioning_profiles=disable_provisioning_profiles,
|
||||
include_release=project_include_release,
|
||||
generate_dsym=generate_dsym,
|
||||
configuration_path=bazel_command_line.configuration_path,
|
||||
bazel_app_arguments=bazel_command_line.get_project_generation_arguments(),
|
||||
target_name=target_name
|
||||
)
|
||||
|
|
@ -1006,14 +962,10 @@ if __name__ == '__main__':
|
|||
buildParser.add_argument(
|
||||
'--configuration',
|
||||
choices=[
|
||||
'debug_universal',
|
||||
'debug_arm64',
|
||||
'debug_armv7',
|
||||
'debug_sim_arm64',
|
||||
'release_sim_arm64',
|
||||
'release_arm64',
|
||||
'release_armv7',
|
||||
'release_universal'
|
||||
],
|
||||
required=True,
|
||||
help='Build configuration'
|
||||
|
|
@ -1254,14 +1206,10 @@ if __name__ == '__main__':
|
|||
spm_parser.add_argument(
|
||||
'--configuration',
|
||||
choices=[
|
||||
'debug_universal',
|
||||
'debug_arm64',
|
||||
'debug_armv7',
|
||||
'debug_sim_arm64',
|
||||
'release_sim_arm64',
|
||||
'release_arm64',
|
||||
'release_armv7',
|
||||
'release_universal'
|
||||
],
|
||||
required=True,
|
||||
help='Build configuration'
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ def remove_directory(path):
|
|||
if os.path.isdir(path):
|
||||
shutil.rmtree(path)
|
||||
|
||||
def generate_xcodeproj(build_environment: BuildEnvironment, disable_extensions, disable_provisioning_profiles, include_release, generate_dsym, configuration_path, bazel_app_arguments, target_name):
|
||||
def generate_xcodeproj(build_environment: BuildEnvironment, disable_extensions, disable_provisioning_profiles, include_release, generate_dsym, bazel_app_arguments, target_name):
|
||||
if '/' in target_name:
|
||||
app_target_spec = target_name.split('/')[0] + '/' + target_name.split('/')[1] + ':' + target_name.split('/')[1]
|
||||
app_target = target_name
|
||||
|
|
@ -22,7 +22,6 @@ def generate_xcodeproj(build_environment: BuildEnvironment, disable_extensions,
|
|||
bazel_generate_arguments = [build_environment.bazel_path]
|
||||
|
||||
bazel_generate_arguments += ['run', '//{}_xcodeproj'.format(app_target_spec)]
|
||||
bazel_generate_arguments += ['--override_repository=build_configuration={}'.format(configuration_path)]
|
||||
|
||||
if target_name == 'Telegram':
|
||||
if disable_extensions:
|
||||
|
|
@ -32,7 +31,6 @@ def generate_xcodeproj(build_environment: BuildEnvironment, disable_extensions,
|
|||
project_bazel_arguments = []
|
||||
for argument in bazel_app_arguments:
|
||||
project_bazel_arguments.append(argument)
|
||||
project_bazel_arguments += ['--override_repository=build_configuration={}'.format(configuration_path)]
|
||||
|
||||
if target_name == 'Telegram':
|
||||
if disable_extensions:
|
||||
|
|
@ -54,5 +52,5 @@ def generate_xcodeproj(build_environment: BuildEnvironment, disable_extensions,
|
|||
return xcodeproj_path
|
||||
|
||||
|
||||
def generate(build_environment: BuildEnvironment, disable_extensions, disable_provisioning_profiles, include_release, generate_dsym, configuration_path, bazel_app_arguments, target_name) -> str:
|
||||
return generate_xcodeproj(build_environment, disable_extensions, disable_provisioning_profiles, include_release, generate_dsym, configuration_path, bazel_app_arguments, target_name)
|
||||
def generate(build_environment: BuildEnvironment, disable_extensions, disable_provisioning_profiles, include_release, generate_dsym, bazel_app_arguments, target_name) -> str:
|
||||
return generate_xcodeproj(build_environment, disable_extensions, disable_provisioning_profiles, include_release, generate_dsym, bazel_app_arguments, target_name)
|
||||
|
|
|
|||
1
build-system/bazel-rules/sourcekit-bazel-bsp
Submodule
1
build-system/bazel-rules/sourcekit-bazel-bsp
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit fb37d850e8715df81761feeea25f2158514fa2be
|
||||
|
|
@ -52,9 +52,9 @@ class EncryptionV2
|
|||
iv = keyIv[32..43]
|
||||
auth_data = keyIv[44..-1]
|
||||
|
||||
puts "key: #{key.inspect}"
|
||||
puts "iv: #{iv.inspect}"
|
||||
puts "auth_data: #{auth_data.inspect}"
|
||||
#puts "key: #{key.inspect}"
|
||||
#puts "iv: #{iv.inspect}"
|
||||
#puts "auth_data: #{auth_data.inspect}"
|
||||
|
||||
cipher.key = key
|
||||
cipher.iv = iv
|
||||
|
|
|
|||
755
scripts/Telegram
Executable file
755
scripts/Telegram
Executable file
|
|
@ -0,0 +1,755 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright 2020 The Bazel Authors. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Invoked by `bazel run` to launch *_application targets in the simulator."""
|
||||
|
||||
# This script works in one of two modes.
|
||||
#
|
||||
# If either --ios_simulator_version or --ios_simulator_device were not
|
||||
# passed to bazel:
|
||||
#
|
||||
# 1. Discovers a simulator compatible with the minimum_os of the
|
||||
# *_application target, preferring already-booted simulators
|
||||
# if possible
|
||||
# 2. Boots the simulator if needed
|
||||
# 3. Installs and launches the application
|
||||
# 4. Displays the application's output on the console
|
||||
#
|
||||
# This mode does not kill running simulators or shutdown or delete the simulator
|
||||
# after it completes.
|
||||
#
|
||||
# If --ios_simulator_version and --ios_simulator_device were both passed
|
||||
# to bazel:
|
||||
#
|
||||
# 1. Creates a new temporary simulator by running "simctl create ..."
|
||||
# 2. Boots the new temporary simulator
|
||||
# 3. Installs and launches the application
|
||||
# 4. Displays the application's output on the console
|
||||
# 5. When done, shuts down and deletes the newly-created simulator
|
||||
#
|
||||
# All environment variables with names starting with "IOS_" are passed to the
|
||||
# application, after stripping the prefix "IOS_".
|
||||
|
||||
import collections.abc
|
||||
import contextlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
import pathlib
|
||||
import platform
|
||||
import plistlib
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
from typing import Dict, Optional
|
||||
import zipfile
|
||||
|
||||
|
||||
# Custom type for methods yielding an Apple simulator UDID.
|
||||
AppleSimulatorUDID = collections.abc.Generator[str, None, None]
|
||||
|
||||
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s.%(msecs)03d %(levelname)s %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S",
|
||||
level=logging.INFO,
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if platform.system() != "Darwin":
|
||||
raise Exception(
|
||||
"Cannot run Apple platform application targets on a non-mac machine."
|
||||
)
|
||||
|
||||
|
||||
class DeviceType(collections.abc.Mapping):
|
||||
"""Wraps the `devicetype` dictionary from `simctl list -j`.
|
||||
|
||||
Provides an ordering so iPhones > iPads. In addition, maintains the
|
||||
original order from `simctl list` as `simctl_list_index` to ensure
|
||||
newer device types are sorted after older device types.
|
||||
"""
|
||||
|
||||
def __init__(self, device_type, simctl_list_index):
|
||||
self.device_type = device_type
|
||||
self.simctl_list_index = simctl_list_index
|
||||
|
||||
def __getitem__(self, name):
|
||||
return self.device_type[name]
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.device_type)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.device_type)
|
||||
|
||||
def __repr__(self):
|
||||
return self["name"] + " (" + self["identifier"] + ")"
|
||||
|
||||
def __lt__(self, other):
|
||||
# Order iPhones ahead of (later in the list than) iPads.
|
||||
if self.is_ipad() and other.is_iphone():
|
||||
return True
|
||||
elif self.is_iphone() and other.is_ipad():
|
||||
return False
|
||||
# Order device types from the same product family in the same order
|
||||
# as `simctl list`.
|
||||
return self.simctl_list_index < other.simctl_list_index
|
||||
|
||||
def supports_platform_type(self, platform_type: str) -> bool:
|
||||
"""Returns boolean to indicate if device supports given Apple platform type."""
|
||||
if platform_type == "ios":
|
||||
return self.is_iphone() or self.is_ipad()
|
||||
elif platform_type == "tvos":
|
||||
return self.is_apple_tv()
|
||||
elif platform_type == "watchos":
|
||||
return self.is_apple_watch()
|
||||
elif platform_type == "visionos":
|
||||
return self.is_apple_vision()
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Apple platform type not supported for simulator: {platform_type}."
|
||||
)
|
||||
|
||||
def is_apple_tv(self) -> bool:
|
||||
return self.has_product_family_or_identifier("Apple TV")
|
||||
|
||||
def is_apple_watch(self) -> bool:
|
||||
return self.has_product_family_or_identifier("Apple Watch")
|
||||
|
||||
def is_apple_vision(self) -> bool:
|
||||
return self.has_product_family_or_identifier("Apple Vision")
|
||||
|
||||
def is_iphone(self) -> bool:
|
||||
return self.has_product_family_or_identifier("iPhone")
|
||||
|
||||
def is_ipad(self) -> bool:
|
||||
return self.has_product_family_or_identifier("iPad")
|
||||
|
||||
def has_product_family_or_identifier(self, device_type: str) -> bool:
|
||||
product_family = self.get("productFamily")
|
||||
if product_family:
|
||||
return product_family == device_type
|
||||
# Some older simulators are missing `productFamily`. Try to guess from the
|
||||
# identifier.
|
||||
return device_type in self["identifier"]
|
||||
|
||||
|
||||
class Device(collections.abc.Mapping):
|
||||
"""Wraps the `device` dictionary from `simctl list -j`.
|
||||
|
||||
Provides an ordering so booted devices > shutdown devices, delegating
|
||||
to `DeviceType` order when both devices have the same state.
|
||||
"""
|
||||
|
||||
def __init__(self, device, device_type):
|
||||
self.device = device
|
||||
self.device_type = device_type
|
||||
|
||||
def is_shutdown(self):
|
||||
return self["state"] == "Shutdown"
|
||||
|
||||
def is_booted(self):
|
||||
return self["state"] == "Booted"
|
||||
|
||||
def __getitem__(self, name):
|
||||
return self.device[name]
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.device)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.device)
|
||||
|
||||
def __repr__(self):
|
||||
return self["name"] + "(" + self["udid"] + ")"
|
||||
|
||||
def __lt__(self, other):
|
||||
if self.is_shutdown() and other.is_booted():
|
||||
return True
|
||||
elif self.is_booted() and other.is_shutdown():
|
||||
return False
|
||||
else:
|
||||
return self.device_type < other.device_type
|
||||
|
||||
|
||||
def minimum_os_to_simctl_runtime_version(minimum_os: str) -> int:
|
||||
"""Converts a minimum OS string to a simctl RuntimeVersion integer.
|
||||
|
||||
Args:
|
||||
minimum_os: A string in the form '12.2' or '13.2.3'.
|
||||
|
||||
Returns:
|
||||
An integer in the form 0xAABBCC, where AA is the major version, BB is
|
||||
the minor version, and CC is the micro version.
|
||||
"""
|
||||
# Pad the minimum OS version to major.minor.micro.
|
||||
minimum_os_components = (minimum_os.split(".") + ["0"] * 3)[:3]
|
||||
result = 0
|
||||
for component in minimum_os_components:
|
||||
result = (result << 8) | int(component)
|
||||
return result
|
||||
|
||||
|
||||
def discover_best_compatible_simulator(
|
||||
*,
|
||||
platform_type: str,
|
||||
simctl_path: str,
|
||||
minimum_os: str,
|
||||
sim_device: str,
|
||||
sim_os_version: str,
|
||||
) -> (Optional[DeviceType], Optional[Device]):
|
||||
"""Discovers the best compatible simulator device type and device.
|
||||
|
||||
Args:
|
||||
platform_type: The Apple platform type for the given *_application() target.
|
||||
simctl_path: The path to the `simctl` binary.
|
||||
minimum_os: The minimum OS version required by the *_application() target.
|
||||
sim_device: Optional name of the device (e.g. "iPhone 8 Plus").
|
||||
sim_os_version: Optional version of the Apple platform runtime (e.g.
|
||||
"13.2").
|
||||
|
||||
Returns:
|
||||
A tuple (device_type, device) containing the DeviceType and Device
|
||||
of the best compatible simulator (might be None if no match was found).
|
||||
|
||||
Raises:
|
||||
subprocess.SubprocessError: if `simctl list` fails or times out.
|
||||
"""
|
||||
# The `simctl list` CLI provides only very basic case-insensitive description
|
||||
# matching search term functionality.
|
||||
#
|
||||
# This code needs to enforce a numeric floor on `minimum_os`, so it directly
|
||||
# parses the JSON output by `simctl list` instead of repeatedly invoking
|
||||
# `simctl list` with search terms.
|
||||
cmd = [simctl_path, "list", "-j"]
|
||||
with subprocess.Popen(cmd, stdout=subprocess.PIPE) as process:
|
||||
simctl_data = json.load(process.stdout)
|
||||
if process.wait() != os.EX_OK:
|
||||
raise subprocess.CalledProcessError(process.returncode, cmd)
|
||||
compatible_device_types = []
|
||||
minimum_runtime_version = minimum_os_to_simctl_runtime_version(minimum_os)
|
||||
# Prepare the device name for case-insensitive matching.
|
||||
sim_device = sim_device and sim_device.casefold()
|
||||
# `simctl list` orders device types from oldest to newest. Remember
|
||||
# the index of each device type to preserve that ordering when
|
||||
# sorting device types.
|
||||
for simctl_list_index, device_type in enumerate(simctl_data["devicetypes"]):
|
||||
device_type = DeviceType(device_type, simctl_list_index)
|
||||
if not device_type.supports_platform_type(platform_type):
|
||||
continue
|
||||
# Some older simulators are missing `maxRuntimeVersion`. Assume those
|
||||
# simulators support all OSes (even though it's not true).
|
||||
max_runtime_version = device_type.get("maxRuntimeVersion")
|
||||
if max_runtime_version and max_runtime_version < minimum_runtime_version:
|
||||
continue
|
||||
if sim_device and device_type["name"].casefold() != sim_device:
|
||||
continue
|
||||
compatible_device_types.append(device_type)
|
||||
compatible_device_types.sort()
|
||||
# logger.info(
|
||||
# "Found %d potentialcompatible device types.", len(compatible_device_types)
|
||||
# )
|
||||
compatible_runtime_identifiers = set()
|
||||
for runtime in simctl_data["runtimes"]:
|
||||
if not runtime["isAvailable"]:
|
||||
continue
|
||||
if sim_os_version and runtime["version"] != sim_os_version:
|
||||
continue
|
||||
compatible_runtime_identifiers.add(runtime["identifier"])
|
||||
compatible_devices = []
|
||||
for runtime_identifier, devices in simctl_data["devices"].items():
|
||||
if runtime_identifier not in compatible_runtime_identifiers:
|
||||
continue
|
||||
for device in devices:
|
||||
if not device["isAvailable"]:
|
||||
continue
|
||||
compatible_device = None
|
||||
for device_type in compatible_device_types:
|
||||
if device["deviceTypeIdentifier"] == device_type["identifier"]:
|
||||
compatible_device = Device(device, device_type)
|
||||
break
|
||||
if not compatible_device:
|
||||
continue
|
||||
compatible_devices.append(compatible_device)
|
||||
compatible_devices.sort()
|
||||
logger.debug("Found %d compatible devices.", len(compatible_devices))
|
||||
if compatible_device_types:
|
||||
best_compatible_device_type = compatible_device_types[-1]
|
||||
else:
|
||||
best_compatible_device_type = None
|
||||
if compatible_devices:
|
||||
best_compatible_device = compatible_devices[-1]
|
||||
else:
|
||||
best_compatible_device = None
|
||||
return (best_compatible_device_type, best_compatible_device)
|
||||
|
||||
|
||||
def persistent_simulator(
|
||||
*,
|
||||
platform_type: str,
|
||||
simctl_path: str,
|
||||
minimum_os: str,
|
||||
sim_device: str,
|
||||
sim_os_version: str,
|
||||
) -> str:
|
||||
"""Finds or creates a persistent compatible Apple simulator.
|
||||
|
||||
Boots the simulator if needed. Does not shut down or delete the simulator when
|
||||
done.
|
||||
|
||||
Args:
|
||||
platform_type: The Apple platform type for the given *_application() target.
|
||||
simctl_path: The path to the `simctl` binary.
|
||||
minimum_os: The minimum OS version required by the *_application() target.
|
||||
sim_device: Optional name of the device (e.g. "iPhone 8 Plus").
|
||||
sim_os_version: Optional version of the Apple platform runtime (e.g.
|
||||
"13.2").
|
||||
|
||||
Returns:
|
||||
The UDID of the compatible Apple simulator.
|
||||
|
||||
Raises:
|
||||
Exception: if a compatible simulator was not found.
|
||||
"""
|
||||
(best_compatible_device_type, best_compatible_device) = (
|
||||
discover_best_compatible_simulator(
|
||||
platform_type=platform_type,
|
||||
simctl_path=simctl_path,
|
||||
minimum_os=minimum_os,
|
||||
sim_device=sim_device,
|
||||
sim_os_version=sim_os_version,
|
||||
)
|
||||
)
|
||||
if best_compatible_device:
|
||||
udid = best_compatible_device["udid"]
|
||||
if best_compatible_device.is_shutdown():
|
||||
logger.debug("Booting compatible device: %s", best_compatible_device)
|
||||
subprocess.run([simctl_path, "boot", udid], check=True)
|
||||
else:
|
||||
logger.debug("Using compatible device: %s", best_compatible_device)
|
||||
return udid
|
||||
if best_compatible_device_type:
|
||||
device_name = best_compatible_device_type["name"]
|
||||
device_id = best_compatible_device_type["identifier"]
|
||||
# logger.info("Creating new %s simulator", device_name)
|
||||
create_result = subprocess.run(
|
||||
[simctl_path, "create", device_name, device_id],
|
||||
encoding="utf-8",
|
||||
stdout=subprocess.PIPE,
|
||||
check=True,
|
||||
)
|
||||
udid = create_result.stdout.rstrip()
|
||||
logger.debug("Created new simulator: %s", udid)
|
||||
return udid
|
||||
raise Exception(
|
||||
f"Could not find or create a simulator for the {platform_type} platform"
|
||||
f"compatible with minimum OS version {minimum_os} (device name "
|
||||
f"{sim_device}, OS version {sim_os_version})"
|
||||
)
|
||||
|
||||
|
||||
def wait_for_sim_to_boot(simctl_path: str, udid: str) -> bool:
|
||||
"""Blocks until the given simulator is booted.
|
||||
|
||||
Args:
|
||||
simctl_path: The path to the `simctl` binary.
|
||||
udid: The identifier of the simulator to wait for.
|
||||
|
||||
Returns:
|
||||
True if the simulator boots within 60 seconds, False otherwise.
|
||||
"""
|
||||
logger.info("Waiting for simulator to boot...")
|
||||
for _ in range(0, 60):
|
||||
# The expected output of "simctl list" is like:
|
||||
# -- iOS 8.4 --
|
||||
# iPhone 5s (E946FA1C-26AB-465C-A7AC-24750D520BEA) (Shutdown)
|
||||
# TestDevice (8491C4BC-B18E-4E2D-934A-54FA76365E48) (Booted)
|
||||
# So if there's any booted simulator, $booted_device will not be empty.
|
||||
#logger.info("will list devices with udid: %s", udid)
|
||||
simctl_list_result = subprocess.run(
|
||||
[simctl_path, "list", "devices"],
|
||||
encoding="utf-8",
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
#logger.info(simctl_list_result.stdout)
|
||||
for line in simctl_list_result.stdout.split("\n"):
|
||||
if line.find(udid) != -1 and line.find("Booted") != -1:
|
||||
logger.debug("Simulator is booted.")
|
||||
# Simulator is booted.
|
||||
return True
|
||||
logger.debug("Simulator not booted, still waiting...")
|
||||
time.sleep(1)
|
||||
return False
|
||||
|
||||
|
||||
def boot_simulator(*, developer_path: str, simctl_path: str, udid: str) -> None:
|
||||
"""Launches the Apple simulator for the given identifier.
|
||||
|
||||
Ensures the Simulator process is in the foreground.
|
||||
|
||||
Args:
|
||||
developer_path: The path to /Applications/Xcode.app/Contents/Developer.
|
||||
simctl_path: The path to the `simctl` binary.
|
||||
udid: The identifier of the simulator to wait for.
|
||||
|
||||
Raises:
|
||||
Exception: if the simulator did not launch within 60 seconds.
|
||||
"""
|
||||
logger.info("Launching simulator with udid: %s", udid)
|
||||
# Using subprocess.Popen() to launch Simulator.app and then
|
||||
# `osascript -e "tell application \"Simulator\" to activate" is racy
|
||||
# and can fail with:
|
||||
#
|
||||
# Simulator got an error: Connection is invalid. (-609)
|
||||
#
|
||||
# This is likely because the newly-spawned Simulator.app process
|
||||
# hasn't had time to connect to the Apple Events system which
|
||||
# `osascript` relies on.
|
||||
simulator_path = os.path.join(developer_path, "Applications/Simulator.app")
|
||||
subprocess.run(
|
||||
["open", "-a", simulator_path, "--args", "-CurrentDeviceUDID", udid],
|
||||
check=True,
|
||||
)
|
||||
logger.debug("Simulator launched.")
|
||||
if not wait_for_sim_to_boot(simctl_path, udid):
|
||||
raise Exception("Failed to launch simulator with UDID: " + udid)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def temporary_simulator(
|
||||
*, platform_type: str, simctl_path: str, device: str, version: str
|
||||
) -> AppleSimulatorUDID:
|
||||
"""Creates a temporary Apple simulator, cleaned up automatically upon close.
|
||||
|
||||
Args:
|
||||
platform_type: The Apple platform type for the given *_application() target.
|
||||
simctl_path: The path to the `simctl` binary.
|
||||
device: The name of the device (e.g. "iPhone 8 Plus").
|
||||
version: The version of the Apple platform runtime (e.g. "13.2").
|
||||
|
||||
Yields:
|
||||
The UDID of the newly-created Apple simulator.
|
||||
"""
|
||||
runtime_version_name = version.replace(".", "-")
|
||||
# capitalizes 'os' from Apple platform type string (e.g. watchos -> watchOS)
|
||||
runtime_platform = platform_type[0:-2].lower() + platform_type[-2:].upper()
|
||||
# logger.info("Creating simulator, device=%s, version=%s", device, version)
|
||||
simctl_create_result = subprocess.run(
|
||||
[
|
||||
simctl_path,
|
||||
"create",
|
||||
"TestDevice",
|
||||
device,
|
||||
"{prefix}.{runtime_platform}-{runtime_version_name}".format(
|
||||
prefix="com.apple.CoreSimulator.SimRuntime",
|
||||
runtime_platform=runtime_platform,
|
||||
runtime_version_name=runtime_version_name,
|
||||
),
|
||||
],
|
||||
encoding="utf-8",
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
udid = simctl_create_result.stdout.rstrip()
|
||||
try:
|
||||
logger.info("Killing all running simulators...")
|
||||
subprocess.run(
|
||||
["pkill", "Simulator"], stderr=subprocess.DEVNULL, check=False
|
||||
)
|
||||
yield udid
|
||||
finally:
|
||||
logger.info("Shutting down simulator with udid: %s", udid)
|
||||
subprocess.run(
|
||||
[simctl_path, "shutdown", udid], stderr=subprocess.DEVNULL, check=False
|
||||
)
|
||||
logger.info("Deleting simulator with udid: %s", udid)
|
||||
subprocess.run([simctl_path, "delete", udid], check=True)
|
||||
|
||||
|
||||
def register_dsyms(dsyms_dir: str):
|
||||
"""Adds all dSYMs in `dsyms_dir` to the symbolscache.
|
||||
|
||||
Args:
|
||||
dsyms_dir: Path to directory potentially containing dSYMs
|
||||
"""
|
||||
symbolscache_command = [
|
||||
"/usr/bin/symbolscache",
|
||||
"delete",
|
||||
"--tag",
|
||||
"Bazel",
|
||||
"compact",
|
||||
"add",
|
||||
"--tag",
|
||||
"Bazel",
|
||||
] + [
|
||||
a
|
||||
for a in pathlib.Path(dsyms_dir).glob(
|
||||
"**/*.dSYM/Contents/Resources/DWARF/*"
|
||||
)
|
||||
]
|
||||
logger.debug("Running command: %s", symbolscache_command)
|
||||
result = subprocess.run(
|
||||
symbolscache_command,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
encoding="utf-8",
|
||||
text=True,
|
||||
)
|
||||
logger.debug("symbolscache output: %s", result.stdout)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def extracted_app(
|
||||
application_output_path: str, app_name: str
|
||||
) -> AppleSimulatorUDID:
|
||||
"""Extracts Foo.app from *_application() output and makes it writable.
|
||||
|
||||
Args:
|
||||
application_output_path: Path to the output of an `*_application()`. If the
|
||||
path is a directory, copies it to a temporary directory and makes the
|
||||
contents writable, as `simctl install` fails to install an `.app` that is
|
||||
read-only. If the path is an .ipa archive, unzips it to a temporary
|
||||
directory.
|
||||
app_name: The name of the application (e.g. "Foo" for "Foo.app").
|
||||
|
||||
Yields:
|
||||
Path to Foo.app in temporary directory (re-used if already present).
|
||||
"""
|
||||
if os.path.isdir(application_output_path):
|
||||
# Re-use the same path for each run and rsync to it (reducing
|
||||
# copies). Ensure the result is writable, or `simctl install` will
|
||||
# fail with `Unhandled error domain NSPOSIXErrorDomain, code 13`.
|
||||
dst_dir = os.path.join(tempfile.gettempdir(), "bazel_temp_" + app_name)
|
||||
os.makedirs(dst_dir, exist_ok=True)
|
||||
|
||||
# NOTE: use `which` to find the path to `rsync`.
|
||||
# In macOS 15.4, the system `rsync` is using `openrsync` which contains some permission issues.
|
||||
# This allows users to workaround the issue by overriding the system `rsync` with a working version.
|
||||
# Remove this once we no longer support macOS versions with broken `rsync`.
|
||||
rsync_path = shutil.which("rsync")
|
||||
|
||||
rsync_command = [
|
||||
rsync_path,
|
||||
"--archive",
|
||||
"--delete",
|
||||
"--checksum",
|
||||
"--chmod=u+w",
|
||||
"--verbose",
|
||||
# The output path might itself be a symlink; resolve to the
|
||||
# real path so rsync doesn't just copy the symlink.
|
||||
os.path.realpath(application_output_path),
|
||||
dst_dir,
|
||||
]
|
||||
logger.debug(
|
||||
"Found app directory: %s, running command: %s",
|
||||
application_output_path,
|
||||
rsync_command,
|
||||
)
|
||||
result = subprocess.run(
|
||||
rsync_command,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
encoding="utf-8",
|
||||
text=True,
|
||||
)
|
||||
logger.debug("rsync output: %s", result.stdout)
|
||||
yield os.path.join(dst_dir, app_name + ".app")
|
||||
else:
|
||||
# Create a new temporary directory for each run, deleting it
|
||||
# afterwards (there's no efficient way to "sync" an unzip, so this
|
||||
# can't re-use the output directory).
|
||||
with tempfile.TemporaryDirectory(prefix="bazel_temp") as temp_dir:
|
||||
logger.debug(
|
||||
"Unzipping IPA from %s to %s", application_output_path, temp_dir
|
||||
)
|
||||
with zipfile.ZipFile(application_output_path) as ipa_zipfile:
|
||||
ipa_zipfile.extractall(temp_dir)
|
||||
yield os.path.join(temp_dir, "Payload", app_name + ".app")
|
||||
|
||||
|
||||
def bundle_id(bundle_path: str) -> str:
|
||||
"""Returns the bundle ID given a bundle directory path."""
|
||||
info_plist_path = os.path.join(bundle_path, "Info.plist")
|
||||
with open(info_plist_path, mode="rb") as plist_file:
|
||||
plist = plistlib.load(plist_file)
|
||||
return plist["CFBundleIdentifier"]
|
||||
|
||||
|
||||
def simctl_launch_environ() -> Dict[str, str]:
|
||||
"""Calculates an environment dictionary for running `simctl launch`."""
|
||||
# Pass environment variables prefixed with "IOS_" to the simulator, replace
|
||||
# the prefix with "SIMCTL_CHILD_". bazel adds "IOS_" to the env vars which
|
||||
# will be passed to the app as prefix to differentiate from other env vars. We
|
||||
# replace the prefix "IOS_" with "SIMCTL_CHILD_" here, because "simctl" only
|
||||
# pass the env vars prefixed with "SIMCTL_CHILD_" to the app.
|
||||
result = {}
|
||||
for k, v in os.environ.items():
|
||||
if not k.startswith("IOS_"):
|
||||
continue
|
||||
new_key = k.replace("IOS_", "SIMCTL_CHILD_", 1)
|
||||
result[new_key] = v
|
||||
if "IDE_DISABLED_OS_ACTIVITY_DT_MODE" not in os.environ:
|
||||
# Ensure os_log() mirrors writes to stderr. (lldb and Xcode set this
|
||||
# environment variable as well.)
|
||||
result["SIMCTL_CHILD_OS_ACTIVITY_DT_MODE"] = "enable"
|
||||
return result
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def apple_simulator(
|
||||
*,
|
||||
platform_type: str,
|
||||
simctl_path: str,
|
||||
minimum_os: str,
|
||||
sim_device: str,
|
||||
sim_os_version: str,
|
||||
) -> AppleSimulatorUDID:
|
||||
"""Finds either a temporary or persistent Apple simulator based on args.
|
||||
|
||||
Args:
|
||||
platform_type: The Apple platform type for the given *_application() target.
|
||||
simctl_path: The path to the `simctl` binary.
|
||||
minimum_os: The minimum OS version required by the *_application() target.
|
||||
sim_device: Optional name of the device (e.g. "iPhone 8 Plus").
|
||||
sim_os_version: Optional version of the Apple platform runtime (e.g.
|
||||
"13.2").
|
||||
|
||||
Yields:
|
||||
The UDID of the simulator.
|
||||
"""
|
||||
yield persistent_simulator(
|
||||
platform_type=platform_type,
|
||||
simctl_path=simctl_path,
|
||||
minimum_os=minimum_os,
|
||||
sim_device=sim_device,
|
||||
sim_os_version=sim_os_version,
|
||||
)
|
||||
|
||||
|
||||
def run_app_in_simulator(
|
||||
*,
|
||||
simulator_udid: str,
|
||||
developer_path: str,
|
||||
simctl_path: str,
|
||||
application_output_path: str,
|
||||
app_name: str,
|
||||
) -> None:
|
||||
"""Installs and runs an app in the specified simulator.
|
||||
|
||||
Args:
|
||||
simulator_udid: The UDID of the simulator in which to run the app.
|
||||
developer_path: The path to /Applications/Xcode.app/Contents/Developer.
|
||||
simctl_path: The path to the `simctl` binary.
|
||||
application_output_path: Path to the output of an `*_application()`.
|
||||
app_name: The name of the application (e.g. "Foo" for "Foo.app").
|
||||
"""
|
||||
boot_simulator(
|
||||
developer_path=developer_path,
|
||||
simctl_path=simctl_path,
|
||||
udid=simulator_udid,
|
||||
)
|
||||
root_dir = os.path.dirname(application_output_path)
|
||||
register_dsyms(root_dir)
|
||||
with extracted_app(application_output_path, app_name) as app_path:
|
||||
logger.info("Will use simulator: %s", simulator_udid)
|
||||
logger.info(
|
||||
"Terminating any existing instances of the app in that simulator..."
|
||||
)
|
||||
# First, quietly kill any existing instances of the app
|
||||
app_bundle_id = bundle_id(app_path)
|
||||
subprocess.run(
|
||||
[simctl_path, "terminate", simulator_udid, app_bundle_id],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
logger.info("Installing...")
|
||||
subprocess.run(
|
||||
[simctl_path, "install", simulator_udid, app_path], check=True
|
||||
)
|
||||
logger.info(
|
||||
"Launching..."
|
||||
)
|
||||
args = [
|
||||
simctl_path,
|
||||
"launch",
|
||||
]
|
||||
# Append optional launch arguments.
|
||||
args.extend(sys.argv[1:])
|
||||
args.extend([
|
||||
simulator_udid,
|
||||
app_bundle_id,
|
||||
])
|
||||
subprocess.run(args, env=simctl_launch_environ(), check=True)
|
||||
|
||||
|
||||
def main(
|
||||
*,
|
||||
app_name: str,
|
||||
application_output_path: str,
|
||||
minimum_os: str,
|
||||
platform_type: str,
|
||||
sim_device: str,
|
||||
sim_os_version: str,
|
||||
):
|
||||
"""Main entry point to `bazel run` for *_application() targets.
|
||||
|
||||
Args:
|
||||
app_name: The name of the application (e.g. "Foo" for "Foo.app").
|
||||
application_output_path: Path to the output of an *_application().
|
||||
minimum_os: The minimum OS version required by the *_application() target.
|
||||
platform_type: The Apple platform type for the given *_application() target.
|
||||
sim_device: The name of the device (e.g. "iPhone 8 Plus").
|
||||
sim_os_version: The version of the Apple platform runtime (e.g. "13.2").
|
||||
"""
|
||||
xcode_select_result = subprocess.run(
|
||||
["xcode-select", "-p"],
|
||||
encoding="utf-8",
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
developer_path = xcode_select_result.stdout.rstrip()
|
||||
simctl_path = os.path.join(developer_path, "usr", "bin", "simctl")
|
||||
|
||||
with apple_simulator(
|
||||
platform_type=platform_type,
|
||||
simctl_path=simctl_path,
|
||||
minimum_os=minimum_os,
|
||||
sim_device=sim_device,
|
||||
sim_os_version=sim_os_version,
|
||||
) as simulator_udid:
|
||||
run_app_in_simulator(
|
||||
simulator_udid=simulator_udid,
|
||||
developer_path=developer_path,
|
||||
simctl_path=simctl_path,
|
||||
application_output_path=application_output_path,
|
||||
app_name=app_name,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(
|
||||
app_name="Telegram",
|
||||
application_output_path="Telegram/Telegram.ipa",
|
||||
minimum_os="13.0",
|
||||
platform_type="ios",
|
||||
sim_device="iPhone 16 Pro",
|
||||
sim_os_version="26.0",
|
||||
)
|
||||
39
scripts/launch_and_debug.sh
Executable file
39
scripts/launch_and_debug.sh
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/zsh
|
||||
|
||||
set -e
|
||||
|
||||
# We don't use bazelisk run because it does a bunch of things we don't want in this case.
|
||||
# Instead, we have our own script for launching the simulator and lldb.
|
||||
# Ideally we should upstream these changes back to rules_apple since they should be useful for everyone.
|
||||
|
||||
echo "Building..."
|
||||
./build-input/bazel-8.4.2-darwin-arm64 build Telegram/Telegram --announce_rc --features=swift.use_global_module_cache --verbose_failures --remote_cache_async --jobs=16 --define=buildNumber=10000 --define=telegramVersion=12.2.1 --disk_cache=/Users/ali/telegram-bazel-cache -c dbg --ios_multi_cpus=sim_arm64 --watchos_cpus=arm64_32 --features=swift.enable_batch_mode
|
||||
chmod -R 777 ./bazel-bin/Telegram
|
||||
|
||||
tmp_file=$(pwd)/bazel-bin/Telegram/pid.txt
|
||||
rm ${tmp_file} > /dev/null 2>&1 || true
|
||||
touch ${tmp_file}
|
||||
cp ./scripts/Telegram ./bazel-bin/Telegram/Telegram
|
||||
|
||||
pushd ./bazel-bin
|
||||
python3 ./Telegram/Telegram --wait-for-debugger --stdout=$(tty) --stderr=$(tty) > ${tmp_file}
|
||||
popd
|
||||
|
||||
# Get pid from the tmp_file
|
||||
echo "$(cat "${tmp_file}" | awk -F': ' '{print $2}')" > ${tmp_file}
|
||||
# Ugly hack to remove the newline from the file
|
||||
pid=$(tr -d '\n' < ${tmp_file})
|
||||
echo "Launched app's pid: ${pid}"
|
||||
|
||||
xcode_path=$(xcode-select -p)
|
||||
debugserver_path="${xcode_path}/../SharedFrameworks/LLDB.framework/Versions/A/Resources/debugserver"
|
||||
|
||||
# Just for sanity, kill any other debugservers that might be running
|
||||
pgrep -lfa Resources/debugserver | awk '{print $1}' | xargs kill -9
|
||||
|
||||
# Launch the debugserver. The output of this command will signal the IDE to launch the lldb extension,
|
||||
# which is hardcoded to connect to port 6667.
|
||||
${debugserver_path} "localhost:6667" --attach ${pid}
|
||||
|
||||
# Kill the app when debugging ends, just like in Xcode.
|
||||
kill -9 ${pid} > /dev/null 2>&1 || true
|
||||
|
|
@ -1178,6 +1178,7 @@ public enum StarsWithdrawalScreenSubject {
|
|||
case enterAmount(current: StarsAmount, minValue: StarsAmount, fractionAfterCommission: Int, kind: PaidMessageKind, completion: (Int64) -> Void)
|
||||
case postSuggestion(channel: EnginePeer, isFromAdmin: Bool, current: CurrencyAmount, timestamp: Int32?, completion: (CurrencyAmount, Int32?) -> Void)
|
||||
case postSuggestionModification(current: CurrencyAmount, timestamp: Int32?, completion: (CurrencyAmount, Int32?) -> Void)
|
||||
case starGiftOffer(peer: EnginePeer, gift: StarGift.UniqueGift, completion: (CurrencyAmount, Int32) -> Void)
|
||||
}
|
||||
|
||||
public enum ChannelMembersSearchControllerMode {
|
||||
|
|
@ -1272,6 +1273,7 @@ public protocol SharedAccountContext: AnyObject {
|
|||
func navigateToChat(accountId: AccountRecordId, peerId: PeerId, messageId: MessageId?)
|
||||
func openChatMessage(_ params: OpenChatMessageParams) -> Bool
|
||||
func messageFromPreloadedChatHistoryViewForLocation(id: MessageId, location: ChatHistoryLocationInput, context: AccountContext, chatLocation: ChatLocation, subject: ChatControllerSubject?, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tag: HistoryViewInputTag?) -> Signal<(MessageIndex?, Bool), NoError>
|
||||
|
||||
func makeOverlayAudioPlayerController(context: AccountContext, chatLocation: ChatLocation, type: MediaManagerPlayerType, initialMessageId: MessageId, initialOrder: MusicPlaybackSettingsOrder, playlistLocation: SharedMediaPlaylistLocation?, parentNavigationController: NavigationController?) -> ViewController & OverlayAudioPlayerController
|
||||
func makePeerInfoController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: Peer, mode: PeerInfoControllerMode, avatarInitiallyExpanded: Bool, fromChat: Bool, requestsContext: PeerInvitationImportersContext?) -> ViewController?
|
||||
func makeChannelAdminController(context: AccountContext, peerId: PeerId, adminId: PeerId, initialParticipant: ChannelParticipant) -> ViewController?
|
||||
|
|
@ -1355,54 +1357,34 @@ public protocol SharedAccountContext: AnyObject {
|
|||
func makeInstantPageController(context: AccountContext, message: Message, sourcePeerType: MediaAutoDownloadPeerType?) -> ViewController?
|
||||
func makeInstantPageController(context: AccountContext, webPage: TelegramMediaWebpage, anchor: String?, sourceLocation: InstantPageSourceLocation) -> ViewController
|
||||
func openChatWallpaper(context: AccountContext, message: Message, present: @escaping (ViewController, Any?) -> Void)
|
||||
|
||||
func makeRecentSessionsController(context: AccountContext, activeSessionsContext: ActiveSessionsContext) -> ViewController & RecentSessionsController
|
||||
|
||||
func makeChatQrCodeScreen(context: AccountContext, peer: Peer, threadId: Int64?, temporary: Bool) -> ViewController
|
||||
|
||||
func makePremiumIntroController(context: AccountContext, source: PremiumIntroSource, forceDark: Bool, dismissed: (() -> Void)?) -> ViewController
|
||||
func makePremiumIntroController(sharedContext: SharedAccountContext, engine: TelegramEngineUnauthorized, inAppPurchaseManager: InAppPurchaseManager, source: PremiumIntroSource, proceed: (() -> Void)?) -> ViewController
|
||||
|
||||
func makePremiumDemoController(context: AccountContext, subject: PremiumDemoSubject, forceDark: Bool, action: @escaping () -> Void, dismissed: (() -> Void)?) -> ViewController
|
||||
func makePremiumLimitController(context: AccountContext, subject: PremiumLimitSubject, count: Int32, forceDark: Bool, cancel: @escaping () -> Void, action: @escaping () -> Bool) -> ViewController
|
||||
|
||||
func makeStarsGiftController(context: AccountContext, birthdays: [EnginePeer.Id: TelegramBirthday]?, completion: @escaping (([EnginePeer.Id]) -> Void)) -> ViewController
|
||||
func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (([EnginePeer.Id]) -> Signal<Never, TransferStarGiftError>)?) -> ViewController
|
||||
func makeGiftOptionsController(context: AccountContext, peerId: EnginePeer.Id, premiumOptions: [CachedPremiumGiftOption], hasBirthday: Bool, completion: (() -> Void)?) -> ViewController
|
||||
func makeGiftStoreController(context: AccountContext, peerId: EnginePeer.Id, gift: StarGift.Gift) -> ViewController
|
||||
func makePremiumPrivacyControllerController(context: AccountContext, subject: PremiumPrivacySubject, peerId: EnginePeer.Id) -> ViewController
|
||||
func makePremiumBoostLevelsController(context: AccountContext, peerId: EnginePeer.Id, subject: BoostSubject, boostStatus: ChannelBoostStatus, myBoostStatus: MyBoostStatus, forceDark: Bool, openStats: (() -> Void)?) -> ViewController
|
||||
|
||||
func makeStickerPackScreen(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, mainStickerPack: StickerPackReference, stickerPacks: [StickerPackReference], loadedStickerPacks: [LoadedStickerPack], actionTitle: String?, isEditing: Bool, expandIfNeeded: Bool, parentNavigationController: NavigationController?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, actionPerformed: ((Bool) -> Void)?) -> ViewController
|
||||
|
||||
func makeCameraScreen(context: AccountContext, mode: CameraScreenMode, cameraHolder: Any?, transitionIn: CameraScreenTransitionIn?, transitionOut: @escaping (Bool) -> CameraScreenTransitionOut?, completion: @escaping (Any, @escaping () -> Void) -> Void, transitionedOut: (() -> Void)?) -> ViewController
|
||||
|
||||
func makeMediaPickerScreen(context: AccountContext, hasSearch: Bool, completion: @escaping (Any) -> Void) -> ViewController
|
||||
|
||||
func makeStoryMediaEditorScreen(context: AccountContext, source: Any?, text: String?, link: (url: String, name: String?)?, remainingCount: Int32, completion: @escaping ([MediaEditorScreenResult], MediaEditorTransitionOutExternalState, @escaping (@escaping () -> Void) -> Void) -> Void) -> ViewController
|
||||
|
||||
func makeBotPreviewEditorScreen(context: AccountContext, source: Any?, target: Stories.PendingTarget, transitionArguments: (UIView, CGRect, UIImage?)?, transitionOut: @escaping () -> BotPreviewEditorTransitionOut?, externalState: MediaEditorTransitionOutExternalState, completion: @escaping (MediaEditorScreenResult, @escaping (@escaping () -> Void) -> Void) -> Void, cancelled: @escaping () -> Void) -> ViewController
|
||||
|
||||
func makeStickerEditorScreen(context: AccountContext, source: Any?, intro: Bool, transitionArguments: (UIView, CGRect, UIImage?)?, completion: @escaping (TelegramMediaFile, [String], @escaping () -> Void) -> Void, cancelled: @escaping () -> Void) -> ViewController
|
||||
|
||||
func makeStickerMediaPickerScreen(context: AccountContext, getSourceRect: @escaping () -> CGRect?, completion: @escaping (Any?, UIView?, CGRect, UIImage?, Bool, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void, dismissed: @escaping () -> Void) -> ViewController
|
||||
|
||||
func makeAvatarMediaPickerScreen(context: AccountContext, getSourceRect: @escaping () -> CGRect?, canDelete: Bool, performDelete: @escaping () -> Void, completion: @escaping (Any?, UIView?, CGRect, UIImage?, Bool, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void, dismissed: @escaping () -> Void) -> ViewController
|
||||
|
||||
func makeStoryMediaPickerScreen(context: AccountContext, isDark: Bool, forCollage: Bool, selectionLimit: Int?, getSourceRect: @escaping () -> CGRect, completion: @escaping (Any, UIView, CGRect, UIImage?, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void, multipleCompletion: @escaping ([Any], Bool) -> Void, dismissed: @escaping () -> Void, groupsPresented: @escaping () -> Void) -> ViewController
|
||||
|
||||
func makeStickerPickerScreen(context: AccountContext, inputData: Promise<StickerPickerInput>, completion: @escaping (FileMediaReference) -> Void) -> ViewController
|
||||
|
||||
func makeProxySettingsController(sharedContext: SharedAccountContext, account: UnauthorizedAccount) -> ViewController
|
||||
|
||||
func makeDataAndStorageController(context: AccountContext, sensitiveContent: Bool) -> ViewController
|
||||
|
||||
func makeInstalledStickerPacksController(context: AccountContext, mode: InstalledStickerPacksControllerMode, forceTheme: PresentationTheme?) -> ViewController
|
||||
|
||||
func makeChannelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, boosts: Bool, boostStatus: ChannelBoostStatus?) -> ViewController
|
||||
func makeMessagesStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, messageId: EngineMessage.Id) -> ViewController
|
||||
func makeStoryStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, storyId: Int32, storyItem: EngineStoryItem, fromStory: Bool) -> ViewController
|
||||
|
||||
func makeStarsTransactionsScreen(context: AccountContext, starsContext: StarsContext) -> ViewController
|
||||
func makeStarsPurchaseScreen(context: AccountContext, starsContext: StarsContext, options: [Any], purpose: StarsPurchasePurpose, targetPeerId: EnginePeer.Id?, customTheme: PresentationTheme?, completion: @escaping (Int64) -> Void) -> ViewController
|
||||
func makeStarsTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, completion: @escaping (Bool) -> Void) -> ViewController
|
||||
|
|
@ -1421,38 +1403,32 @@ public protocol SharedAccountContext: AnyObject {
|
|||
func makeStarsIntroScreen(context: AccountContext) -> ViewController
|
||||
func makeGiftViewScreen(context: AccountContext, message: EngineMessage, shareStory: ((StarGift.UniqueGift) -> Void)?) -> ViewController
|
||||
func makeGiftViewScreen(context: AccountContext, gift: StarGift.UniqueGift, shareStory: ((StarGift.UniqueGift) -> Void)?, openChatTheme: (() -> Void)?, dismissed: (() -> Void)?) -> ViewController
|
||||
func makeGiftWearPreviewScreen(context: AccountContext, gift: StarGift.UniqueGift) -> ViewController
|
||||
func makeGiftWearPreviewScreen(context: AccountContext, gift: StarGift, attributes: [StarGift.UniqueGift.Attribute]?) -> ViewController
|
||||
func makeGiftUpgradePreviewScreen(context: AccountContext, attributes: [StarGift.UniqueGift.Attribute], peerName: String) -> ViewController
|
||||
func makeGiftAuctionInfoScreen(context: AccountContext, auctionContext: GiftAuctionContext, completion: (() -> Void)?) -> ViewController
|
||||
func makeGiftAuctionBidScreen(context: AccountContext, toPeerId: EnginePeer.Id, text: String?, entities: [MessageTextEntity]?, hideName: Bool, auctionContext: GiftAuctionContext, acquiredGifts: Signal<[GiftAuctionAcquiredGift], NoError>?) -> ViewController
|
||||
func makeGiftAuctionViewScreen(context: AccountContext, auctionContext: GiftAuctionContext, completion: @escaping (Signal<[GiftAuctionAcquiredGift], NoError>) -> Void) -> ViewController
|
||||
func makeGiftAuctionViewScreen(context: AccountContext, auctionContext: GiftAuctionContext, completion: @escaping (Signal<[GiftAuctionAcquiredGift], NoError>, [StarGift.UniqueGift.Attribute]?) -> Void) -> ViewController
|
||||
func makeGiftAuctionActiveBidsScreen(context: AccountContext) -> ViewController
|
||||
|
||||
func makeGiftOfferScreen(context: AccountContext, gift: StarGift.UniqueGift, peer: EnginePeer, amount: CurrencyAmount, commit: @escaping () -> Void) -> ViewController
|
||||
func makeGiftUpgradeVariantsPreviewScreen(context: AccountContext, gift: StarGift, attributes: [StarGift.UniqueGift.Attribute]) -> ViewController
|
||||
func makeGiftAuctionWearPreviewScreen(context: AccountContext, auctionContext: GiftAuctionContext, acquiredGifts: Signal<[GiftAuctionAcquiredGift], NoError>?, attributes: [StarGift.UniqueGift.Attribute], completion: @escaping () -> Void) -> ViewController
|
||||
func makeGiftDemoScreen(context: AccountContext) -> ViewController
|
||||
func makeStorySharingScreen(context: AccountContext, subject: StorySharingSubject, parentController: ViewController) -> ViewController
|
||||
|
||||
func makeContentReportScreen(context: AccountContext, subject: ReportContentSubject, forceDark: Bool, present: @escaping (ViewController) -> Void, completion: @escaping () -> Void, requestSelectMessages: ((String, Data, String?) -> Void)?)
|
||||
|
||||
func makeShareController(context: AccountContext, subject: ShareControllerSubject, forceExternal: Bool, shareStory: (() -> Void)?, enqueued: (([PeerId], [Int64]) -> Void)?, actionCompleted: (() -> Void)?) -> ViewController
|
||||
|
||||
func makeMiniAppListScreenInitialData(context: AccountContext) -> Signal<MiniAppListScreenInitialData, NoError>
|
||||
func makeMiniAppListScreen(context: AccountContext, initialData: MiniAppListScreenInitialData) -> ViewController
|
||||
|
||||
func makeIncomingMessagePrivacyScreen(context: AccountContext, value: GlobalPrivacySettings.NonContactChatsPrivacy, exceptions: SelectivePrivacySettings, update: @escaping (GlobalPrivacySettings.NonContactChatsPrivacy) -> Void) -> ViewController
|
||||
|
||||
func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, botPeer: EnginePeer, chatPeer: EnginePeer?, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?, verifyAgeCompletion: ((Int) -> Void)?)
|
||||
|
||||
func makeAffiliateProgramSetupScreenInitialData(context: AccountContext, peerId: EnginePeer.Id, mode: AffiliateProgramSetupScreenMode) -> Signal<AffiliateProgramSetupScreenInitialData, NoError>
|
||||
func makeAffiliateProgramSetupScreen(context: AccountContext, initialData: AffiliateProgramSetupScreenInitialData) -> ViewController
|
||||
func makeAffiliateProgramJoinScreen(context: AccountContext, sourcePeer: EnginePeer, commissionPermille: Int32, programDuration: Int32?, revenuePerUser: Double, mode: JoinAffiliateProgramScreenMode) -> ViewController
|
||||
|
||||
func makeJoinSubjectScreen(context: AccountContext, mode: JoinSubjectScreenMode) -> ViewController
|
||||
|
||||
func makeOldChannelsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, intent: OldChannelsControllerIntent, completed: @escaping (Bool) -> Void) -> ViewController
|
||||
|
||||
func makeGalleryController(context: AccountContext, source: GalleryControllerItemSource, streamSingleVideo: Bool, isPreview: Bool) -> ViewController
|
||||
|
||||
func makeAccountFreezeInfoScreen(context: AccountContext) -> ViewController
|
||||
func makeSendInviteLinkScreen(context: AccountContext, subject: SendInviteLinkScreenSubject, peers: [TelegramForbiddenInvitePeer], theme: PresentationTheme?) -> ViewController
|
||||
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
func makePostSuggestionsSettingsScreen(context: AccountContext, peerId: EnginePeer.Id) async -> ViewController
|
||||
|
||||
|
|
@ -1471,6 +1447,7 @@ public protocol SharedAccountContext: AnyObject {
|
|||
func makeNewContactScreen(context: AccountContext, peer: EnginePeer?, phoneNumber: String?, shareViaException: Bool, completion: @escaping (EnginePeer?, DeviceContactStableId?, DeviceContactExtendedData?) -> Void) -> ViewController
|
||||
|
||||
func makeLoginEmailSetupController(context: AccountContext, blocking: Bool, emailPattern: String?, canAutoDismissIfNeeded: Bool, navigationController: NavigationController?, completion: @escaping () -> Void, dismiss: @escaping () -> Void) -> ViewController
|
||||
func makePasskeySetupController(context: AccountContext, displaySkip: Bool, navigationController: NavigationController?, completion: @escaping () -> Void, dismiss: @escaping () -> Void) -> ViewController
|
||||
|
||||
func navigateToCurrentCall()
|
||||
var hasOngoingCall: ValuePromise<Bool> { get }
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ public enum StarsPurchasePurpose: Equatable {
|
|||
case sendMessage(peerId: EnginePeer.Id, requiredStars: Int64)
|
||||
case buyStarGift(requiredStars: Int64)
|
||||
case removeOriginalDetailsStarGift(requiredStars: Int64)
|
||||
case starGiftOffer(requiredStars: Int64)
|
||||
}
|
||||
|
||||
public struct PremiumConfiguration {
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
|||
if let currentController = currentController {
|
||||
controller = currentController
|
||||
} else {
|
||||
controller = AuthorizationSequencePhoneEntryController(sharedContext: self.sharedContext, account: self.account, isTestingEnvironment: self.account.testingEnvironment, otherAccountPhoneNumbers: self.otherAccountPhoneNumbers, network: self.account.network, presentationData: self.presentationData, openUrl: { [weak self] url in
|
||||
controller = AuthorizationSequencePhoneEntryController(sharedContext: self.sharedContext, account: self.account, apiId: self.apiId, apiHash: self.apiHash, isTestingEnvironment: self.account.testingEnvironment, otherAccountPhoneNumbers: self.otherAccountPhoneNumbers, network: self.account.network, presentationData: self.presentationData, openUrl: { [weak self] url in
|
||||
self?.openUrl(url)
|
||||
}, back: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
|
|
@ -315,6 +315,48 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
|||
}
|
||||
})
|
||||
}
|
||||
controller.loginWithPasskey = { [weak self, weak controller] passkey, syncContacts in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
self.actionDisposable.set((authorizeWithPasskey(
|
||||
accountManager: self.sharedContext.accountManager,
|
||||
account: self.account,
|
||||
passkey: passkey,
|
||||
foreignDatacenter: nil,
|
||||
forcedPasswordSetupNotice: { value in
|
||||
guard let entry = CodableEntry(ApplicationSpecificCounterNotice(value: value)) else {
|
||||
return nil
|
||||
}
|
||||
return (ApplicationSpecificNotice.forcedPasswordSetupKey(), entry)
|
||||
},
|
||||
syncContacts: syncContacts
|
||||
)
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if result.updatedAccount !== self.account {
|
||||
self.account = result.updatedAccount
|
||||
self.inAppPurchaseManager = InAppPurchaseManager(engine: .unauthorized(self.engine))
|
||||
}
|
||||
}, error: { [weak self, weak controller] error in
|
||||
Queue.mainQueue().async {
|
||||
if let strongSelf = self, let controller {
|
||||
let text: String
|
||||
switch error {
|
||||
case .limitExceeded:
|
||||
text = strongSelf.presentationData.strings.Login_CodeFloodError
|
||||
case .generic, .invalidEmailAddress, .codeExpired, .invalidEmailToken, .invalidCode:
|
||||
text = strongSelf.presentationData.strings.Login_UnknownError
|
||||
}
|
||||
|
||||
controller.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
controller.updateData(countryCode: countryCode, countryName: nil, number: number)
|
||||
return controller
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ import CountrySelectionUI
|
|||
import PhoneNumberFormat
|
||||
import DebugSettingsUI
|
||||
import MessageUI
|
||||
import AuthenticationServices
|
||||
|
||||
public final class AuthorizationSequencePhoneEntryController: ViewController, MFMailComposeViewControllerDelegate {
|
||||
public final class AuthorizationSequencePhoneEntryController: ViewController, MFMailComposeViewControllerDelegate, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
|
||||
private var controllerNode: AuthorizationSequencePhoneEntryControllerNode {
|
||||
return self.displayNode as! AuthorizationSequencePhoneEntryControllerNode
|
||||
}
|
||||
|
|
@ -22,6 +23,8 @@ public final class AuthorizationSequencePhoneEntryController: ViewController, MF
|
|||
|
||||
private let sharedContext: SharedAccountContext
|
||||
private var account: UnauthorizedAccount?
|
||||
private let apiId: Int32
|
||||
private let apiHash: String
|
||||
private let isTestingEnvironment: Bool
|
||||
private let otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)])
|
||||
private let network: Network
|
||||
|
|
@ -52,6 +55,7 @@ public final class AuthorizationSequencePhoneEntryController: ViewController, MF
|
|||
}
|
||||
}
|
||||
public var loginWithNumber: ((String, Bool) -> Void)?
|
||||
public var loginWithPasskey: ((AuthorizationPasskeyData, Bool) -> Void)?
|
||||
var accountUpdated: ((UnauthorizedAccount) -> Void)?
|
||||
|
||||
weak var confirmationController: PhoneConfirmationController?
|
||||
|
|
@ -60,9 +64,11 @@ public final class AuthorizationSequencePhoneEntryController: ViewController, MF
|
|||
|
||||
private let hapticFeedback = HapticFeedback()
|
||||
|
||||
public init(sharedContext: SharedAccountContext, account: UnauthorizedAccount?, countriesConfiguration: CountriesConfiguration? = nil, isTestingEnvironment: Bool, otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)]), network: Network, presentationData: PresentationData, openUrl: @escaping (String) -> Void, back: @escaping () -> Void) {
|
||||
public init(sharedContext: SharedAccountContext, account: UnauthorizedAccount?, countriesConfiguration: CountriesConfiguration? = nil, apiId: Int32, apiHash: String, isTestingEnvironment: Bool, otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)]), network: Network, presentationData: PresentationData, openUrl: @escaping (String) -> Void, back: @escaping () -> Void) {
|
||||
self.sharedContext = sharedContext
|
||||
self.account = account
|
||||
self.apiId = apiId
|
||||
self.apiHash = apiHash
|
||||
self.isTestingEnvironment = isTestingEnvironment
|
||||
self.otherAccountPhoneNumbers = otherAccountPhoneNumbers
|
||||
self.network = network
|
||||
|
|
@ -151,6 +157,12 @@ public final class AuthorizationSequencePhoneEntryController: ViewController, MF
|
|||
strongSelf.account = account
|
||||
strongSelf.accountUpdated?(account)
|
||||
}
|
||||
self.controllerNode.retryPasskey = { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.loadAndPresentPasskey(force: true)
|
||||
}
|
||||
|
||||
if let (code, name, number) = self.currentData {
|
||||
self.controllerNode.codeAndNumber = (code, name, number)
|
||||
|
|
@ -187,6 +199,124 @@ public final class AuthorizationSequencePhoneEntryController: ViewController, MF
|
|||
} else {
|
||||
self.controllerNode.updateCountryCode()
|
||||
}
|
||||
|
||||
self.loadAndPresentPasskey(force: false)
|
||||
}
|
||||
|
||||
private func loadAndPresentPasskey(force: Bool) {
|
||||
if #available(iOS 16.0, *) {
|
||||
Task { @MainActor [weak self] in
|
||||
guard let self, let account = self.account else {
|
||||
return
|
||||
}
|
||||
|
||||
let decodeBase64: (String) -> Data? = { string in
|
||||
var string = string.replacingOccurrences(of: "-", with: "+")
|
||||
.replacingOccurrences(of: "_", with: "/")
|
||||
while string.count % 4 != 0 {
|
||||
string.append("=")
|
||||
}
|
||||
return Data(base64Encoded: string)
|
||||
}
|
||||
|
||||
let engine = TelegramEngineUnauthorized(account: account)
|
||||
let passkeyDataString = await engine.auth.requestPasskeyLoginData(apiId: self.apiId, apiHash: self.apiHash).get()
|
||||
guard let passkeyDataString, let passkeyData = passkeyDataString.data(using: .utf8) else {
|
||||
return
|
||||
}
|
||||
guard let params = try? JSONSerialization.jsonObject(with: passkeyData) as? [String: Any] else {
|
||||
return
|
||||
}
|
||||
guard let pkDict = params["publicKey"] as? [String: Any] else {
|
||||
return
|
||||
}
|
||||
guard let relyingPartyIdentifier = pkDict["rpId"] as? String else {
|
||||
return
|
||||
}
|
||||
guard let challengeBase64 = pkDict["challenge"] as? String else {
|
||||
return
|
||||
}
|
||||
guard let challengeData = decodeBase64(challengeBase64) else {
|
||||
return
|
||||
}
|
||||
|
||||
let platformProvider = ASAuthorizationPlatformPublicKeyCredentialProvider(relyingPartyIdentifier: relyingPartyIdentifier)
|
||||
let platformKeyRequest = platformProvider.createCredentialAssertionRequest(challenge: challengeData)
|
||||
let authController = ASAuthorizationController(authorizationRequests: [platformKeyRequest])
|
||||
authController.delegate = self
|
||||
authController.presentationContextProvider = self
|
||||
if force {
|
||||
authController.performRequests()
|
||||
} else {
|
||||
authController.performRequests(options: [.preferImmediatelyAvailableCredentials])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
|
||||
Task { @MainActor [weak self] in
|
||||
guard let self, let account = self.account else {
|
||||
return
|
||||
}
|
||||
|
||||
let encodeBase64URL: (Data) -> String = { data in
|
||||
var string = data.base64EncodedString()
|
||||
string = string
|
||||
.replacingOccurrences(of: "+", with: "-")
|
||||
.replacingOccurrences(of: "/", with: "_")
|
||||
string = string.replacingOccurrences(of: "=", with: "")
|
||||
return string
|
||||
}
|
||||
|
||||
if #available(iOS 17.0, *) {
|
||||
if let credential = authorization.credential as? ASAuthorizationPlatformPublicKeyCredentialAssertion {
|
||||
guard let clientData = String(data: credential.rawClientDataJSON, encoding: .utf8) else {
|
||||
return
|
||||
}
|
||||
guard let userHandle = String(data: credential.userID, encoding: .utf8) else {
|
||||
return
|
||||
}
|
||||
let passkey = AuthorizationPasskeyData(
|
||||
id: encodeBase64URL(credential.credentialID),
|
||||
clientData: clientData,
|
||||
authenticatorData: credential.rawAuthenticatorData,
|
||||
signature: credential.signature,
|
||||
userHandle: userHandle
|
||||
)
|
||||
self.loginWithPasskey?(passkey, self.controllerNode.syncContacts)
|
||||
|
||||
/*if let clientData = String(data: credential.rawClientDataJSON, encoding: .utf8), let attestationObject = credential.rawAttestationObject {
|
||||
let passkey = await component.context.engine.auth.requestCreatePasskey(id: encodeBase64URL(credential.credentialID), clientData: clientData, attestationObject: attestationObject).get()
|
||||
if let passkey {
|
||||
if self.passkeysData == nil {
|
||||
self.passkeysData = []
|
||||
self.passkeysData?.insert(passkey, at: 0)
|
||||
}
|
||||
self.state?.updated(transition: .immediate)
|
||||
}
|
||||
}*/
|
||||
let _ = account
|
||||
let _ = credential
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: any Error) {
|
||||
if (error as NSError).domain == "com.apple.AuthenticationServices.AuthorizationError" && (error as NSError).code == 1001 {
|
||||
self.controllerNode.updateDisplayPasskeyLoginOption()
|
||||
if let validLayout = self.validLayout {
|
||||
self.containerLayoutUpdated(validLayout, transition: .immediate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
|
||||
guard let windowScene = self.view.window?.windowScene else {
|
||||
preconditionFailure()
|
||||
}
|
||||
return ASPresentationAnchor(windowScene: windowScene)
|
||||
}
|
||||
|
||||
public func updateCountryCode() {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import TelegramAnimatedStickerNode
|
|||
import SolidRoundedButtonNode
|
||||
import AuthorizationUtils
|
||||
import ManagedAnimationNode
|
||||
import Markdown
|
||||
|
||||
private final class PhoneAndCountryNode: ASDisplayNode {
|
||||
let strings: PresentationStrings
|
||||
|
|
@ -312,7 +313,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||
private let managedAnimationNode: ManagedPhoneAnimationNode
|
||||
private let titleNode: ASTextNode
|
||||
private let titleActivateAreaNode: AccessibilityAreaNode
|
||||
private let noticeNode: ASTextNode
|
||||
private let noticeNode: ImmediateTextNode
|
||||
private let noticeActivateAreaNode: AccessibilityAreaNode
|
||||
private let phoneAndCountryNode: PhoneAndCountryNode
|
||||
private let contactSyncNode: ContactSyncNode
|
||||
|
|
@ -323,6 +324,8 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||
private let tokenEventsDisposable = MetaDisposable()
|
||||
var accountUpdated: ((UnauthorizedAccount) -> Void)?
|
||||
|
||||
var retryPasskey: (() -> Void)?
|
||||
|
||||
private let debugAction: () -> Void
|
||||
|
||||
var currentNumber: String {
|
||||
|
|
@ -405,7 +408,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||
self.titleActivateAreaNode = AccessibilityAreaNode()
|
||||
self.titleActivateAreaNode.accessibilityTraits = .staticText
|
||||
|
||||
self.noticeNode = ASTextNode()
|
||||
self.noticeNode = ImmediateTextNode()
|
||||
self.noticeNode.maximumNumberOfLines = 0
|
||||
self.noticeNode.isUserInteractionEnabled = true
|
||||
self.noticeNode.displaysAsynchronously = false
|
||||
|
|
@ -443,6 +446,23 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||
self.addSubnode(self.managedAnimationNode)
|
||||
self.contactSyncNode.isHidden = true
|
||||
|
||||
self.noticeNode.highlightAttributeAction = { attributes in
|
||||
if let _ = attributes[NSAttributedString.Key(rawValue: "URL")] {
|
||||
return NSAttributedString.Key(rawValue: "URL")
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
self.noticeNode.tapAttributeAction = { [weak self] attributes, _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if let _ = attributes[NSAttributedString.Key(rawValue: "URL")] as? String {
|
||||
self.retryPasskey?()
|
||||
}
|
||||
}
|
||||
self.noticeNode.linkHighlightColor = theme.list.itemAccentColor.withAlphaComponent(0.2)
|
||||
|
||||
self.phoneAndCountryNode.selectCountryCode = { [weak self] in
|
||||
self?.selectCountryCode?()
|
||||
}
|
||||
|
|
@ -484,7 +504,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||
super.didLoad()
|
||||
|
||||
self.titleNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.debugTap(_:))))
|
||||
#if DEBUG
|
||||
#if DEBUG && false
|
||||
self.noticeNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.debugQrTap(_:))))
|
||||
#endif
|
||||
}
|
||||
|
|
@ -555,6 +575,27 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||
let _ = self.phoneAndCountryNode.processNumberChange(number: self.phoneAndCountryNode.phoneInputNode.number)
|
||||
}
|
||||
|
||||
func updateDisplayPasskeyLoginOption() {
|
||||
if self.account == nil {
|
||||
return
|
||||
}
|
||||
let attributedText = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(self.strings.Login_PhoneWithPasskeySubtitle, attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: Font.regular(17.0), textColor: self.theme.list.itemPrimaryTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(17.0), textColor: self.theme.list.itemPrimaryTextColor),
|
||||
link: MarkdownAttributeSet(font: Font.regular(17.0), textColor: self.theme.list.itemAccentColor),
|
||||
linkAttribute: { url in
|
||||
return ("URL", url)
|
||||
}
|
||||
)))
|
||||
let chevronImage = generateTintedImage(image: UIImage(bundleImageName: "Item List/InlineTextRightArrow"), color: self.theme.list.itemAccentColor)
|
||||
|
||||
if let range = attributedText.string.range(of: ">"), let chevronImage {
|
||||
attributedText.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: attributedText.string))
|
||||
}
|
||||
|
||||
self.noticeNode.attributedText = attributedText
|
||||
}
|
||||
|
||||
func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
var insets = layout.insets(options: [])
|
||||
insets.top = layout.statusBarHeight ?? 20.0
|
||||
|
|
@ -565,7 +606,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||
let titleInset: CGFloat = layout.size.width > 320.0 ? 18.0 : 0.0
|
||||
let additionalBottomInset: CGFloat = layout.size.width > 320.0 ? 80.0 : 10.0
|
||||
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.account == nil ? strings.Login_NewNumber : strings.Login_PhoneTitle, font: Font.bold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.account == nil ? self.strings.Login_NewNumber : self.strings.Login_PhoneTitle, font: Font.bold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
self.titleActivateAreaNode.accessibilityLabel = self.titleNode.attributedText?.string ?? ""
|
||||
|
||||
let inset: CGFloat = 24.0
|
||||
|
|
@ -576,7 +617,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||
|
||||
let noticeInset: CGFloat = self.account == nil ? 32.0 : 0.0
|
||||
|
||||
let noticeSize = self.noticeNode.measure(CGSize(width: min(274.0 + noticeInset, maximumWidth - 28.0), height: CGFloat.greatestFiniteMagnitude))
|
||||
let noticeSize = self.noticeNode.updateLayout(CGSize(width: min(274.0 + noticeInset, maximumWidth - 28.0), height: CGFloat.greatestFiniteMagnitude))
|
||||
let proceedHeight = self.proceedNode.updateLayout(width: maximumWidth - inset * 2.0, transition: transition)
|
||||
let proceedSize = CGSize(width: maximumWidth - inset * 2.0, height: proceedHeight)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ enum BotCheckoutActionButtonState: Equatable {
|
|||
|
||||
private let titleFont = Font.semibold(17.0)
|
||||
|
||||
final class BotCheckoutActionButton: HighlightableButtonNode {
|
||||
final class BotCheckoutActionButton: HighlightTrackingButtonNode {
|
||||
static var height: CGFloat = 52.0
|
||||
|
||||
private var activeFillColor: UIColor
|
||||
private var inactiveFillColor: UIColor
|
||||
private var foregroundColor: UIColor
|
||||
|
||||
private let activeBackgroundNode: ASImageNode
|
||||
private let activeBackgroundNode: ASDisplayNode
|
||||
private var applePayButton: UIButton?
|
||||
private let labelNode: TextNode
|
||||
|
||||
|
|
@ -29,23 +29,17 @@ final class BotCheckoutActionButton: HighlightableButtonNode {
|
|||
|
||||
private var placeholderNode: ShimmerEffectNode?
|
||||
|
||||
private var activeImage: UIImage?
|
||||
private var inactiveImage: UIImage?
|
||||
|
||||
init(activeFillColor: UIColor, inactiveFillColor: UIColor, foregroundColor: UIColor) {
|
||||
self.activeFillColor = activeFillColor
|
||||
self.inactiveFillColor = inactiveFillColor
|
||||
self.foregroundColor = foregroundColor
|
||||
|
||||
let diameter: CGFloat = 20.0
|
||||
self.activeImage = generateStretchableFilledCircleImage(diameter: diameter, color: activeFillColor)
|
||||
self.inactiveImage = generateStretchableFilledCircleImage(diameter: diameter, color: inactiveFillColor)
|
||||
let diameter: CGFloat = 52.0
|
||||
|
||||
self.activeBackgroundNode = ASImageNode()
|
||||
self.activeBackgroundNode.displaysAsynchronously = false
|
||||
self.activeBackgroundNode.displayWithoutProcessing = true
|
||||
self.activeBackgroundNode = ASDisplayNode()
|
||||
self.activeBackgroundNode.isLayerBacked = true
|
||||
self.activeBackgroundNode.image = self.activeImage
|
||||
self.activeBackgroundNode.backgroundColor = activeFillColor
|
||||
self.activeBackgroundNode.cornerRadius = diameter / 2.0
|
||||
|
||||
self.labelNode = TextNode()
|
||||
self.labelNode.displaysAsynchronously = false
|
||||
|
|
@ -55,6 +49,21 @@ final class BotCheckoutActionButton: HighlightableButtonNode {
|
|||
|
||||
self.addSubnode(self.activeBackgroundNode)
|
||||
self.addSubnode(self.labelNode)
|
||||
|
||||
self.highligthedChanged = { [weak self] highlighted in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let transition = ContainedViewLayoutTransition.animated(duration: highlighted ? 0.25 : 0.35, curve: .spring)
|
||||
if highlighted {
|
||||
let highlightedColor = self.activeFillColor.withMultiplied(hue: 1.0, saturation: 0.77, brightness: 1.01)
|
||||
transition.updateBackgroundColor(node: self.activeBackgroundNode, color: highlightedColor)
|
||||
transition.updateTransformScale(node: self, scale: 1.05)
|
||||
} else {
|
||||
transition.updateBackgroundColor(node: self.activeBackgroundNode, color: self.activeFillColor)
|
||||
transition.updateTransformScale(node: self, scale: 1.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setState(_ state: BotCheckoutActionButtonState) {
|
||||
|
|
@ -93,14 +102,8 @@ final class BotCheckoutActionButton: HighlightableButtonNode {
|
|||
placeholderNode.removeFromSupernode()
|
||||
}
|
||||
|
||||
let image = isEnabled ? self.activeImage : self.inactiveImage
|
||||
if let image = image, let currentImage = self.activeBackgroundNode.image, currentImage !== image {
|
||||
self.activeBackgroundNode.image = image
|
||||
self.activeBackgroundNode.layer.animate(from: currentImage.cgImage! as AnyObject, to: image.cgImage! as AnyObject, keyPath: "contents", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.2)
|
||||
} else {
|
||||
self.activeBackgroundNode.image = image
|
||||
}
|
||||
|
||||
self.activeBackgroundNode.backgroundColor = isEnabled ? self.activeFillColor : self.inactiveFillColor
|
||||
|
||||
let makeLayout = TextNode.asyncLayout(self.labelNode)
|
||||
let (labelLayout, labelApply) = makeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: titleFont, textColor: self.foregroundColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: size, alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
let _ = labelApply()
|
||||
|
|
|
|||
|
|
@ -259,31 +259,31 @@ enum BotCheckoutEntry: ItemListNodeEntry {
|
|||
}
|
||||
})
|
||||
case let .paymentMethod(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
arguments.openPaymentMethod()
|
||||
})
|
||||
case let .shippingInfo(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
arguments.openInfo(.address(.street1))
|
||||
})
|
||||
case let .shippingMethod(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
arguments.openShippingMethod()
|
||||
})
|
||||
case let .nameInfo(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
arguments.openInfo(.name)
|
||||
})
|
||||
case let .emailInfo(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
arguments.openInfo(.email)
|
||||
})
|
||||
case let .phoneInfo(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
arguments.openInfo(.phone)
|
||||
})
|
||||
case let .actionPlaceholder(_, shimmeringIndex):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: " ", label: " ", sectionId: self.section, style: .blocks, disclosureStyle: .none, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: " ", label: " ", sectionId: self.section, style: .blocks, disclosureStyle: .none, action: {
|
||||
}, shimmeringIndex: shimmeringIndex)
|
||||
}
|
||||
}
|
||||
|
|
@ -1245,7 +1245,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
|||
override func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition, additionalInsets: UIEdgeInsets) {
|
||||
var updatedInsets = layout.intrinsicInsets
|
||||
|
||||
let bottomPanelHorizontalInset: CGFloat = 16.0
|
||||
let bottomPanelHorizontalInset: CGFloat = 30.0
|
||||
|
||||
var botName: String?
|
||||
if let botPeer = self.botPeerValue {
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ class BotCheckoutHeaderItemNode: ListViewItemNode {
|
|||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners, glass: true) : nil
|
||||
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: contentSize.height - separatorHeight), size: CGSize(width: params.width, height: separatorHeight))
|
||||
|
||||
|
|
|
|||
|
|
@ -141,13 +141,13 @@ class BotCheckoutPriceItemNode: ListViewItemNode {
|
|||
let naturalContentHeight: CGFloat
|
||||
var verticalOffset: CGFloat = 0.0
|
||||
if item.isFinal {
|
||||
naturalContentHeight = 44.0
|
||||
naturalContentHeight = 52.0
|
||||
} else {
|
||||
switch neighbors.bottom {
|
||||
case .otherSection, .none:
|
||||
naturalContentHeight = 44.0
|
||||
naturalContentHeight = 52.0
|
||||
default:
|
||||
naturalContentHeight = 34.0
|
||||
naturalContentHeight = 42.0
|
||||
}
|
||||
}
|
||||
if let _ = previousItem as? BotCheckoutHeaderItem {
|
||||
|
|
@ -209,7 +209,7 @@ class BotCheckoutPriceItemNode: ListViewItemNode {
|
|||
strongSelf.separatorNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
strongSelf.separatorNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: params.width - leftInset, height: UIScreenPixel))
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners, glass: true) : nil
|
||||
|
||||
strongSelf.bottomSeparatorNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
strongSelf.bottomSeparatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: contentSize.height), size: CGSize(width: params.width, height: UIScreenPixel))
|
||||
|
|
|
|||
|
|
@ -70,15 +70,17 @@ final class BotPaymentActionItemNode: BotPaymentItemNode {
|
|||
self.titleNode.attributedText = NSAttributedString(string: self.title, font: titleFont, textColor: theme.list.itemAccentColor)
|
||||
}
|
||||
|
||||
self.buttonNode.frame = CGRect(origin: CGPoint(x: sideInset, y: 0.0), size: CGSize(width: width - sideInset * 2.0, height: 44.0))
|
||||
transition.updateFrame(node: self.highlightedBackgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: 44.0 + UIScreenPixel)))
|
||||
let height: CGFloat = 52.0
|
||||
|
||||
self.buttonNode.frame = CGRect(origin: CGPoint(x: sideInset, y: 0.0), size: CGSize(width: width - sideInset * 2.0, height: height))
|
||||
transition.updateFrame(node: self.highlightedBackgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: height + UIScreenPixel)))
|
||||
|
||||
let leftInset: CGFloat = 16.0
|
||||
|
||||
let titleSize = self.titleNode.measure(CGSize(width: width - leftInset - 32.0 - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude))
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset + sideInset, y: 11.0), size: titleSize))
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset + sideInset, y: 16.0), size: titleSize))
|
||||
|
||||
return 44.0
|
||||
return height
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@ final class BotPaymentCardInputItemNode: BotPaymentItemNode, STPPaymentCardTextF
|
|||
self.cardField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||
}
|
||||
|
||||
self.cardField.frame = CGRect(origin: CGPoint(x: 5.0 + sideInset, y: 0.0), size: CGSize(width: width - 10.0 - sideInset * 2.0, height: 44.0))
|
||||
self.cardField.frame = CGRect(origin: CGPoint(x: 5.0 + sideInset, y: 4.0), size: CGSize(width: width - 10.0 - sideInset * 2.0, height: 44.0))
|
||||
|
||||
return 44.0
|
||||
return 52.0
|
||||
}
|
||||
|
||||
func paymentCardTextFieldDidChange(_ textField: STPPaymentCardTextField) {
|
||||
|
|
|
|||
|
|
@ -102,13 +102,15 @@ class BotPaymentDisclosureItemNode: BotPaymentItemNode {
|
|||
}
|
||||
}
|
||||
|
||||
self.buttonNode.frame = CGRect(origin: CGPoint(x: sideInset, y: 0.0), size: CGSize(width: width - sideInset * 2.0, height: 44.0))
|
||||
transition.updateFrame(node: self.highlightedBackgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: 44.0 + UIScreenPixel)))
|
||||
let height: CGFloat = 52.0
|
||||
|
||||
self.buttonNode.frame = CGRect(origin: CGPoint(x: sideInset, y: 0.0), size: CGSize(width: width - sideInset * 2.0, height: height))
|
||||
transition.updateFrame(node: self.highlightedBackgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: height + UIScreenPixel)))
|
||||
|
||||
let leftInset: CGFloat = 16.0
|
||||
|
||||
let titleSize = self.titleNode.measure(CGSize(width: width - leftInset - 70.0 - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude))
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset + sideInset, y: 11.0), size: titleSize))
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset + sideInset, y: 16.0), size: titleSize))
|
||||
|
||||
var textInset = leftInset
|
||||
if !titleSize.width.isZero {
|
||||
|
|
@ -117,9 +119,9 @@ class BotPaymentDisclosureItemNode: BotPaymentItemNode {
|
|||
textInset = max(measuredInset, textInset)
|
||||
|
||||
let textSize = self.textNode.measure(CGSize(width: width - measuredInset - 8.0 - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude))
|
||||
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: textInset + sideInset, y: 11.0), size: textSize))
|
||||
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: textInset + sideInset, y: 16.0), size: textSize))
|
||||
|
||||
return 44.0
|
||||
return height
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
|
|
|
|||
|
|
@ -108,11 +108,12 @@ final class BotPaymentFieldItemNode: BotPaymentItemNode, UITextFieldDelegate {
|
|||
self.textField.textField.tintColor = theme.list.itemAccentColor
|
||||
}
|
||||
|
||||
let height: CGFloat = 52.0
|
||||
let leftInset: CGFloat = 16.0
|
||||
|
||||
let titleSize = self.titleNode.measure(CGSize(width: width - leftInset - 70.0 - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude))
|
||||
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset + sideInset, y: 11.0), size: titleSize))
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset + sideInset, y: 16.0), size: titleSize))
|
||||
|
||||
var textInset = leftInset
|
||||
if !titleSize.width.isZero {
|
||||
|
|
@ -121,9 +122,9 @@ final class BotPaymentFieldItemNode: BotPaymentItemNode, UITextFieldDelegate {
|
|||
|
||||
textInset = max(measuredInset, textInset)
|
||||
|
||||
transition.updateFrame(node: self.textField, frame: CGRect(origin: CGPoint(x: textInset + sideInset, y: 0.0), size: CGSize(width: max(1.0, width - textInset - 8.0), height: 40.0)))
|
||||
transition.updateFrame(node: self.textField, frame: CGRect(origin: CGPoint(x: textInset + sideInset, y: 5.0), size: CGSize(width: max(1.0, width - textInset - 8.0), height: 40.0)))
|
||||
|
||||
return 44.0
|
||||
return height
|
||||
}
|
||||
|
||||
func activateInput() {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class BotPaymentItemNode: ASDisplayNode {
|
|||
self.bottomSeparatorNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
self.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
self.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(theme, top: hasTopCorners, bottom: hasBottomCorners, glass: true) : nil
|
||||
|
||||
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: height)))
|
||||
transition.updateFrame(node: self.maskNode, frame: self.backgroundNode.frame.insetBy(dx: sideInset, dy: 0.0))
|
||||
|
|
|
|||
|
|
@ -74,14 +74,14 @@ final class BotPaymentSwitchItemNode: BotPaymentItemNode {
|
|||
|
||||
let titleSize = self.titleNode.measure(CGSize(width: width - leftInset - 70.0 - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude))
|
||||
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset + sideInset, y: 11.0), size: titleSize))
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset + sideInset, y: 16.0), size: titleSize))
|
||||
|
||||
let switchSize = self.switchNode.measure(CGSize(width: 100.0, height: 100.0))
|
||||
let switchFrame = CGRect(origin: CGPoint(x: width - switchSize.width - 15.0 - sideInset, y: 6.0), size: switchSize)
|
||||
let switchFrame = CGRect(origin: CGPoint(x: width - switchSize.width - 15.0 - sideInset, y: 12.0), size: switchSize)
|
||||
transition.updateFrame(node: self.switchNode, frame: switchFrame)
|
||||
transition.updateFrame(node: self.buttonNode, frame: switchFrame)
|
||||
|
||||
return 44.0
|
||||
return 52.0
|
||||
}
|
||||
|
||||
@objc private func buttonPressed() {
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ final class BotReceiptControllerNode: ItemListControllerNode {
|
|||
override func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition, additionalInsets: UIEdgeInsets) {
|
||||
var updatedInsets = layout.intrinsicInsets
|
||||
|
||||
let bottomPanelHorizontalInset: CGFloat = 16.0
|
||||
let bottomPanelHorizontalInset: CGFloat = 30.0
|
||||
let bottomPanelVerticalInset: CGFloat = 16.0
|
||||
let bottomPanelHeight = max(updatedInsets.bottom, layout.inputHeight ?? 0.0) + bottomPanelVerticalInset * 2.0 + BotCheckoutActionButton.height
|
||||
|
||||
|
|
|
|||
|
|
@ -1425,9 +1425,13 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||
var nodeList = document.getElementsByTagName('link');
|
||||
for (var i = 0; i < nodeList.length; i++)
|
||||
{
|
||||
if((nodeList[i].getAttribute('rel') == 'icon')||(nodeList[i].getAttribute('rel') == 'shortcut icon')||(nodeList[i].getAttribute('rel').startsWith('apple-touch-icon')))
|
||||
{
|
||||
const node = nodeList[i];
|
||||
var rel = nodeList[i].getAttribute('rel') || '';
|
||||
if (
|
||||
rel === 'icon' ||
|
||||
rel === 'shortcut icon' ||
|
||||
rel.indexOf('apple-touch-icon') === 0
|
||||
) {
|
||||
var node = nodeList[i];
|
||||
favicons.push({
|
||||
url: node.getAttribute('href'),
|
||||
sizes: node.getAttribute('sizes')
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
private let dismissAutoarchiveDisposable = MetaDisposable()
|
||||
private var didSuggestAutoarchive = false
|
||||
private var didSuggestLoginEmailSetup = false
|
||||
private var didSuggestLoginPasskeySetup = false
|
||||
|
||||
private var presentationData: PresentationData
|
||||
private let presentationDataValue = Promise<PresentationData>()
|
||||
|
|
@ -2586,6 +2587,30 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
return
|
||||
}
|
||||
|
||||
if values.contains(.setupPasskey) {
|
||||
if strongSelf.didSuggestLoginPasskeySetup {
|
||||
return
|
||||
}
|
||||
strongSelf.didSuggestLoginPasskeySetup = true
|
||||
|
||||
let _ = (context.engine.notices.getServerProvidedSuggestions(reload: true)
|
||||
|> deliverOnMainQueue).start(next: { [weak strongSelf] currentValues in
|
||||
guard let strongSelf, currentValues.contains(.setupPasskey) else {
|
||||
return
|
||||
}
|
||||
if let navigationController = strongSelf.navigationController as? NavigationController {
|
||||
let controller = strongSelf.context.sharedContext.makePasskeySetupController(context: strongSelf.context, displaySkip: true, navigationController: navigationController, completion: {
|
||||
let _ = context.engine.notices.dismissServerProvidedSuggestion(suggestion: ServerProvidedSuggestion.setupPasskey.id).startStandalone()
|
||||
}, dismiss: {
|
||||
let _ = context.engine.notices.dismissServerProvidedSuggestion(suggestion: ServerProvidedSuggestion.setupPasskey.id).startStandalone()
|
||||
})
|
||||
navigationController.pushViewController(controller)
|
||||
}
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if strongSelf.didSuggestAutoarchive {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,19 @@ private extension ComponentTransition.Animation.Curve {
|
|||
preconditionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
var viewAnimationOptions: UIView.AnimationOptions {
|
||||
switch self {
|
||||
case .linear:
|
||||
return [.curveLinear]
|
||||
case .easeInOut:
|
||||
return [.curveEaseInOut]
|
||||
case .spring:
|
||||
return UIView.AnimationOptions(rawValue: 7 << 16)
|
||||
case .custom:
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension ComponentTransition.Animation {
|
||||
|
|
@ -70,6 +83,24 @@ public extension ComponentTransition.Animation {
|
|||
}
|
||||
}
|
||||
|
||||
public extension ComponentTransition {
|
||||
func animateView(allowUserInteraction: Bool = false, delay: Double = 0.0, _ f: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) {
|
||||
switch self.animation {
|
||||
case .none:
|
||||
f()
|
||||
completion?(true)
|
||||
case let .curve(duration, curve):
|
||||
var options = curve.viewAnimationOptions
|
||||
if allowUserInteraction {
|
||||
options.insert(.allowUserInteraction)
|
||||
}
|
||||
UIView.animate(withDuration: duration, delay: delay, options: options, animations: {
|
||||
f()
|
||||
}, completion: completion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct ComponentTransition {
|
||||
public enum Animation {
|
||||
public enum Curve {
|
||||
|
|
|
|||
|
|
@ -157,40 +157,6 @@ public final class SheetComponent<ChildEnvironmentType: Sendable & Equatable>: C
|
|||
}
|
||||
}
|
||||
|
||||
final class BackgroundView: UIView {
|
||||
let topCornersView = UIView()
|
||||
let bottomCornersView = UIView()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.topCornersView.clipsToBounds = true
|
||||
self.topCornersView.layer.cornerCurve = .continuous
|
||||
self.topCornersView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||||
|
||||
self.bottomCornersView.clipsToBounds = true
|
||||
self.bottomCornersView.layer.cornerCurve = .continuous
|
||||
self.bottomCornersView.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
|
||||
|
||||
self.addSubview(self.topCornersView)
|
||||
self.topCornersView.addSubview(self.bottomCornersView)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
func update(size: CGSize, color: UIColor, topCornerRadius: CGFloat, bottomCornerRadius: CGFloat, transition: ComponentTransition) {
|
||||
transition.setCornerRadius(layer: self.topCornersView.layer, cornerRadius: topCornerRadius)
|
||||
transition.setCornerRadius(layer: self.bottomCornersView.layer, cornerRadius: bottomCornerRadius)
|
||||
|
||||
transition.setFrame(view: self.topCornersView, frame: CGRect(origin: .zero, size: size))
|
||||
transition.setFrame(view: self.bottomCornersView, frame: CGRect(origin: .zero, size: size))
|
||||
|
||||
transition.setBackgroundColor(view: self.bottomCornersView, color: color)
|
||||
}
|
||||
}
|
||||
|
||||
public final class View: UIView, UIScrollViewDelegate, ComponentTaggedView {
|
||||
public final class Tag {
|
||||
public init() {
|
||||
|
|
@ -208,9 +174,9 @@ public final class SheetComponent<ChildEnvironmentType: Sendable & Equatable>: C
|
|||
|
||||
private let dimView: UIView
|
||||
private let scrollView: ScrollView
|
||||
private let backgroundView: BackgroundView
|
||||
private let backgroundView: SheetBackgroundView
|
||||
private var effectView: UIVisualEffectView?
|
||||
private let clipView: BackgroundView
|
||||
private let clipView: SheetBackgroundView
|
||||
private let contentView: ComponentView<ChildEnvironmentType>
|
||||
private var headerView: ComponentView<Empty>?
|
||||
|
||||
|
|
@ -233,8 +199,8 @@ public final class SheetComponent<ChildEnvironmentType: Sendable & Equatable>: C
|
|||
self.scrollView.showsHorizontalScrollIndicator = false
|
||||
self.scrollView.alwaysBounceVertical = true
|
||||
|
||||
self.backgroundView = BackgroundView()
|
||||
self.clipView = BackgroundView()
|
||||
self.backgroundView = SheetBackgroundView()
|
||||
self.clipView = SheetBackgroundView()
|
||||
|
||||
self.contentView = ComponentView<ChildEnvironmentType>()
|
||||
|
||||
|
|
@ -589,3 +555,37 @@ public final class SheetComponent<ChildEnvironmentType: Sendable & Equatable>: C
|
|||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
public final class SheetBackgroundView: UIView {
|
||||
let topCornersView = UIView()
|
||||
let bottomCornersView = UIView()
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.topCornersView.clipsToBounds = true
|
||||
self.topCornersView.layer.cornerCurve = .continuous
|
||||
self.topCornersView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||||
|
||||
self.bottomCornersView.clipsToBounds = true
|
||||
self.bottomCornersView.layer.cornerCurve = .continuous
|
||||
self.bottomCornersView.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
|
||||
|
||||
self.addSubview(self.topCornersView)
|
||||
self.topCornersView.addSubview(self.bottomCornersView)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
public func update(size: CGSize, color: UIColor, topCornerRadius: CGFloat, bottomCornerRadius: CGFloat, transition: ComponentTransition) {
|
||||
transition.setCornerRadius(layer: self.topCornersView.layer, cornerRadius: topCornerRadius)
|
||||
transition.setCornerRadius(layer: self.bottomCornersView.layer, cornerRadius: bottomCornerRadius)
|
||||
|
||||
transition.setFrame(view: self.topCornersView, frame: CGRect(origin: .zero, size: size))
|
||||
transition.setFrame(view: self.bottomCornersView, frame: CGRect(origin: .zero, size: size))
|
||||
|
||||
transition.setBackgroundColor(view: self.bottomCornersView, color: color)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ class GeneralChartComponentController: ChartThemeContainer {
|
|||
values.append(ChartDetailsViewModel.Value(
|
||||
prefix: nil,
|
||||
title: self.strings.revenueInUsd,
|
||||
value: "≈$\(convertedValueString)",
|
||||
value: "~$\(convertedValueString)",
|
||||
color: color,
|
||||
visible: firstValue.visible
|
||||
))
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
} else {
|
||||
text = String(format: "%0.3f", convertedValue)
|
||||
}
|
||||
updatedLabels.append(LinesChartLabel(value: label.value, text: "≈$\(text)"))
|
||||
updatedLabels.append(LinesChartLabel(value: label.value, text: "~$\(text)"))
|
||||
}
|
||||
labels = updatedLabels
|
||||
}
|
||||
|
|
|
|||
|
|
@ -494,7 +494,7 @@ private func inviteLinkEditControllerEntries(invite: ExportedInvitation?, state:
|
|||
var label: String = ""
|
||||
if let subscriptionFee = state.subscriptionFee, subscriptionFee > StarsAmount.zero {
|
||||
let usdRate = Double(configuration.usdWithdrawRate) / 1000.0 / 100.0
|
||||
label = presentationData.strings.InviteLink_Create_FeePerMonth("≈\(formatTonUsdValue(subscriptionFee.value, divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat))").string
|
||||
label = presentationData.strings.InviteLink_Create_FeePerMonth("~\(formatTonUsdValue(subscriptionFee.value, divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat))").string
|
||||
}
|
||||
entries.append(.subscriptionFee(presentationData.theme, presentationData.strings.InviteLink_Create_FeePlaceholder, isEditingEnabled, state.subscriptionFee, label, StarsAmount(value: configuration.maxFee, nanos: 0)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public final class ListMessageItemInteraction {
|
|||
})
|
||||
}
|
||||
|
||||
public final class ListMessageItem: ListViewItem {
|
||||
public final class ListMessageItem: ListViewItem, ItemListItem {
|
||||
let presentationData: ChatPresentationData
|
||||
let systemStyle: ItemListSystemStyle
|
||||
let context: AccountContext
|
||||
|
|
@ -57,6 +57,7 @@ public final class ListMessageItem: ListViewItem {
|
|||
let isGlobalSearchResult: Bool
|
||||
let isDownloadList: Bool
|
||||
let isSavedMusic: Bool
|
||||
let isStoryMusic: Bool
|
||||
let displayFileInfo: Bool
|
||||
let displayBackground: Bool
|
||||
let canReorder: Bool
|
||||
|
|
@ -64,9 +65,11 @@ public final class ListMessageItem: ListViewItem {
|
|||
|
||||
let header: ListViewItemHeader?
|
||||
|
||||
public var sectionId: ItemListSectionId
|
||||
|
||||
public let selectable: Bool = true
|
||||
|
||||
public init(presentationData: ChatPresentationData, systemStyle: ItemListSystemStyle = .legacy, context: AccountContext, chatLocation: ChatLocation, interaction: ListMessageItemInteraction, message: Message?, translateToLanguage: String? = nil, selection: ChatHistoryMessageSelection, displayHeader: Bool, customHeader: ListViewItemHeader? = nil, hintIsLink: Bool = false, isGlobalSearchResult: Bool = false, isDownloadList: Bool = false, isSavedMusic: Bool = false, displayFileInfo: Bool = true, displayBackground: Bool = false, canReorder: Bool = false, style: ItemListStyle = .plain) {
|
||||
public init(presentationData: ChatPresentationData, systemStyle: ItemListSystemStyle = .legacy, context: AccountContext, chatLocation: ChatLocation, interaction: ListMessageItemInteraction, message: Message?, translateToLanguage: String? = nil, selection: ChatHistoryMessageSelection, displayHeader: Bool, customHeader: ListViewItemHeader? = nil, hintIsLink: Bool = false, isGlobalSearchResult: Bool = false, isDownloadList: Bool = false, isSavedMusic: Bool = false, isStoryMusic: Bool = false, displayFileInfo: Bool = true, displayBackground: Bool = false, canReorder: Bool = false, style: ItemListStyle = .plain, sectionId: ItemListSectionId = 0) {
|
||||
self.presentationData = presentationData
|
||||
self.systemStyle = systemStyle
|
||||
self.context = context
|
||||
|
|
@ -86,10 +89,12 @@ public final class ListMessageItem: ListViewItem {
|
|||
self.isGlobalSearchResult = isGlobalSearchResult
|
||||
self.isDownloadList = isDownloadList
|
||||
self.isSavedMusic = isSavedMusic
|
||||
self.isStoryMusic = isStoryMusic
|
||||
self.displayFileInfo = displayFileInfo
|
||||
self.displayBackground = displayBackground
|
||||
self.canReorder = canReorder
|
||||
self.style = style
|
||||
self.sectionId = sectionId
|
||||
}
|
||||
|
||||
public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||
|
|
@ -120,7 +125,23 @@ public final class ListMessageItem: ListViewItem {
|
|||
node.setupItem(self)
|
||||
|
||||
let nodeLayout = node.asyncLayout()
|
||||
let (top, bottom, dateAtBottom) = (previousItem != nil && !(previousItem is ItemListItem), nextItem != nil, self.getDateAtBottom(top: previousItem, bottom: nextItem))
|
||||
|
||||
var topMerged = false
|
||||
if let previousItem {
|
||||
if let previousItem = previousItem as? ItemListItem, previousItem.sectionId == self.sectionId && !previousItem.isAlwaysPlain {
|
||||
topMerged = true
|
||||
}
|
||||
}
|
||||
|
||||
var bottomMerged = false
|
||||
if let nextItem {
|
||||
if let nextItem = nextItem as? ItemListItem, nextItem.sectionId == self.sectionId && !nextItem.isAlwaysPlain {
|
||||
bottomMerged = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let (top, bottom, dateAtBottom) = (topMerged, bottomMerged, self.getDateAtBottom(top: previousItem, bottom: nextItem))
|
||||
let (layout, apply) = nodeLayout(self, params, top, bottom, dateAtBottom)
|
||||
|
||||
node.updateSelectionState(animated: false)
|
||||
|
|
@ -152,9 +173,22 @@ public final class ListMessageItem: ListViewItem {
|
|||
|
||||
let nodeLayout = nodeValue.asyncLayout()
|
||||
|
||||
var topMerged = false
|
||||
if let previousItem {
|
||||
if let previousItem = previousItem as? ItemListItem, previousItem.sectionId == self.sectionId && !previousItem.isAlwaysPlain {
|
||||
topMerged = true
|
||||
}
|
||||
}
|
||||
|
||||
var bottomMerged = false
|
||||
if let nextItem {
|
||||
if let nextItem = nextItem as? ItemListItem, nextItem.sectionId == self.sectionId && !nextItem.isAlwaysPlain {
|
||||
bottomMerged = true
|
||||
}
|
||||
}
|
||||
|
||||
async {
|
||||
let (top, bottom, dateAtBottom) = (previousItem != nil && !(previousItem is ItemListItem), nextItem != nil, self.getDateAtBottom(top: previousItem, bottom: nextItem))
|
||||
|
||||
let (top, bottom, dateAtBottom) = (topMerged, bottomMerged, self.getDateAtBottom(top: previousItem, bottom: nextItem))
|
||||
let (layout, apply) = nodeLayout(self, params, top, bottom, dateAtBottom)
|
||||
Queue.mainQueue().async {
|
||||
completion(layout, { _ in
|
||||
|
|
|
|||
|
|
@ -446,9 +446,9 @@ public func storyLocationPickerController(
|
|||
) -> ViewController {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkColorPresentationTheme)
|
||||
let updatedPresentationData: (PresentationData, Signal<PresentationData, NoError>) = (presentationData, .single(presentationData))
|
||||
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: nil, buttons: [.standalone], initialButton: .standalone, fromMenu: false, hasTextInput: false)
|
||||
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, style: .glass, chatLocation: nil, buttons: [.standalone], initialButton: .standalone, fromMenu: false, hasTextInput: false)
|
||||
controller.requestController = { _, present in
|
||||
let locationPickerController = LocationPickerController(context: context, updatedPresentationData: updatedPresentationData, mode: .share(peer: nil, selfPeer: nil, hasLiveLocation: false), source: .story, initialLocation: location, completion: { location, queryId, resultId, address, countryCode in
|
||||
let locationPickerController = LocationPickerController(context: context, style: .glass, updatedPresentationData: updatedPresentationData, mode: .share(peer: nil, selfPeer: nil, hasLiveLocation: false), source: .story, initialLocation: location, completion: { location, queryId, resultId, address, countryCode in
|
||||
completion(location, queryId, resultId, address, countryCode)
|
||||
})
|
||||
present(locationPickerController, locationPickerController.mediaPickerContext)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public func mediaPasteboardScreen(
|
|||
getSourceRect: (() -> CGRect?)? = nil,
|
||||
makeEntityInputView: @escaping () -> AttachmentTextInputPanelInputView? = { return nil }
|
||||
) -> ViewController {
|
||||
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: .peer(id: peer.id), buttons: [.standalone], initialButton: .standalone, makeEntityInputView: makeEntityInputView)
|
||||
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, style: .glass, chatLocation: .peer(id: peer.id), buttons: [.standalone], initialButton: .standalone, makeEntityInputView: makeEntityInputView)
|
||||
controller.requestController = { _, present in
|
||||
presentMediaPicker(.media(subjects), false, nil, nil, { mediaPicker, mediaPickerContext in
|
||||
present(mediaPicker, mediaPickerContext)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ swift_library(
|
|||
"//submodules/Components/ActivityIndicatorComponent",
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBarButtonComponent",
|
||||
"//submodules/TelegramUI/Components/ListSectionComponent",
|
||||
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
||||
"//submodules/TelegramUI/Components/PlainButtonComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ import BundleIconComponent
|
|||
import AnimatedStickerComponent
|
||||
import ActivityIndicatorComponent
|
||||
import GlassBarButtonComponent
|
||||
import ListSectionComponent
|
||||
import ListActionItemComponent
|
||||
import PlainButtonComponent
|
||||
|
||||
private final class CreateExternalMediaStreamScreenComponent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
|
@ -49,41 +52,51 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
final class State: ComponentState {
|
||||
let context: AccountContext
|
||||
let peerId: EnginePeer.Id
|
||||
let mode: CreateExternalMediaStreamScreen.Mode
|
||||
|
||||
private(set) var credentials: GroupCallStreamCredentials?
|
||||
var isDelayingLoadingIndication: Bool = true
|
||||
|
||||
private var credentialsDisposable: Disposable?
|
||||
private let credentialsDisposable = MetaDisposable()
|
||||
private let activeActionDisposable = MetaDisposable()
|
||||
|
||||
init(context: AccountContext, peerId: EnginePeer.Id, credentialsPromise: Promise<GroupCallStreamCredentials>?) {
|
||||
init(context: AccountContext, peerId: EnginePeer.Id, mode: CreateExternalMediaStreamScreen.Mode, credentialsPromise: Promise<GroupCallStreamCredentials>?) {
|
||||
self.context = context
|
||||
self.peerId = peerId
|
||||
self.mode = mode
|
||||
|
||||
super.init()
|
||||
|
||||
self.getCredentials(credentialsPromise: credentialsPromise)
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.credentialsDisposable.dispose()
|
||||
self.activeActionDisposable.dispose()
|
||||
}
|
||||
|
||||
func getCredentials(credentialsPromise: Promise<GroupCallStreamCredentials>? = nil, revoke: Bool = false) {
|
||||
let credentialsSignal: Signal<GroupCallStreamCredentials, NoError>
|
||||
if let credentialsPromise = credentialsPromise {
|
||||
credentialsSignal = credentialsPromise.get()
|
||||
} else {
|
||||
credentialsSignal = context.engine.calls.getGroupCallStreamCredentials(peerId: peerId, isLiveStream: false, revokePreviousCredentials: false)
|
||||
var isLiveStream = false
|
||||
if case let .create(isLiveStreamValue) = self.mode {
|
||||
isLiveStream = isLiveStreamValue
|
||||
}
|
||||
credentialsSignal = self.context.engine.calls.getGroupCallStreamCredentials(peerId: self.peerId, isLiveStream: isLiveStream, revokePreviousCredentials: revoke)
|
||||
|> `catch` { _ -> Signal<GroupCallStreamCredentials, NoError> in
|
||||
return .never()
|
||||
}
|
||||
}
|
||||
self.credentialsDisposable = (credentialsSignal |> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
self.credentialsDisposable.set((credentialsSignal |> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
strongSelf.credentials = result
|
||||
strongSelf.updated(transition: .immediate)
|
||||
})
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.credentialsDisposable?.dispose()
|
||||
self.activeActionDisposable.dispose()
|
||||
}))
|
||||
}
|
||||
|
||||
func copyCredentials(_ key: KeyPath<GroupCallStreamCredentials, String>) {
|
||||
|
|
@ -160,7 +173,7 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
}
|
||||
|
||||
func makeState() -> State {
|
||||
return State(context: self.context, peerId: self.peerId, credentialsPromise: self.credentialsPromise)
|
||||
return State(context: self.context, peerId: self.peerId, mode: self.mode, credentialsPromise: self.credentialsPromise)
|
||||
}
|
||||
|
||||
static var body: Body {
|
||||
|
|
@ -176,26 +189,25 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
|
||||
let activityIndicator = Child(ActivityIndicatorComponent.self)
|
||||
|
||||
let credentialsBackground = Child(RoundedRectangle.self)
|
||||
let credentialsSection = Child(ListSectionComponent.self)
|
||||
|
||||
let credentialsStripe = Child(Rectangle.self)
|
||||
let credentialsURLTitle = Child(MultilineTextComponent.self)
|
||||
let credentialsURLText = Child(MultilineTextComponent.self)
|
||||
|
||||
let credentialsKeyTitle = Child(MultilineTextComponent.self)
|
||||
let credentialsKeyText = Child(MultilineTextComponent.self)
|
||||
|
||||
let credentialsCopyURLButton = Child(Button.self)
|
||||
let credentialsCopyKeyButton = Child(Button.self)
|
||||
// let credentialsBackground = Child(RoundedRectangle.self)
|
||||
// let credentialsStripe = Child(Rectangle.self)
|
||||
// let credentialsURLTitle = Child(MultilineTextComponent.self)
|
||||
// let credentialsURLText = Child(MultilineTextComponent.self)
|
||||
//
|
||||
// let credentialsKeyTitle = Child(MultilineTextComponent.self)
|
||||
// let credentialsKeyText = Child(MultilineTextComponent.self)
|
||||
//
|
||||
// let credentialsCopyURLButton = Child(Button.self)
|
||||
// let credentialsCopyKeyButton = Child(Button.self)
|
||||
|
||||
return { context in
|
||||
let topInset: CGFloat = 16.0
|
||||
let sideInset: CGFloat = 16.0
|
||||
let buttonSideInset: CGFloat = 36.0
|
||||
let credentialsSideInset: CGFloat = 16.0
|
||||
let credentialsTopInset: CGFloat = 12.0
|
||||
let credentialsTitleSpacing: CGFloat = 5.0
|
||||
|
||||
let component = context.component
|
||||
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
|
||||
let state = context.state
|
||||
|
||||
|
|
@ -355,124 +367,145 @@ private final class CreateExternalMediaStreamScreenComponent: CombinedComponent
|
|||
)
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: floor((context.availableSize.width - text.size.width) / 2.0), y: animationFrame.maxY + 18.0), size: text.size)
|
||||
|
||||
context.add(text
|
||||
.position(CGPoint(x: textFrame.midX, y: textFrame.midY))
|
||||
)
|
||||
|
||||
let credentialsFrame = CGRect(origin: CGPoint(x: sideInset, y: textFrame.maxY + 30.0), size: credentialsAreaSize)
|
||||
|
||||
if let credentials = context.state.credentials {
|
||||
let credentialsURLTitle = credentialsURLTitle.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_ServerUrl, font: Font.regular(15.0), textColor: theme.list.itemPrimaryTextColor, paragraphAlignment: .left)),
|
||||
horizontalAlignment: .left,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
availableSize: CGSize(width: credentialsAreaSize.width - credentialsSideInset * 2.0, height: credentialsAreaSize.height),
|
||||
transition: context.transition
|
||||
var credentialsSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
credentialsSectionItems.append(
|
||||
AnyComponentWithIdentity(id: "url", component: AnyComponent(
|
||||
ListActionItemComponent(
|
||||
theme: theme,
|
||||
style: .glass,
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: environment.strings.CreateExternalStream_ServerUrl,
|
||||
font: Font.regular(15.0),
|
||||
textColor: theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
maximumNumberOfLines: 1
|
||||
))),
|
||||
AnyComponentWithIdentity(id: AnyHashable(1), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: credentials.url, font: Font.regular(17.0), textColor: theme.list.itemAccentColor, paragraphAlignment: .left)),
|
||||
horizontalAlignment: .left,
|
||||
truncationType: .middle,
|
||||
maximumNumberOfLines: 1
|
||||
)))
|
||||
], alignment: .left, spacing: 5.0)),
|
||||
contentInsets: UIEdgeInsets(top: 14.0, left: 0.0, bottom: 14.0, right: 0.0),
|
||||
accessory: .custom(ListActionItemComponent.CustomAccessory(
|
||||
component: AnyComponentWithIdentity(
|
||||
id: "copy",
|
||||
component: AnyComponent(
|
||||
PlainButtonComponent(
|
||||
content: AnyComponent(BundleIconComponent(name: "Chat/Context Menu/Copy", tintColor: theme.list.itemAccentColor)),
|
||||
action: { [weak state] in
|
||||
guard let state = state else {
|
||||
return
|
||||
}
|
||||
state.copyCredentials(\.url)
|
||||
},
|
||||
animateScale: false
|
||||
)
|
||||
)
|
||||
),
|
||||
insets: UIEdgeInsets(top: 0.0, left: 8.0, bottom: 0.0, right: 14.0),
|
||||
isInteractive: true
|
||||
)),
|
||||
action: nil
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
let credentialsKeyTitle = credentialsKeyTitle.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_StreamKey, font: Font.regular(15.0), textColor: theme.list.itemPrimaryTextColor, paragraphAlignment: .left)),
|
||||
horizontalAlignment: .left,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
availableSize: CGSize(width: credentialsAreaSize.width - credentialsSideInset * 2.0, height: credentialsAreaSize.height),
|
||||
transition: context.transition
|
||||
credentialsSectionItems.append(
|
||||
AnyComponentWithIdentity(id: "key", component: AnyComponent(
|
||||
ListActionItemComponent(
|
||||
theme: theme,
|
||||
style: .glass,
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: environment.strings.CreateExternalStream_StreamKey,
|
||||
font: Font.regular(15.0),
|
||||
textColor: theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
maximumNumberOfLines: 1
|
||||
))),
|
||||
AnyComponentWithIdentity(id: AnyHashable(1), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: credentials.streamKey, font: Font.regular(17.0), textColor: theme.list.itemAccentColor, paragraphAlignment: .left)),
|
||||
horizontalAlignment: .left,
|
||||
truncationType: .middle,
|
||||
maximumNumberOfLines: 1
|
||||
)))
|
||||
], alignment: .left, spacing: 5.0)),
|
||||
contentInsets: UIEdgeInsets(top: 14.0, left: 0.0, bottom: 14.0, right: 0.0),
|
||||
accessory: .custom(ListActionItemComponent.CustomAccessory(
|
||||
component: AnyComponentWithIdentity(
|
||||
id: "copy",
|
||||
component: AnyComponent(
|
||||
PlainButtonComponent(
|
||||
content: AnyComponent(BundleIconComponent(name: "Chat/Context Menu/Copy", tintColor: theme.list.itemAccentColor)),
|
||||
action: { [weak state] in
|
||||
guard let state = state else {
|
||||
return
|
||||
}
|
||||
state.copyCredentials(\.streamKey)
|
||||
},
|
||||
animateScale: false
|
||||
)
|
||||
)
|
||||
),
|
||||
insets: UIEdgeInsets(top: 0.0, left: 8.0, bottom: 0.0, right: 14.0),
|
||||
isInteractive: true
|
||||
)),
|
||||
action: nil
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
let credentialsURLText = credentialsURLText.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: credentials.url, font: Font.regular(17.0), textColor: theme.list.itemAccentColor, paragraphAlignment: .left)),
|
||||
horizontalAlignment: .left,
|
||||
truncationType: .middle,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
availableSize: CGSize(width: credentialsAreaSize.width - credentialsSideInset * 2.0 - 22.0, height: credentialsAreaSize.height),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let credentialsKeyText = credentialsKeyText.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: credentials.streamKey, font: Font.regular(17.0), textColor: theme.list.itemAccentColor, paragraphAlignment: .left)),
|
||||
horizontalAlignment: .left,
|
||||
truncationType: .middle,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
availableSize: CGSize(width: credentialsAreaSize.width - credentialsSideInset * 2.0 - 48.0, height: credentialsAreaSize.height),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let credentialsBackground = credentialsBackground.update(
|
||||
component: RoundedRectangle(color: theme.list.itemBlocksBackgroundColor, cornerRadius: 26.0),
|
||||
availableSize: credentialsAreaSize,
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let credentialsStripe = credentialsStripe.update(
|
||||
component: Rectangle(color: theme.list.itemPlainSeparatorColor),
|
||||
availableSize: CGSize(width: credentialsAreaSize.width - credentialsSideInset * 2.0, height: UIScreenPixel),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let credentialsCopyURLButton = credentialsCopyURLButton.update(
|
||||
component: Button(
|
||||
content: AnyComponent(BundleIconComponent(name: "Chat/Context Menu/Copy", tintColor: theme.list.itemAccentColor)),
|
||||
action: { [weak state] in
|
||||
guard let state = state else {
|
||||
return
|
||||
credentialsSectionItems.append(
|
||||
AnyComponentWithIdentity(id: "revoke", component: AnyComponent(
|
||||
ListActionItemComponent(
|
||||
theme: theme,
|
||||
style: .glass,
|
||||
title: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: environment.strings.CreateExternalStream_RevokeStreamKey, font: Font.regular(17.0), textColor: theme.list.itemDestructiveColor)),
|
||||
horizontalAlignment: .center,
|
||||
truncationType: .middle,
|
||||
maximumNumberOfLines: 1
|
||||
)),
|
||||
titleAlignment: .center,
|
||||
action: { [weak state] _ in
|
||||
guard let state = state else {
|
||||
return
|
||||
}
|
||||
let alertController = textAlertController(context: component.context, title: nil, text: environment.strings.CreateExternalStream_Revoke_Text, actions: [TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {
|
||||
}), TextAlertAction(type: .defaultAction, title: environment.strings.CreateExternalStream_Revoke_Revoke, action: { [weak state] in
|
||||
state?.getCredentials(revoke: true)
|
||||
})])
|
||||
environment.controller()?.present(alertController, in: .window(.root))
|
||||
}
|
||||
state.copyCredentials(\.url)
|
||||
}
|
||||
).minSize(CGSize(width: 44.0, height: 44.0)),
|
||||
availableSize: CGSize(width: 44.0, height: 44.0),
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
let credentialsSection = credentialsSection.update(
|
||||
component: ListSectionComponent(
|
||||
theme: theme,
|
||||
style: .glass,
|
||||
header: nil,
|
||||
footer: nil,
|
||||
items: credentialsSectionItems
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: context.availableSize.height),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
let credentialsCopyKeyButton = credentialsCopyKeyButton.update(
|
||||
component: Button(
|
||||
content: AnyComponent(BundleIconComponent(name: "Chat/Context Menu/Copy", tintColor: theme.list.itemAccentColor)),
|
||||
action: { [weak state] in
|
||||
guard let state = state else {
|
||||
return
|
||||
}
|
||||
state.copyCredentials(\.streamKey)
|
||||
}
|
||||
).minSize(CGSize(width: 44.0, height: 44.0)),
|
||||
availableSize: CGSize(width: 44.0, height: 44.0),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
context.add(credentialsBackground
|
||||
.position(CGPoint(x: credentialsFrame.midX, y: credentialsFrame.midY))
|
||||
)
|
||||
|
||||
context.add(credentialsStripe
|
||||
.position(CGPoint(x: credentialsFrame.minX + credentialsSideInset + credentialsStripe.size.width / 2.0, y: credentialsFrame.minY + credentialsItemHeight))
|
||||
)
|
||||
|
||||
context.add(credentialsURLTitle
|
||||
.position(CGPoint(x: credentialsFrame.minX + credentialsSideInset + credentialsURLTitle.size.width / 2.0, y: credentialsFrame.minY + credentialsTopInset + credentialsURLTitle.size.height / 2.0))
|
||||
)
|
||||
context.add(credentialsURLText
|
||||
.position(CGPoint(x: credentialsFrame.minX + credentialsSideInset + credentialsURLText.size.width / 2.0, y: credentialsFrame.minY + credentialsTopInset + credentialsTitleSpacing + credentialsURLTitle.size.height + credentialsURLText.size.height / 2.0))
|
||||
)
|
||||
context.add(credentialsCopyURLButton
|
||||
.position(CGPoint(x: credentialsFrame.maxX - 4.0 - credentialsCopyURLButton.size.width / 2.0, y: credentialsFrame.minY + credentialsItemHeight / 2.0))
|
||||
)
|
||||
|
||||
context.add(credentialsKeyTitle
|
||||
.position(CGPoint(x: credentialsFrame.minX + credentialsSideInset + credentialsKeyTitle.size.width / 2.0, y: credentialsFrame.minY + credentialsItemHeight + credentialsTopInset + credentialsKeyTitle.size.height / 2.0))
|
||||
)
|
||||
context.add(credentialsKeyText
|
||||
.position(CGPoint(x: credentialsFrame.minX + credentialsSideInset + credentialsKeyText.size.width / 2.0, y: credentialsFrame.minY + credentialsItemHeight + credentialsTopInset + credentialsTitleSpacing + credentialsKeyTitle.size.height + credentialsKeyText.size.height / 2.0))
|
||||
)
|
||||
context.add(credentialsCopyKeyButton
|
||||
.position(CGPoint(x: credentialsFrame.maxX - 4.0 - credentialsCopyKeyButton.size.width / 2.0, y: credentialsFrame.minY + credentialsItemHeight + credentialsItemHeight / 2.0))
|
||||
)
|
||||
context.add(credentialsSection
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: textFrame.maxY + 30.0 + credentialsSection.size.height / 2.0)))
|
||||
} else if !context.state.isDelayingLoadingIndication {
|
||||
let credentialsFrame = CGRect(origin: CGPoint(x: sideInset, y: textFrame.maxY + 30.0), size: credentialsAreaSize)
|
||||
let activityIndicator = activityIndicator.update(
|
||||
component: ActivityIndicatorComponent(color: theme.list.controlSecondaryColor),
|
||||
availableSize: CGSize(width: 100.0, height: 100.0),
|
||||
|
|
|
|||
|
|
@ -548,34 +548,6 @@ private func stringForRight(strings: PresentationStrings, right: TelegramChatAdm
|
|||
}
|
||||
}
|
||||
|
||||
private func rightDependencies(_ right: TelegramChatAdminRightsFlags) -> [TelegramChatAdminRightsFlags] {
|
||||
if right.contains(.canChangeInfo) {
|
||||
return []
|
||||
} else if right.contains(.canPostMessages) {
|
||||
return []
|
||||
} else if right.contains(.canEditMessages) {
|
||||
return []
|
||||
} else if right.contains(.canDeleteMessages) {
|
||||
return []
|
||||
} else if right.contains(.canBanUsers) {
|
||||
return []
|
||||
} else if right.contains(.canInviteUsers) {
|
||||
return []
|
||||
} else if right.contains(.canPinMessages) {
|
||||
return []
|
||||
} else if right.contains(.canAddAdmins) {
|
||||
return []
|
||||
} else if right.contains(.canManageDirect) {
|
||||
return []
|
||||
} else if right.contains(.canManageCalls) {
|
||||
return []
|
||||
} else if right.contains(.canBeAnonymous) {
|
||||
return []
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
private func canEditAdminRights(accountPeerId: EnginePeer.Id, channelPeer: EnginePeer, initialParticipant: ChannelParticipant?) -> Bool {
|
||||
if case let .channel(channel) = channelPeer {
|
||||
if channel.flags.contains(.isCreator) {
|
||||
|
|
@ -658,6 +630,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
|
|||
.direct(.canChangeInfo),
|
||||
.sub(.messages, messageRelatedFlags),
|
||||
.sub(.stories, storiesRelatedFlags),
|
||||
.direct(.canBanUsers),
|
||||
.direct(.canInviteUsers),
|
||||
.direct(.canManageDirect),
|
||||
.direct(.canManageCalls),
|
||||
|
|
|
|||
|
|
@ -732,7 +732,7 @@ private func channelPermissionsControllerEntries(context: AccountContext, presen
|
|||
var price: String = ""
|
||||
let usdRate = Double(configuration.usdWithdrawRate) / 1000.0 / 100.0
|
||||
|
||||
price = "≈\(formatTonUsdValue(sendPaidMessageStars, divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat))"
|
||||
price = "~\(formatTonUsdValue(sendPaidMessageStars, divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat))"
|
||||
|
||||
entries.append(.messagePriceHeader(presentationData.theme, presentationData.strings.GroupInfo_Permissions_MessagePrice))
|
||||
entries.append(.messagePrice(presentationData.theme, sendPaidMessageStars, configuration.paidMessageMaxAmount, price))
|
||||
|
|
|
|||
|
|
@ -354,15 +354,15 @@ protocol PhoneDemoDecorationView: UIView {
|
|||
func resetAnimation()
|
||||
}
|
||||
|
||||
final class PhoneDemoComponent: Component {
|
||||
typealias EnvironmentType = DemoPageEnvironment
|
||||
public final class PhoneDemoComponent: Component {
|
||||
public typealias EnvironmentType = DemoPageEnvironment
|
||||
|
||||
enum Position {
|
||||
public enum Position {
|
||||
case top
|
||||
case bottom
|
||||
}
|
||||
|
||||
enum BackgroundDecoration {
|
||||
public enum BackgroundDecoration {
|
||||
case none
|
||||
case dataRain
|
||||
case swirlStars
|
||||
|
|
@ -375,7 +375,7 @@ final class PhoneDemoComponent: Component {
|
|||
case todo
|
||||
}
|
||||
|
||||
enum Model {
|
||||
public enum Model {
|
||||
case notch
|
||||
case island
|
||||
}
|
||||
|
|
@ -419,11 +419,11 @@ final class PhoneDemoComponent: Component {
|
|||
return true
|
||||
}
|
||||
|
||||
final class View: UIView, ComponentTaggedView {
|
||||
final class Tag {
|
||||
public final class View: UIView, ComponentTaggedView {
|
||||
public final class Tag {
|
||||
}
|
||||
|
||||
func matches(tag: Any) -> Bool {
|
||||
public func matches(tag: Any) -> Bool {
|
||||
if let _ = tag as? Tag, self.isCentral {
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ public final class PremiumGradientBackgroundComponent: Component {
|
|||
}
|
||||
}
|
||||
|
||||
final class DemoPageEnvironment: Equatable {
|
||||
public final class DemoPageEnvironment: Equatable {
|
||||
public let isDisplaying: Bool
|
||||
public let isCentral: Bool
|
||||
public let position: CGFloat
|
||||
|
|
@ -1134,13 +1134,13 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
let closeButton = closeButton.update(
|
||||
component: GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: theme.rootController.navigationBar.glassBarButtonBackgroundColor,
|
||||
isDark: theme.overallDarkAppearance,
|
||||
state: .glass,
|
||||
backgroundColor: UIColor(rgb: 0x7f76f4),
|
||||
isDark: false,
|
||||
state: .tintedGlass,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Navigation/Close",
|
||||
tintColor: theme.rootController.navigationBar.glassBarButtonForegroundColor
|
||||
tintColor: .white
|
||||
)
|
||||
)),
|
||||
action: { _ in
|
||||
|
|
|
|||
|
|
@ -2049,7 +2049,8 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||
}
|
||||
subtitle = "\(environment.strings.Gift_Options_Premium_Months(product.months)) • \(product.price)"
|
||||
} else {
|
||||
subtitle = product.price
|
||||
//subtitle = product.price
|
||||
subtitle = "\(environment.strings.Gift_Options_Premium_Months(product.months)) • \(product.price)"
|
||||
}
|
||||
}
|
||||
if product.isCurrent {
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/Settings/ThemeAccentColorScreen",
|
||||
"//submodules/TelegramUI/Components/Settings/GenerateThemeName",
|
||||
"//submodules/TelegramUI/Components/Settings/PeerNameColorItem",
|
||||
"//submodules/TelegramUI/Components/Settings/PasskeysScreen",
|
||||
"//submodules/TelegramUI/Components/FaceScanScreen",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/Components/BundleIconComponent",
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public func ChangePhoneNumberController(context: AccountContext) -> ViewControll
|
|||
let requestDisposable = MetaDisposable()
|
||||
let changePhoneDisposable = MetaDisposable()
|
||||
|
||||
let controller = AuthorizationSequencePhoneEntryController(sharedContext: context.sharedContext, account: nil, countriesConfiguration: context.currentCountriesConfiguration.with { $0 }, isTestingEnvironment: false, otherAccountPhoneNumbers: (nil, []), network: context.account.network, presentationData: presentationData, openUrl: { _ in }, back: {
|
||||
let controller = AuthorizationSequencePhoneEntryController(sharedContext: context.sharedContext, account: nil, countriesConfiguration: context.currentCountriesConfiguration.with { $0 }, apiId: 0, apiHash: "", isTestingEnvironment: false, otherAccountPhoneNumbers: (nil, []), network: context.account.network, presentationData: presentationData, openUrl: { _ in }, back: {
|
||||
dismissImpl?()
|
||||
})
|
||||
controller.loginWithNumber = { [weak controller] phoneNumber, _ in
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ private func incomingMessagePrivacyScreenEntries(presentationData: PresentationD
|
|||
|
||||
let usdRate = Double(configuration.usdWithdrawRate) / 1000.0 / 100.0
|
||||
|
||||
let price = "≈\(formatTonUsdValue(amount.value, divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat))"
|
||||
let price = "~\(formatTonUsdValue(amount.value, divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat))"
|
||||
|
||||
entries.append(.price(value: amount.value, maxValue: configuration.paidMessageMaxAmount, price: price, isEnabled: isPremium))
|
||||
entries.append(.priceInfo(commission: configuration.paidMessageCommissionPermille / 10, value: price))
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import PremiumUI
|
|||
import AuthorizationUI
|
||||
import AuthenticationServices
|
||||
import ChatTimerScreen
|
||||
import PasskeysScreen
|
||||
|
||||
private final class PrivacyAndSecurityControllerArguments {
|
||||
let account: Account
|
||||
|
|
@ -35,6 +36,7 @@ private final class PrivacyAndSecurityControllerArguments {
|
|||
let openSavedMusicPrivacy: () -> Void
|
||||
let openPasscode: () -> Void
|
||||
let openTwoStepVerification: (TwoStepVerificationAccessConfiguration?) -> Void
|
||||
let openPasskeys: () -> Void
|
||||
let openActiveSessions: () -> Void
|
||||
let toggleArchiveAndMuteNonContacts: (Bool) -> Void
|
||||
let setupAccountAutoremove: () -> Void
|
||||
|
|
@ -44,7 +46,7 @@ private final class PrivacyAndSecurityControllerArguments {
|
|||
let openMessagePrivacy: () -> Void
|
||||
let openGiftsPrivacy: () -> Void
|
||||
|
||||
init(account: Account, openBlockedUsers: @escaping () -> Void, openLastSeenPrivacy: @escaping () -> Void, openGroupsPrivacy: @escaping () -> Void, openVoiceCallPrivacy: @escaping () -> Void, openProfilePhotoPrivacy: @escaping () -> Void, openForwardPrivacy: @escaping () -> Void, openPhoneNumberPrivacy: @escaping () -> Void, openVoiceMessagePrivacy: @escaping () -> Void, openBioPrivacy: @escaping () -> Void, openBirthdayPrivacy: @escaping () -> Void, openSavedMusicPrivacy: @escaping () -> Void, openPasscode: @escaping () -> Void, openTwoStepVerification: @escaping (TwoStepVerificationAccessConfiguration?) -> Void, openActiveSessions: @escaping () -> Void, toggleArchiveAndMuteNonContacts: @escaping (Bool) -> Void, setupAccountAutoremove: @escaping () -> Void, setupMessageAutoremove: @escaping () -> Void, openDataSettings: @escaping () -> Void, openEmailSettings: @escaping (String?) -> Void, openMessagePrivacy: @escaping () -> Void, openGiftsPrivacy: @escaping () -> Void) {
|
||||
init(account: Account, openBlockedUsers: @escaping () -> Void, openLastSeenPrivacy: @escaping () -> Void, openGroupsPrivacy: @escaping () -> Void, openVoiceCallPrivacy: @escaping () -> Void, openProfilePhotoPrivacy: @escaping () -> Void, openForwardPrivacy: @escaping () -> Void, openPhoneNumberPrivacy: @escaping () -> Void, openVoiceMessagePrivacy: @escaping () -> Void, openBioPrivacy: @escaping () -> Void, openBirthdayPrivacy: @escaping () -> Void, openSavedMusicPrivacy: @escaping () -> Void, openPasscode: @escaping () -> Void, openTwoStepVerification: @escaping (TwoStepVerificationAccessConfiguration?) -> Void, openPasskeys: @escaping () -> Void, openActiveSessions: @escaping () -> Void, toggleArchiveAndMuteNonContacts: @escaping (Bool) -> Void, setupAccountAutoremove: @escaping () -> Void, setupMessageAutoremove: @escaping () -> Void, openDataSettings: @escaping () -> Void, openEmailSettings: @escaping (String?) -> Void, openMessagePrivacy: @escaping () -> Void, openGiftsPrivacy: @escaping () -> Void) {
|
||||
self.account = account
|
||||
self.openBlockedUsers = openBlockedUsers
|
||||
self.openLastSeenPrivacy = openLastSeenPrivacy
|
||||
|
|
@ -59,6 +61,7 @@ private final class PrivacyAndSecurityControllerArguments {
|
|||
self.openSavedMusicPrivacy = openSavedMusicPrivacy
|
||||
self.openPasscode = openPasscode
|
||||
self.openTwoStepVerification = openTwoStepVerification
|
||||
self.openPasskeys = openPasskeys
|
||||
self.openActiveSessions = openActiveSessions
|
||||
self.toggleArchiveAndMuteNonContacts = toggleArchiveAndMuteNonContacts
|
||||
self.setupAccountAutoremove = setupAccountAutoremove
|
||||
|
|
@ -113,6 +116,7 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
|
|||
case selectivePrivacyInfo(PresentationTheme, String)
|
||||
case passcode(PresentationTheme, String, Bool, String)
|
||||
case twoStepVerification(PresentationTheme, String, String, TwoStepVerificationAccessConfiguration?)
|
||||
case passkeys(PresentationTheme, String, String)
|
||||
case loginEmail(PresentationTheme, String, String?)
|
||||
case loginEmailInfo(PresentationTheme, String)
|
||||
case activeSessions(PresentationTheme, String, String)
|
||||
|
|
@ -129,7 +133,7 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
|
|||
|
||||
var section: ItemListSectionId {
|
||||
switch self {
|
||||
case .blockedPeers, .activeSessions, .passcode, .twoStepVerification, .messageAutoremoveTimeout, .messageAutoremoveInfo:
|
||||
case .blockedPeers, .activeSessions, .passcode, .twoStepVerification, .passkeys, .messageAutoremoveTimeout, .messageAutoremoveInfo:
|
||||
return PrivacyAndSecuritySection.general.rawValue
|
||||
case .loginEmail, .loginEmailInfo:
|
||||
return PrivacyAndSecuritySection.loginEmail.rawValue
|
||||
|
|
@ -154,60 +158,62 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
|
|||
return 3
|
||||
case .twoStepVerification:
|
||||
return 4
|
||||
case .messageAutoremoveTimeout:
|
||||
case .passkeys:
|
||||
return 5
|
||||
case .messageAutoremoveInfo:
|
||||
case .messageAutoremoveTimeout:
|
||||
return 6
|
||||
case .loginEmail:
|
||||
case .messageAutoremoveInfo:
|
||||
return 7
|
||||
case .loginEmailInfo:
|
||||
case .loginEmail:
|
||||
return 8
|
||||
case .privacyHeader:
|
||||
case .loginEmailInfo:
|
||||
return 9
|
||||
case .phoneNumberPrivacy:
|
||||
case .privacyHeader:
|
||||
return 10
|
||||
case .lastSeenPrivacy:
|
||||
case .phoneNumberPrivacy:
|
||||
return 11
|
||||
case .profilePhotoPrivacy:
|
||||
case .lastSeenPrivacy:
|
||||
return 12
|
||||
case .bioPrivacy:
|
||||
case .profilePhotoPrivacy:
|
||||
return 13
|
||||
case .giftsAutoSavePrivacy:
|
||||
case .bioPrivacy:
|
||||
return 14
|
||||
case .birthdayPrivacy:
|
||||
case .giftsAutoSavePrivacy:
|
||||
return 15
|
||||
case .savedMusicPrivacy:
|
||||
case .birthdayPrivacy:
|
||||
return 16
|
||||
case .forwardPrivacy:
|
||||
case .savedMusicPrivacy:
|
||||
return 17
|
||||
case .voiceCallPrivacy:
|
||||
case .forwardPrivacy:
|
||||
return 18
|
||||
case .voiceMessagePrivacy:
|
||||
case .voiceCallPrivacy:
|
||||
return 19
|
||||
case .messagePrivacy:
|
||||
case .voiceMessagePrivacy:
|
||||
return 20
|
||||
case .groupPrivacy:
|
||||
case .messagePrivacy:
|
||||
return 21
|
||||
case .groupPrivacyFooter:
|
||||
case .groupPrivacy:
|
||||
return 22
|
||||
case .selectivePrivacyInfo:
|
||||
case .groupPrivacyFooter:
|
||||
return 23
|
||||
case .autoArchiveHeader:
|
||||
case .selectivePrivacyInfo:
|
||||
return 24
|
||||
case .autoArchive:
|
||||
case .autoArchiveHeader:
|
||||
return 25
|
||||
case .autoArchiveInfo:
|
||||
case .autoArchive:
|
||||
return 26
|
||||
case .accountHeader:
|
||||
case .autoArchiveInfo:
|
||||
return 27
|
||||
case .accountTimeout:
|
||||
case .accountHeader:
|
||||
return 28
|
||||
case .accountInfo:
|
||||
case .accountTimeout:
|
||||
return 29
|
||||
case .dataSettings:
|
||||
case .accountInfo:
|
||||
return 30
|
||||
case .dataSettingsInfo:
|
||||
case .dataSettings:
|
||||
return 31
|
||||
case .dataSettingsInfo:
|
||||
return 32
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -321,6 +327,12 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
|
|||
} else {
|
||||
return false
|
||||
}
|
||||
case let .passkeys(lhsTheme, lhsText, lhsValue):
|
||||
if case let .passkeys(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .loginEmail(lhsTheme, lhsText, lhsEmailPattern):
|
||||
if case let .loginEmail(rhsTheme, rhsText, rhsEmailPattern) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsEmailPattern == rhsEmailPattern {
|
||||
return true
|
||||
|
|
@ -488,6 +500,10 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
|
|||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, icon: UIImage(bundleImageName: "Settings/Menu/TwoStepAuth")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openTwoStepVerification(data)
|
||||
})
|
||||
case let .passkeys(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, icon: UIImage(bundleImageName: "Settings/Menu/Passkeys")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openPasskeys()
|
||||
})
|
||||
case let .messageAutoremoveTimeout(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, icon: UIImage(bundleImageName: "Settings/Menu/Timer")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.setupMessageAutoremove()
|
||||
|
|
@ -617,6 +633,8 @@ private func privacyAndSecurityControllerEntries(
|
|||
activeWebsitesCount: Int,
|
||||
hasTwoStepAuth: Bool?,
|
||||
twoStepAuthData: TwoStepVerificationAccessConfiguration?,
|
||||
hasPasskeys: Bool?,
|
||||
displayPasskeys: Bool,
|
||||
canAutoarchive: Bool,
|
||||
isPremiumDisabled: Bool,
|
||||
isPremium: Bool,
|
||||
|
|
@ -654,6 +672,14 @@ private func privacyAndSecurityControllerEntries(
|
|||
}
|
||||
entries.append(.twoStepVerification(presentationData.theme, presentationData.strings.PrivacySettings_TwoStepAuth, twoStepAuthString, twoStepAuthData))
|
||||
|
||||
if displayPasskeys {
|
||||
var passkeysString = ""
|
||||
if let hasPasskeys = hasPasskeys {
|
||||
passkeysString = hasPasskeys ? presentationData.strings.PrivacySettings_PasscodeOn : presentationData.strings.PrivacySettings_PasscodeOff
|
||||
}
|
||||
entries.append(.passkeys(presentationData.theme, presentationData.strings.PrivacySettings_Passkey, passkeysString))
|
||||
}
|
||||
|
||||
if let privacySettings = privacySettings {
|
||||
let value: Int32?
|
||||
if let updatingMessageAutoremoveTimeoutValue = state.updatingMessageAutoremoveTimeoutValue {
|
||||
|
|
@ -788,6 +814,7 @@ public func privacyAndSecurityController(
|
|||
updatedSettings: ((AccountPrivacySettings?) -> Void)? = nil,
|
||||
updatedBlockedPeers: ((BlockedPeersContext?) -> Void)? = nil,
|
||||
updatedHasTwoStepAuth: ((Bool) -> Void)? = nil,
|
||||
updatedHasPasskeys: ((Bool) -> Void)? = nil,
|
||||
focusOnItemTag: PrivacyAndSecurityEntryTag? = nil,
|
||||
activeSessionsContext: ActiveSessionsContext? = nil,
|
||||
webSessionsContext: WebSessionsContext? = nil,
|
||||
|
|
@ -835,6 +862,10 @@ public func privacyAndSecurityController(
|
|||
let updateTwoStepAuthDisposable = MetaDisposable()
|
||||
actionsDisposable.add(updateTwoStepAuthDisposable)
|
||||
|
||||
|
||||
let updatePasskeyDataDisposable = MetaDisposable()
|
||||
actionsDisposable.add(updatePasskeyDataDisposable)
|
||||
|
||||
let twoStepAuthDataValue = Promise<TwoStepVerificationAccessConfiguration?>(nil)
|
||||
let hasTwoStepAuthDataValue = twoStepAuthDataValue.get()
|
||||
|> mapToSignal { data -> Signal<Bool?, NoError> in
|
||||
|
|
@ -855,6 +886,19 @@ public func privacyAndSecurityController(
|
|||
} else {
|
||||
twoStepAuth.set(hasTwoStepAuthDataValue)
|
||||
}
|
||||
|
||||
let passkeysDataValue = Promise<[TelegramPasskey]?>(nil)
|
||||
let hasPasskeysDataValue = passkeysDataValue.get()
|
||||
|> mapToSignal { data -> Signal<Bool?, NoError> in
|
||||
if let data = data {
|
||||
return .single(!data.isEmpty)
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
|
||||
let passkeys = Promise<Bool?>()
|
||||
passkeys.set(hasPasskeysDataValue)
|
||||
|
||||
let loginEmail: Signal<String?, NoError>
|
||||
if let loginEmailPattern = loginEmailPattern {
|
||||
|
|
@ -893,6 +937,23 @@ public func privacyAndSecurityController(
|
|||
)
|
||||
}
|
||||
updateHasTwoStepAuth()
|
||||
|
||||
let updateHasPasskeys: () -> Void = {
|
||||
let signal = context.engine.auth.passkeysData()
|
||||
|> map { value -> [TelegramPasskey]? in
|
||||
return value
|
||||
}
|
||||
|> deliverOnMainQueue
|
||||
updatePasskeyDataDisposable.set(
|
||||
signal.start(next: { value in
|
||||
passkeysDataValue.set(.single(value))
|
||||
if let value {
|
||||
updatedHasPasskeys?(!value.isEmpty)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
updateHasPasskeys()
|
||||
|
||||
var setupEmailImpl: ((String?) -> Void)?
|
||||
|
||||
|
|
@ -1203,6 +1264,14 @@ public func privacyAndSecurityController(
|
|||
let controller = twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: false, data: data.flatMap({ Signal<TwoStepVerificationUnlockSettingsControllerData, NoError>.single(.access(configuration: $0)) })))
|
||||
pushControllerImpl?(controller, true)
|
||||
})
|
||||
}, openPasskeys: {
|
||||
Task { @MainActor in
|
||||
let initialPasskeysData = await (passkeysDataValue.get() |> take(1)).get()
|
||||
let passkeysScreen = PasskeysScreen(context: context, displaySkip: false, initialPasskeysData: initialPasskeysData, passkeysDataUpdated: { passkeysData in
|
||||
passkeysDataValue.set(.single(passkeysData))
|
||||
}, completion: {}, cancel: {})
|
||||
pushControllerImpl?(passkeysScreen, true)
|
||||
}
|
||||
}, openActiveSessions: {
|
||||
pushControllerImpl?(recentSessionsController(context: context, activeSessionsContext: activeSessionsContext, webSessionsContext: webSessionsContext, websitesOnly: true), true)
|
||||
}, toggleArchiveAndMuteNonContacts: { archiveValue in
|
||||
|
|
@ -1442,6 +1511,15 @@ public func privacyAndSecurityController(
|
|||
updatedBlockedPeers?(blockedPeersContext)
|
||||
}))
|
||||
|
||||
var displayPasskeys = false
|
||||
if let data = context.currentAppConfiguration.with({ $0 }).data {
|
||||
if let _ = data["ios_display_passkeys"] {
|
||||
displayPasskeys = true
|
||||
} else if let isDev = data["dev"] as? Double, isDev == 1.0 {
|
||||
displayPasskeys = true
|
||||
}
|
||||
}
|
||||
|
||||
let signal = combineLatest(
|
||||
queue: .mainQueue(),
|
||||
context.sharedContext.presentationData,
|
||||
|
|
@ -1454,11 +1532,12 @@ public func privacyAndSecurityController(
|
|||
webSessionsContext.state,
|
||||
context.sharedContext.accountManager.accessChallengeData(),
|
||||
combineLatest(twoStepAuth.get(), twoStepAuthDataValue.get()),
|
||||
combineLatest(passkeys.get(), passkeysDataValue.get()),
|
||||
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App()),
|
||||
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)),
|
||||
loginEmail
|
||||
)
|
||||
|> map { presentationData, state, privacySettings, noticeView, sharedData, recentPeers, blockedPeersState, activeWebsitesState, accessChallengeData, twoStepAuth, appConfiguration, accountPeer, loginEmail -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
|> map { presentationData, state, privacySettings, noticeView, sharedData, recentPeers, blockedPeersState, activeWebsitesState, accessChallengeData, twoStepAuth, passkeys, appConfiguration, accountPeer, loginEmail -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
var canAutoarchive = false
|
||||
if let data = appConfiguration.data, let hasAutoarchive = data["autoarchive_setting_available"] as? Bool {
|
||||
canAutoarchive = hasAutoarchive
|
||||
|
|
@ -1474,7 +1553,7 @@ public func privacyAndSecurityController(
|
|||
let isPremium = accountPeer?.isPremium ?? false
|
||||
let isPremiumDisabled = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }).isPremiumDisabled
|
||||
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: privacyAndSecurityControllerEntries(presentationData: presentationData, state: state, privacySettings: privacySettings, accessChallengeData: accessChallengeData.data, blockedPeerCount: blockedPeersState.totalCount, activeWebsitesCount: activeWebsitesState.sessions.count, hasTwoStepAuth: twoStepAuth.0, twoStepAuthData: twoStepAuth.1, canAutoarchive: canAutoarchive, isPremiumDisabled: isPremiumDisabled, isPremium: isPremium, loginEmail: loginEmail, accountPeer: accountPeer), style: .blocks, ensureVisibleItemTag: focusOnItemTag, animateChanges: false)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: privacyAndSecurityControllerEntries(presentationData: presentationData, state: state, privacySettings: privacySettings, accessChallengeData: accessChallengeData.data, blockedPeerCount: blockedPeersState.totalCount, activeWebsitesCount: activeWebsitesState.sessions.count, hasTwoStepAuth: twoStepAuth.0, twoStepAuthData: twoStepAuth.1, hasPasskeys: passkeys.0, displayPasskeys: displayPasskeys, canAutoarchive: canAutoarchive, isPremiumDisabled: isPremiumDisabled, isPremium: isPremium, loginEmail: loginEmail, accountPeer: accountPeer), style: .blocks, ensureVisibleItemTag: focusOnItemTag, animateChanges: false)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,10 +180,10 @@ final class MonetizationBalanceItemNode: ListViewItemNode, ItemListItemNode {
|
|||
case .ton:
|
||||
let cryptoValue = formatTonAmountText(stats.balances.availableBalance.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat)
|
||||
amountString = tonAmountAttributedString(cryptoValue, integralFont: integralFont, fractionalFont: fractionalFont, color: item.presentationData.theme.list.itemPrimaryTextColor, decimalSeparator: item.presentationData.dateTimeFormat.decimalSeparator)
|
||||
value = stats.balances.availableBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))"
|
||||
value = stats.balances.availableBalance.amount == StarsAmount.zero ? "" : "~\(formatTonUsdValue(stats.balances.availableBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))"
|
||||
case .stars:
|
||||
amountString = NSAttributedString(string: presentationStringsFormattedNumber(stats.balances.availableBalance.amount, item.presentationData.dateTimeFormat.groupingSeparator), font: integralFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor)
|
||||
value = stats.balances.availableBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))"
|
||||
value = stats.balances.availableBalance.amount == StarsAmount.zero ? "" : "~\(formatTonUsdValue(stats.balances.availableBalance.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))"
|
||||
isStars = true
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -443,7 +443,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.context,
|
||||
params.width,
|
||||
item.presentationData,
|
||||
item.publicShares.flatMap { "≈\( compactNumericCountString(max(0, stats.forwards - Int($0))))" } ?? "–",
|
||||
item.publicShares.flatMap { "~\( compactNumericCountString(max(0, stats.forwards - Int($0))))" } ?? "–",
|
||||
item.presentationData.strings.Stats_Message_PrivateShares,
|
||||
nil,
|
||||
.generic
|
||||
|
|
@ -485,7 +485,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.context,
|
||||
params.width,
|
||||
item.presentationData,
|
||||
item.publicShares.flatMap { "≈\( compactNumericCountString(max(0, views.forwardCount - Int($0))))" } ?? "–",
|
||||
item.publicShares.flatMap { "~\( compactNumericCountString(max(0, views.forwardCount - Int($0))))" } ?? "–",
|
||||
item.presentationData.strings.Stats_Message_PrivateShares,
|
||||
nil,
|
||||
.generic
|
||||
|
|
@ -512,7 +512,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.context,
|
||||
params.width,
|
||||
item.presentationData,
|
||||
"≈\(Int(stats.premiumAudience?.value ?? 0))",
|
||||
"~\(Int(stats.premiumAudience?.value ?? 0))",
|
||||
item.isGroup ? item.presentationData.strings.Stats_Boosts_PremiumMembers : item.presentationData.strings.Stats_Boosts_PremiumSubscribers,
|
||||
(String(format: "%.02f%%", premiumSubscribers * 100.0), .generic),
|
||||
.generic
|
||||
|
|
@ -770,7 +770,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatTonAmountText(stats.balances.availableBalance.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
item.presentationData.strings.Monetization_StarsProceeds_Available,
|
||||
(stats.balances.availableBalance.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(stats.balances.availableBalance.amount.value == 0 ? "" : "~\(formatTonUsdValue(stats.balances.availableBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.ton
|
||||
)
|
||||
|
||||
|
|
@ -780,7 +780,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatTonAmountText(stats.balances.currentBalance.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
item.presentationData.strings.Monetization_StarsProceeds_Current,
|
||||
(stats.balances.currentBalance.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.currentBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(stats.balances.currentBalance.amount.value == 0 ? "" : "~\(formatTonUsdValue(stats.balances.currentBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.ton
|
||||
)
|
||||
|
||||
|
|
@ -790,7 +790,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatTonAmountText(stats.balances.overallRevenue.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
item.presentationData.strings.Monetization_StarsProceeds_Total,
|
||||
(stats.balances.overallRevenue.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.overallRevenue.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(stats.balances.overallRevenue.amount.value == 0 ? "" : "~\(formatTonUsdValue(stats.balances.overallRevenue.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.ton
|
||||
)
|
||||
|
||||
|
|
@ -800,7 +800,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatStarsAmountText(additionalStats.balances.availableBalance.amount, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
" ",
|
||||
(additionalStats.balances.availableBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(additionalStats.balances.availableBalance.amount.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(additionalStats.balances.availableBalance.amount == StarsAmount.zero ? "" : "~\(formatTonUsdValue(additionalStats.balances.availableBalance.amount.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.stars
|
||||
)
|
||||
|
||||
|
|
@ -810,7 +810,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatStarsAmountText(additionalStats.balances.currentBalance.amount, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
" ",
|
||||
(additionalStats.balances.currentBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(additionalStats.balances.currentBalance.amount.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(additionalStats.balances.currentBalance.amount == StarsAmount.zero ? "" : "~\(formatTonUsdValue(additionalStats.balances.currentBalance.amount.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.stars
|
||||
)
|
||||
|
||||
|
|
@ -820,7 +820,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatStarsAmountText(additionalStats.balances.overallRevenue.amount, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
" ",
|
||||
(additionalStats.balances.overallRevenue.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(additionalStats.balances.overallRevenue.amount.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(additionalStats.balances.overallRevenue.amount == StarsAmount.zero ? "" : "~\(formatTonUsdValue(additionalStats.balances.overallRevenue.amount.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.stars
|
||||
)
|
||||
|
||||
|
|
@ -834,7 +834,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatTonAmountText(stats.balances.availableBalance.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
item.presentationData.strings.Monetization_Overview_Available,
|
||||
(stats.balances.availableBalance.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(stats.balances.availableBalance.amount.value == 0 ? "" : "~\(formatTonUsdValue(stats.balances.availableBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.ton
|
||||
)
|
||||
|
||||
|
|
@ -844,7 +844,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatTonAmountText(stats.balances.currentBalance.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
item.presentationData.strings.Monetization_Overview_Current,
|
||||
(stats.balances.currentBalance.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.currentBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(stats.balances.currentBalance.amount.value == 0 ? "" : "~\(formatTonUsdValue(stats.balances.currentBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.ton
|
||||
)
|
||||
|
||||
|
|
@ -854,7 +854,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatTonAmountText(stats.balances.overallRevenue.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
item.presentationData.strings.Monetization_Overview_Total,
|
||||
(stats.balances.overallRevenue.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.overallRevenue.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(stats.balances.overallRevenue.amount.value == 0 ? "" : "~\(formatTonUsdValue(stats.balances.overallRevenue.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.ton
|
||||
)
|
||||
|
||||
|
|
@ -869,7 +869,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatStarsAmountText(stats.balances.availableBalance.amount, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
item.presentationData.strings.Monetization_StarsProceeds_Available,
|
||||
(stats.balances.availableBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(stats.balances.availableBalance.amount == StarsAmount.zero ? "" : "~\(formatTonUsdValue(stats.balances.availableBalance.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.stars
|
||||
)
|
||||
|
||||
|
|
@ -879,7 +879,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatStarsAmountText(stats.balances.currentBalance.amount, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
item.presentationData.strings.Monetization_StarsProceeds_Current,
|
||||
(stats.balances.currentBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.currentBalance.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(stats.balances.currentBalance.amount == StarsAmount.zero ? "" : "~\(formatTonUsdValue(stats.balances.currentBalance.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.stars
|
||||
)
|
||||
|
||||
|
|
@ -889,7 +889,7 @@ class StatsOverviewItemNode: ListViewItemNode {
|
|||
item.presentationData,
|
||||
formatStarsAmountText(stats.balances.overallRevenue.amount, dateTimeFormat: item.presentationData.dateTimeFormat),
|
||||
item.presentationData.strings.Monetization_StarsProceeds_Total,
|
||||
(stats.balances.overallRevenue.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.overallRevenue.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
(stats.balances.overallRevenue.amount == StarsAmount.zero ? "" : "~\(formatTonUsdValue(stats.balances.overallRevenue.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic),
|
||||
.stars
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -432,6 +432,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1548122514] = { return Api.InputNotifyPeer.parse_inputNotifyForumTopic($0) }
|
||||
dict[-1195615476] = { return Api.InputNotifyPeer.parse_inputNotifyPeer($0) }
|
||||
dict[423314455] = { return Api.InputNotifyPeer.parse_inputNotifyUsers($0) }
|
||||
dict[1009235855] = { return Api.InputPasskeyCredential.parse_inputPasskeyCredentialPublicKey($0) }
|
||||
dict[-1021329078] = { return Api.InputPasskeyResponse.parse_inputPasskeyResponseLogin($0) }
|
||||
dict[1046713180] = { return Api.InputPasskeyResponse.parse_inputPasskeyResponseRegister($0) }
|
||||
dict[873977640] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentials($0) }
|
||||
dict[178373535] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentialsApplePay($0) }
|
||||
dict[-1966921727] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentialsGooglePay($0) }
|
||||
|
|
@ -617,7 +620,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1189364422] = { return Api.MessageAction.parse_messageActionSetChatTheme($0) }
|
||||
dict[1348510708] = { return Api.MessageAction.parse_messageActionSetChatWallPaper($0) }
|
||||
dict[1007897979] = { return Api.MessageAction.parse_messageActionSetMessagesTTL($0) }
|
||||
dict[-614898352] = { return Api.MessageAction.parse_messageActionStarGift($0) }
|
||||
dict[-366202413] = { return Api.MessageAction.parse_messageActionStarGift($0) }
|
||||
dict[2000845012] = { return Api.MessageAction.parse_messageActionStarGiftPurchaseOffer($0) }
|
||||
dict[1940760427] = { return Api.MessageAction.parse_messageActionStarGiftPurchaseOfferDeclined($0) }
|
||||
dict[-1787656893] = { return Api.MessageAction.parse_messageActionStarGiftUnique($0) }
|
||||
dict[747579941] = { return Api.MessageAction.parse_messageActionSuggestBirthday($0) }
|
||||
dict[1474192222] = { return Api.MessageAction.parse_messageActionSuggestProfilePhoto($0) }
|
||||
|
|
@ -756,6 +761,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[520887001] = { return Api.PaidReactionPrivacy.parse_paidReactionPrivacyAnonymous($0) }
|
||||
dict[543872158] = { return Api.PaidReactionPrivacy.parse_paidReactionPrivacyDefault($0) }
|
||||
dict[-596837136] = { return Api.PaidReactionPrivacy.parse_paidReactionPrivacyPeer($0) }
|
||||
dict[-1738457409] = { return Api.Passkey.parse_passkey($0) }
|
||||
dict[982592842] = { return Api.PasswordKdfAlgo.parse_passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow($0) }
|
||||
dict[-732254058] = { return Api.PasswordKdfAlgo.parse_passwordKdfAlgoUnknown($0) }
|
||||
dict[-368917890] = { return Api.PaymentCharge.parse_paymentCharge($0) }
|
||||
|
|
@ -909,7 +915,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1681948327] = { return Api.SavedDialog.parse_monoForumDialog($0) }
|
||||
dict[-1115174036] = { return Api.SavedDialog.parse_savedDialog($0) }
|
||||
dict[-881854424] = { return Api.SavedReactionTag.parse_savedReactionTag($0) }
|
||||
dict[-1987861422] = { return Api.SavedStarGift.parse_savedStarGift($0) }
|
||||
dict[-355041186] = { return Api.SavedStarGift.parse_savedStarGift($0) }
|
||||
dict[1040931690] = { return Api.SearchPostsFlood.parse_searchPostsFlood($0) }
|
||||
dict[-911191137] = { return Api.SearchResultsCalendarPeriod.parse_searchResultsCalendarPeriod($0) }
|
||||
dict[2137295719] = { return Api.SearchResultsPosition.parse_searchResultPosition($0) }
|
||||
|
|
@ -974,8 +980,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[2109703795] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
|
||||
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
|
||||
dict[-963180333] = { return Api.SponsoredPeer.parse_sponsoredPeer($0) }
|
||||
dict[463097215] = { return Api.StarGift.parse_starGift($0) }
|
||||
dict[-1329630181] = { return Api.StarGift.parse_starGiftUnique($0) }
|
||||
dict[825922887] = { return Api.StarGift.parse_starGift($0) }
|
||||
dict[1453155529] = { return Api.StarGift.parse_starGiftUnique($0) }
|
||||
dict[-753154979] = { return Api.StarGiftActiveAuctionState.parse_starGiftActiveAuctionState($0) }
|
||||
dict[-650279524] = { return Api.StarGiftAttribute.parse_starGiftAttributeBackdrop($0) }
|
||||
dict[970559507] = { return Api.StarGiftAttribute.parse_starGiftAttributeModel($0) }
|
||||
|
|
@ -985,11 +991,14 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[520210263] = { return Api.StarGiftAttributeId.parse_starGiftAttributeIdBackdrop($0) }
|
||||
dict[1219145276] = { return Api.StarGiftAttributeId.parse_starGiftAttributeIdModel($0) }
|
||||
dict[1242965043] = { return Api.StarGiftAttributeId.parse_starGiftAttributeIdPattern($0) }
|
||||
dict[-1419714037] = { return Api.StarGiftAuctionAcquiredGift.parse_starGiftAuctionAcquiredGift($0) }
|
||||
dict[1571835723] = { return Api.StarGiftAuctionState.parse_starGiftAuctionState($0) }
|
||||
dict[2107014202] = { return Api.StarGiftAuctionState.parse_starGiftAuctionStateFinished($0) }
|
||||
dict[1118831432] = { return Api.StarGiftAuctionAcquiredGift.parse_starGiftAuctionAcquiredGift($0) }
|
||||
dict[984483112] = { return Api.StarGiftAuctionRound.parse_starGiftAuctionRound($0) }
|
||||
dict[178266597] = { return Api.StarGiftAuctionRound.parse_starGiftAuctionRoundExtendable($0) }
|
||||
dict[1998212710] = { return Api.StarGiftAuctionState.parse_starGiftAuctionState($0) }
|
||||
dict[-1758614593] = { return Api.StarGiftAuctionState.parse_starGiftAuctionStateFinished($0) }
|
||||
dict[-30197422] = { return Api.StarGiftAuctionState.parse_starGiftAuctionStateNotModified($0) }
|
||||
dict[787403204] = { return Api.StarGiftAuctionUserState.parse_starGiftAuctionUserState($0) }
|
||||
dict[-1342872680] = { return Api.StarGiftBackground.parse_starGiftBackground($0) }
|
||||
dict[-1653926992] = { return Api.StarGiftCollection.parse_starGiftCollection($0) }
|
||||
dict[-1712704739] = { return Api.StarGiftUpgradePrice.parse_starGiftUpgradePrice($0) }
|
||||
dict[-586389774] = { return Api.StarRefProgram.parse_starRefProgram($0) }
|
||||
|
|
@ -1246,7 +1255,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[555358088] = { return Api.WebPage.parse_webPageEmpty($0) }
|
||||
dict[1930545681] = { return Api.WebPage.parse_webPageNotModified($0) }
|
||||
dict[-1328464313] = { return Api.WebPage.parse_webPagePending($0) }
|
||||
dict[55150251] = { return Api.WebPageAttribute.parse_webPageAttributeStarGiftAuction($0) }
|
||||
dict[29770178] = { return Api.WebPageAttribute.parse_webPageAttributeStarGiftAuction($0) }
|
||||
dict[835375875] = { return Api.WebPageAttribute.parse_webPageAttributeStarGiftCollection($0) }
|
||||
dict[1355547603] = { return Api.WebPageAttribute.parse_webPageAttributeStickerSet($0) }
|
||||
dict[781501415] = { return Api.WebPageAttribute.parse_webPageAttributeStory($0) }
|
||||
|
|
@ -1268,6 +1277,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1866176559] = { return Api.account.EmojiStatuses.parse_emojiStatuses($0) }
|
||||
dict[-796072379] = { return Api.account.EmojiStatuses.parse_emojiStatusesNotModified($0) }
|
||||
dict[504403720] = { return Api.account.PaidMessagesRevenue.parse_paidMessagesRevenue($0) }
|
||||
dict[-513057567] = { return Api.account.PasskeyRegistrationOptions.parse_passkeyRegistrationOptions($0) }
|
||||
dict[-119494116] = { return Api.account.Passkeys.parse_passkeys($0) }
|
||||
dict[-1787080453] = { return Api.account.Password.parse_password($0) }
|
||||
dict[-1036572727] = { return Api.account.PasswordInputSettings.parse_passwordInputSettings($0) }
|
||||
dict[-1705233435] = { return Api.account.PasswordSettings.parse_passwordSettings($0) }
|
||||
|
|
@ -1302,6 +1313,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1654593920] = { return Api.auth.LoginToken.parse_loginToken($0) }
|
||||
dict[110008598] = { return Api.auth.LoginToken.parse_loginTokenMigrateTo($0) }
|
||||
dict[957176926] = { return Api.auth.LoginToken.parse_loginTokenSuccess($0) }
|
||||
dict[-503089271] = { return Api.auth.PasskeyLoginOptions.parse_passkeyLoginOptions($0) }
|
||||
dict[326715557] = { return Api.auth.PasswordRecovery.parse_passwordRecovery($0) }
|
||||
dict[1577067778] = { return Api.auth.SentCode.parse_sentCode($0) }
|
||||
dict[-527082948] = { return Api.auth.SentCode.parse_sentCodePaymentRequired($0) }
|
||||
|
|
@ -1484,12 +1496,13 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1803939105] = { return Api.payments.ResaleStarGifts.parse_resaleStarGifts($0) }
|
||||
dict[-74456004] = { return Api.payments.SavedInfo.parse_savedInfo($0) }
|
||||
dict[-1779201615] = { return Api.payments.SavedStarGifts.parse_savedStarGifts($0) }
|
||||
dict[-1745778728] = { return Api.payments.StarGiftActiveAuctions.parse_starGiftActiveAuctions($0) }
|
||||
dict[-1359565892] = { return Api.payments.StarGiftActiveAuctions.parse_starGiftActiveAuctions($0) }
|
||||
dict[-617358640] = { return Api.payments.StarGiftActiveAuctions.parse_starGiftActiveAuctionsNotModified($0) }
|
||||
dict[2103169520] = { return Api.payments.StarGiftAuctionAcquiredGifts.parse_starGiftAuctionAcquiredGifts($0) }
|
||||
dict[244900980] = { return Api.payments.StarGiftAuctionState.parse_starGiftAuctionState($0) }
|
||||
dict[1798960364] = { return Api.payments.StarGiftAuctionState.parse_starGiftAuctionState($0) }
|
||||
dict[-1977011469] = { return Api.payments.StarGiftCollections.parse_starGiftCollections($0) }
|
||||
dict[-1598402793] = { return Api.payments.StarGiftCollections.parse_starGiftCollectionsNotModified($0) }
|
||||
dict[1187439471] = { return Api.payments.StarGiftUpgradeAttributes.parse_starGiftUpgradeAttributes($0) }
|
||||
dict[1038213101] = { return Api.payments.StarGiftUpgradePreview.parse_starGiftUpgradePreview($0) }
|
||||
dict[-2069218660] = { return Api.payments.StarGiftWithdrawalUrl.parse_starGiftWithdrawalUrl($0) }
|
||||
dict[785918357] = { return Api.payments.StarGifts.parse_starGifts($0) }
|
||||
|
|
@ -1930,6 +1943,10 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputNotifyPeer:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputPasskeyCredential:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputPasskeyResponse:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputPaymentCredentials:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputPeer:
|
||||
|
|
@ -2066,6 +2083,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.PaidReactionPrivacy:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.Passkey:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.PasswordKdfAlgo:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.PaymentCharge:
|
||||
|
|
@ -2228,10 +2247,14 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.StarGiftAuctionAcquiredGift:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.StarGiftAuctionRound:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.StarGiftAuctionState:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.StarGiftAuctionUserState:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.StarGiftBackground:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.StarGiftCollection:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.StarGiftUpgradePrice:
|
||||
|
|
@ -2376,6 +2399,10 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.PaidMessagesRevenue:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.PasskeyRegistrationOptions:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.Passkeys:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.Password:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.PasswordInputSettings:
|
||||
|
|
@ -2416,6 +2443,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.auth.LoginToken:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.auth.PasskeyLoginOptions:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.auth.PasswordRecovery:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.auth.SentCode:
|
||||
|
|
@ -2656,6 +2685,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.StarGiftCollections:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.StarGiftUpgradeAttributes:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.StarGiftUpgradePreview:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.StarGiftWithdrawalUrl:
|
||||
|
|
|
|||
|
|
@ -868,6 +868,128 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum InputPasskeyCredential: TypeConstructorDescription {
|
||||
case inputPasskeyCredentialPublicKey(id: String, rawId: String, response: Api.InputPasskeyResponse)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .inputPasskeyCredentialPublicKey(let id, let rawId, let response):
|
||||
if boxed {
|
||||
buffer.appendInt32(1009235855)
|
||||
}
|
||||
serializeString(id, buffer: buffer, boxed: false)
|
||||
serializeString(rawId, buffer: buffer, boxed: false)
|
||||
response.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .inputPasskeyCredentialPublicKey(let id, let rawId, let response):
|
||||
return ("inputPasskeyCredentialPublicKey", [("id", id as Any), ("rawId", rawId as Any), ("response", response as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_inputPasskeyCredentialPublicKey(_ reader: BufferReader) -> InputPasskeyCredential? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: Api.InputPasskeyResponse?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.InputPasskeyResponse
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.InputPasskeyCredential.inputPasskeyCredentialPublicKey(id: _1!, rawId: _2!, response: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum InputPasskeyResponse: TypeConstructorDescription {
|
||||
case inputPasskeyResponseLogin(clientData: Api.DataJSON, authenticatorData: Buffer, signature: Buffer, userHandle: String)
|
||||
case inputPasskeyResponseRegister(clientData: Api.DataJSON, attestationData: Buffer)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .inputPasskeyResponseLogin(let clientData, let authenticatorData, let signature, let userHandle):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1021329078)
|
||||
}
|
||||
clientData.serialize(buffer, true)
|
||||
serializeBytes(authenticatorData, buffer: buffer, boxed: false)
|
||||
serializeBytes(signature, buffer: buffer, boxed: false)
|
||||
serializeString(userHandle, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .inputPasskeyResponseRegister(let clientData, let attestationData):
|
||||
if boxed {
|
||||
buffer.appendInt32(1046713180)
|
||||
}
|
||||
clientData.serialize(buffer, true)
|
||||
serializeBytes(attestationData, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .inputPasskeyResponseLogin(let clientData, let authenticatorData, let signature, let userHandle):
|
||||
return ("inputPasskeyResponseLogin", [("clientData", clientData as Any), ("authenticatorData", authenticatorData as Any), ("signature", signature as Any), ("userHandle", userHandle as Any)])
|
||||
case .inputPasskeyResponseRegister(let clientData, let attestationData):
|
||||
return ("inputPasskeyResponseRegister", [("clientData", clientData as Any), ("attestationData", attestationData as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_inputPasskeyResponseLogin(_ reader: BufferReader) -> InputPasskeyResponse? {
|
||||
var _1: Api.DataJSON?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
||||
}
|
||||
var _2: Buffer?
|
||||
_2 = parseBytes(reader)
|
||||
var _3: Buffer?
|
||||
_3 = parseBytes(reader)
|
||||
var _4: String?
|
||||
_4 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.InputPasskeyResponse.inputPasskeyResponseLogin(clientData: _1!, authenticatorData: _2!, signature: _3!, userHandle: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_inputPasskeyResponseRegister(_ reader: BufferReader) -> InputPasskeyResponse? {
|
||||
var _1: Api.DataJSON?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
||||
}
|
||||
var _2: Buffer?
|
||||
_2 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.InputPasskeyResponse.inputPasskeyResponseRegister(clientData: _1!, attestationData: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum InputPaymentCredentials: TypeConstructorDescription {
|
||||
case inputPaymentCredentials(flags: Int32, data: Api.DataJSON)
|
||||
|
|
|
|||
|
|
@ -1069,7 +1069,9 @@ public extension Api {
|
|||
case messageActionSetChatTheme(theme: Api.ChatTheme)
|
||||
case messageActionSetChatWallPaper(flags: Int32, wallpaper: Api.WallPaper)
|
||||
case messageActionSetMessagesTTL(flags: Int32, period: Int32, autoSettingFrom: Int64?)
|
||||
case messageActionStarGift(flags: Int32, gift: Api.StarGift, message: Api.TextWithEntities?, convertStars: Int64?, upgradeMsgId: Int32?, upgradeStars: Int64?, fromId: Api.Peer?, peer: Api.Peer?, savedId: Int64?, prepaidUpgradeHash: String?, giftMsgId: Int32?, toId: Api.Peer?)
|
||||
case messageActionStarGift(flags: Int32, gift: Api.StarGift, message: Api.TextWithEntities?, convertStars: Int64?, upgradeMsgId: Int32?, upgradeStars: Int64?, fromId: Api.Peer?, peer: Api.Peer?, savedId: Int64?, prepaidUpgradeHash: String?, giftMsgId: Int32?, toId: Api.Peer?, giftNum: Int32?)
|
||||
case messageActionStarGiftPurchaseOffer(flags: Int32, gift: Api.StarGift, price: Api.StarsAmount, expiresAt: Int32)
|
||||
case messageActionStarGiftPurchaseOfferDeclined(flags: Int32, gift: Api.StarGift, price: Api.StarsAmount)
|
||||
case messageActionStarGiftUnique(flags: Int32, gift: Api.StarGift, canExportAt: Int32?, transferStars: Int64?, fromId: Api.Peer?, peer: Api.Peer?, savedId: Int64?, resaleAmount: Api.StarsAmount?, canTransferAt: Int32?, canResellAt: Int32?, dropOriginalDetailsStars: Int64?)
|
||||
case messageActionSuggestBirthday(birthday: Api.Birthday)
|
||||
case messageActionSuggestProfilePhoto(photo: Api.Photo)
|
||||
|
|
@ -1460,9 +1462,9 @@ public extension Api {
|
|||
serializeInt32(period, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(autoSettingFrom!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .messageActionStarGift(let flags, let gift, let message, let convertStars, let upgradeMsgId, let upgradeStars, let fromId, let peer, let savedId, let prepaidUpgradeHash, let giftMsgId, let toId):
|
||||
case .messageActionStarGift(let flags, let gift, let message, let convertStars, let upgradeMsgId, let upgradeStars, let fromId, let peer, let savedId, let prepaidUpgradeHash, let giftMsgId, let toId, let giftNum):
|
||||
if boxed {
|
||||
buffer.appendInt32(-614898352)
|
||||
buffer.appendInt32(-366202413)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
gift.serialize(buffer, true)
|
||||
|
|
@ -1476,6 +1478,24 @@ public extension Api {
|
|||
if Int(flags) & Int(1 << 14) != 0 {serializeString(prepaidUpgradeHash!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 15) != 0 {serializeInt32(giftMsgId!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 18) != 0 {toId!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 19) != 0 {serializeInt32(giftNum!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .messageActionStarGiftPurchaseOffer(let flags, let gift, let price, let expiresAt):
|
||||
if boxed {
|
||||
buffer.appendInt32(2000845012)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
gift.serialize(buffer, true)
|
||||
price.serialize(buffer, true)
|
||||
serializeInt32(expiresAt, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .messageActionStarGiftPurchaseOfferDeclined(let flags, let gift, let price):
|
||||
if boxed {
|
||||
buffer.appendInt32(1940760427)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
gift.serialize(buffer, true)
|
||||
price.serialize(buffer, true)
|
||||
break
|
||||
case .messageActionStarGiftUnique(let flags, let gift, let canExportAt, let transferStars, let fromId, let peer, let savedId, let resaleAmount, let canTransferAt, let canResellAt, let dropOriginalDetailsStars):
|
||||
if boxed {
|
||||
|
|
@ -1678,8 +1698,12 @@ public extension Api {
|
|||
return ("messageActionSetChatWallPaper", [("flags", flags as Any), ("wallpaper", wallpaper as Any)])
|
||||
case .messageActionSetMessagesTTL(let flags, let period, let autoSettingFrom):
|
||||
return ("messageActionSetMessagesTTL", [("flags", flags as Any), ("period", period as Any), ("autoSettingFrom", autoSettingFrom as Any)])
|
||||
case .messageActionStarGift(let flags, let gift, let message, let convertStars, let upgradeMsgId, let upgradeStars, let fromId, let peer, let savedId, let prepaidUpgradeHash, let giftMsgId, let toId):
|
||||
return ("messageActionStarGift", [("flags", flags as Any), ("gift", gift as Any), ("message", message as Any), ("convertStars", convertStars as Any), ("upgradeMsgId", upgradeMsgId as Any), ("upgradeStars", upgradeStars as Any), ("fromId", fromId as Any), ("peer", peer as Any), ("savedId", savedId as Any), ("prepaidUpgradeHash", prepaidUpgradeHash as Any), ("giftMsgId", giftMsgId as Any), ("toId", toId as Any)])
|
||||
case .messageActionStarGift(let flags, let gift, let message, let convertStars, let upgradeMsgId, let upgradeStars, let fromId, let peer, let savedId, let prepaidUpgradeHash, let giftMsgId, let toId, let giftNum):
|
||||
return ("messageActionStarGift", [("flags", flags as Any), ("gift", gift as Any), ("message", message as Any), ("convertStars", convertStars as Any), ("upgradeMsgId", upgradeMsgId as Any), ("upgradeStars", upgradeStars as Any), ("fromId", fromId as Any), ("peer", peer as Any), ("savedId", savedId as Any), ("prepaidUpgradeHash", prepaidUpgradeHash as Any), ("giftMsgId", giftMsgId as Any), ("toId", toId as Any), ("giftNum", giftNum as Any)])
|
||||
case .messageActionStarGiftPurchaseOffer(let flags, let gift, let price, let expiresAt):
|
||||
return ("messageActionStarGiftPurchaseOffer", [("flags", flags as Any), ("gift", gift as Any), ("price", price as Any), ("expiresAt", expiresAt as Any)])
|
||||
case .messageActionStarGiftPurchaseOfferDeclined(let flags, let gift, let price):
|
||||
return ("messageActionStarGiftPurchaseOfferDeclined", [("flags", flags as Any), ("gift", gift as Any), ("price", price as Any)])
|
||||
case .messageActionStarGiftUnique(let flags, let gift, let canExportAt, let transferStars, let fromId, let peer, let savedId, let resaleAmount, let canTransferAt, let canResellAt, let dropOriginalDetailsStars):
|
||||
return ("messageActionStarGiftUnique", [("flags", flags as Any), ("gift", gift as Any), ("canExportAt", canExportAt as Any), ("transferStars", transferStars as Any), ("fromId", fromId as Any), ("peer", peer as Any), ("savedId", savedId as Any), ("resaleAmount", resaleAmount as Any), ("canTransferAt", canTransferAt as Any), ("canResellAt", canResellAt as Any), ("dropOriginalDetailsStars", dropOriginalDetailsStars as Any)])
|
||||
case .messageActionSuggestBirthday(let birthday):
|
||||
|
|
@ -2454,6 +2478,8 @@ public extension Api {
|
|||
if Int(_1!) & Int(1 << 18) != 0 {if let signature = reader.readInt32() {
|
||||
_12 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
} }
|
||||
var _13: Int32?
|
||||
if Int(_1!) & Int(1 << 19) != 0 {_13 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
|
|
@ -2466,8 +2492,54 @@ public extension Api {
|
|||
let _c10 = (Int(_1!) & Int(1 << 14) == 0) || _10 != nil
|
||||
let _c11 = (Int(_1!) & Int(1 << 15) == 0) || _11 != nil
|
||||
let _c12 = (Int(_1!) & Int(1 << 18) == 0) || _12 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 {
|
||||
return Api.MessageAction.messageActionStarGift(flags: _1!, gift: _2!, message: _3, convertStars: _4, upgradeMsgId: _5, upgradeStars: _6, fromId: _7, peer: _8, savedId: _9, prepaidUpgradeHash: _10, giftMsgId: _11, toId: _12)
|
||||
let _c13 = (Int(_1!) & Int(1 << 19) == 0) || _13 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 {
|
||||
return Api.MessageAction.messageActionStarGift(flags: _1!, gift: _2!, message: _3, convertStars: _4, upgradeMsgId: _5, upgradeStars: _6, fromId: _7, peer: _8, savedId: _9, prepaidUpgradeHash: _10, giftMsgId: _11, toId: _12, giftNum: _13)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageActionStarGiftPurchaseOffer(_ reader: BufferReader) -> MessageAction? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.StarGift?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StarGift
|
||||
}
|
||||
var _3: Api.StarsAmount?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StarsAmount
|
||||
}
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.MessageAction.messageActionStarGiftPurchaseOffer(flags: _1!, gift: _2!, price: _3!, expiresAt: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageActionStarGiftPurchaseOfferDeclined(_ reader: BufferReader) -> MessageAction? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.StarGift?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StarGift
|
||||
}
|
||||
var _3: Api.StarsAmount?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StarsAmount
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.MessageAction.messageActionStarGiftPurchaseOfferDeclined(flags: _1!, gift: _2!, price: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -396,6 +396,62 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum Passkey: TypeConstructorDescription {
|
||||
case passkey(flags: Int32, id: String, name: String, date: Int32, softwareEmojiId: Int64?, lastUsageDate: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .passkey(let flags, let id, let name, let date, let softwareEmojiId, let lastUsageDate):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1738457409)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(id, buffer: buffer, boxed: false)
|
||||
serializeString(name, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(softwareEmojiId!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(lastUsageDate!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .passkey(let flags, let id, let name, let date, let softwareEmojiId, let lastUsageDate):
|
||||
return ("passkey", [("flags", flags as Any), ("id", id as Any), ("name", name as Any), ("date", date as Any), ("softwareEmojiId", softwareEmojiId as Any), ("lastUsageDate", lastUsageDate as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_passkey(_ reader: BufferReader) -> Passkey? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
var _5: Int64?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt64() }
|
||||
var _6: Int32?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_6 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 1) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.Passkey.passkey(flags: _1!, id: _2!, name: _3!, date: _4!, softwareEmojiId: _5, lastUsageDate: _6)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum PasswordKdfAlgo: TypeConstructorDescription {
|
||||
case passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow(salt1: Buffer, salt2: Buffer, g: Int32, p: Buffer)
|
||||
|
|
|
|||
|
|
@ -626,13 +626,13 @@ public extension Api {
|
|||
}
|
||||
public extension Api {
|
||||
enum SavedStarGift: TypeConstructorDescription {
|
||||
case savedStarGift(flags: Int32, fromId: Api.Peer?, date: Int32, gift: Api.StarGift, message: Api.TextWithEntities?, msgId: Int32?, savedId: Int64?, convertStars: Int64?, upgradeStars: Int64?, canExportAt: Int32?, transferStars: Int64?, canTransferAt: Int32?, canResellAt: Int32?, collectionId: [Int32]?, prepaidUpgradeHash: String?, dropOriginalDetailsStars: Int64?)
|
||||
case savedStarGift(flags: Int32, fromId: Api.Peer?, date: Int32, gift: Api.StarGift, message: Api.TextWithEntities?, msgId: Int32?, savedId: Int64?, convertStars: Int64?, upgradeStars: Int64?, canExportAt: Int32?, transferStars: Int64?, canTransferAt: Int32?, canResellAt: Int32?, collectionId: [Int32]?, prepaidUpgradeHash: String?, dropOriginalDetailsStars: Int64?, giftNum: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .savedStarGift(let flags, let fromId, let date, let gift, let message, let msgId, let savedId, let convertStars, let upgradeStars, let canExportAt, let transferStars, let canTransferAt, let canResellAt, let collectionId, let prepaidUpgradeHash, let dropOriginalDetailsStars):
|
||||
case .savedStarGift(let flags, let fromId, let date, let gift, let message, let msgId, let savedId, let convertStars, let upgradeStars, let canExportAt, let transferStars, let canTransferAt, let canResellAt, let collectionId, let prepaidUpgradeHash, let dropOriginalDetailsStars, let giftNum):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1987861422)
|
||||
buffer.appendInt32(-355041186)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {fromId!.serialize(buffer, true)}
|
||||
|
|
@ -654,14 +654,15 @@ public extension Api {
|
|||
}}
|
||||
if Int(flags) & Int(1 << 16) != 0 {serializeString(prepaidUpgradeHash!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 18) != 0 {serializeInt64(dropOriginalDetailsStars!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 19) != 0 {serializeInt32(giftNum!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .savedStarGift(let flags, let fromId, let date, let gift, let message, let msgId, let savedId, let convertStars, let upgradeStars, let canExportAt, let transferStars, let canTransferAt, let canResellAt, let collectionId, let prepaidUpgradeHash, let dropOriginalDetailsStars):
|
||||
return ("savedStarGift", [("flags", flags as Any), ("fromId", fromId as Any), ("date", date as Any), ("gift", gift as Any), ("message", message as Any), ("msgId", msgId as Any), ("savedId", savedId as Any), ("convertStars", convertStars as Any), ("upgradeStars", upgradeStars as Any), ("canExportAt", canExportAt as Any), ("transferStars", transferStars as Any), ("canTransferAt", canTransferAt as Any), ("canResellAt", canResellAt as Any), ("collectionId", collectionId as Any), ("prepaidUpgradeHash", prepaidUpgradeHash as Any), ("dropOriginalDetailsStars", dropOriginalDetailsStars as Any)])
|
||||
case .savedStarGift(let flags, let fromId, let date, let gift, let message, let msgId, let savedId, let convertStars, let upgradeStars, let canExportAt, let transferStars, let canTransferAt, let canResellAt, let collectionId, let prepaidUpgradeHash, let dropOriginalDetailsStars, let giftNum):
|
||||
return ("savedStarGift", [("flags", flags as Any), ("fromId", fromId as Any), ("date", date as Any), ("gift", gift as Any), ("message", message as Any), ("msgId", msgId as Any), ("savedId", savedId as Any), ("convertStars", convertStars as Any), ("upgradeStars", upgradeStars as Any), ("canExportAt", canExportAt as Any), ("transferStars", transferStars as Any), ("canTransferAt", canTransferAt as Any), ("canResellAt", canResellAt as Any), ("collectionId", collectionId as Any), ("prepaidUpgradeHash", prepaidUpgradeHash as Any), ("dropOriginalDetailsStars", dropOriginalDetailsStars as Any), ("giftNum", giftNum as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -706,6 +707,8 @@ public extension Api {
|
|||
if Int(_1!) & Int(1 << 16) != 0 {_15 = parseString(reader) }
|
||||
var _16: Int64?
|
||||
if Int(_1!) & Int(1 << 18) != 0 {_16 = reader.readInt64() }
|
||||
var _17: Int32?
|
||||
if Int(_1!) & Int(1 << 19) != 0 {_17 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 1) == 0) || _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
|
|
@ -722,8 +725,9 @@ public extension Api {
|
|||
let _c14 = (Int(_1!) & Int(1 << 15) == 0) || _14 != nil
|
||||
let _c15 = (Int(_1!) & Int(1 << 16) == 0) || _15 != nil
|
||||
let _c16 = (Int(_1!) & Int(1 << 18) == 0) || _16 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 {
|
||||
return Api.SavedStarGift.savedStarGift(flags: _1!, fromId: _2, date: _3!, gift: _4!, message: _5, msgId: _6, savedId: _7, convertStars: _8, upgradeStars: _9, canExportAt: _10, transferStars: _11, canTransferAt: _12, canResellAt: _13, collectionId: _14, prepaidUpgradeHash: _15, dropOriginalDetailsStars: _16)
|
||||
let _c17 = (Int(_1!) & Int(1 << 19) == 0) || _17 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 {
|
||||
return Api.SavedStarGift.savedStarGift(flags: _1!, fromId: _2, date: _3!, gift: _4!, message: _5, msgId: _6, savedId: _7, convertStars: _8, upgradeStars: _9, canExportAt: _10, transferStars: _11, canTransferAt: _12, canResellAt: _13, collectionId: _14, prepaidUpgradeHash: _15, dropOriginalDetailsStars: _16, giftNum: _17)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -288,14 +288,14 @@ public extension Api {
|
|||
}
|
||||
public extension Api {
|
||||
enum StarGift: TypeConstructorDescription {
|
||||
case starGift(flags: Int32, id: Int64, sticker: Api.Document, stars: Int64, availabilityRemains: Int32?, availabilityTotal: Int32?, availabilityResale: Int64?, convertStars: Int64, firstSaleDate: Int32?, lastSaleDate: Int32?, upgradeStars: Int64?, resellMinStars: Int64?, title: String?, releasedBy: Api.Peer?, perUserTotal: Int32?, perUserRemains: Int32?, lockedUntilDate: Int32?, auctionSlug: String?, giftsPerRound: Int32?)
|
||||
case starGiftUnique(flags: Int32, id: Int64, giftId: Int64, title: String, slug: String, num: Int32, ownerId: Api.Peer?, ownerName: String?, ownerAddress: String?, attributes: [Api.StarGiftAttribute], availabilityIssued: Int32, availabilityTotal: Int32, giftAddress: String?, resellAmount: [Api.StarsAmount]?, releasedBy: Api.Peer?, valueAmount: Int64?, valueCurrency: String?, themePeer: Api.Peer?, peerColor: Api.PeerColor?, hostId: Api.Peer?)
|
||||
case starGift(flags: Int32, id: Int64, sticker: Api.Document, stars: Int64, availabilityRemains: Int32?, availabilityTotal: Int32?, availabilityResale: Int64?, convertStars: Int64, firstSaleDate: Int32?, lastSaleDate: Int32?, upgradeStars: Int64?, resellMinStars: Int64?, title: String?, releasedBy: Api.Peer?, perUserTotal: Int32?, perUserRemains: Int32?, lockedUntilDate: Int32?, auctionSlug: String?, giftsPerRound: Int32?, auctionStartDate: Int32?, upgradeVariants: Int32?, background: Api.StarGiftBackground?)
|
||||
case starGiftUnique(flags: Int32, id: Int64, giftId: Int64, title: String, slug: String, num: Int32, ownerId: Api.Peer?, ownerName: String?, ownerAddress: String?, attributes: [Api.StarGiftAttribute], availabilityIssued: Int32, availabilityTotal: Int32, giftAddress: String?, resellAmount: [Api.StarsAmount]?, releasedBy: Api.Peer?, valueAmount: Int64?, valueCurrency: String?, valueUsdAmount: Int64?, themePeer: Api.Peer?, peerColor: Api.PeerColor?, hostId: Api.Peer?, offerMinStars: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let availabilityResale, let convertStars, let firstSaleDate, let lastSaleDate, let upgradeStars, let resellMinStars, let title, let releasedBy, let perUserTotal, let perUserRemains, let lockedUntilDate, let auctionSlug, let giftsPerRound):
|
||||
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let availabilityResale, let convertStars, let firstSaleDate, let lastSaleDate, let upgradeStars, let resellMinStars, let title, let releasedBy, let perUserTotal, let perUserRemains, let lockedUntilDate, let auctionSlug, let giftsPerRound, let auctionStartDate, let upgradeVariants, let background):
|
||||
if boxed {
|
||||
buffer.appendInt32(463097215)
|
||||
buffer.appendInt32(825922887)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
|
|
@ -316,10 +316,13 @@ public extension Api {
|
|||
if Int(flags) & Int(1 << 9) != 0 {serializeInt32(lockedUntilDate!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 11) != 0 {serializeString(auctionSlug!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(giftsPerRound!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(auctionStartDate!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 12) != 0 {serializeInt32(upgradeVariants!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 13) != 0 {background!.serialize(buffer, true)}
|
||||
break
|
||||
case .starGiftUnique(let flags, let id, let giftId, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellAmount, let releasedBy, let valueAmount, let valueCurrency, let themePeer, let peerColor, let hostId):
|
||||
case .starGiftUnique(let flags, let id, let giftId, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellAmount, let releasedBy, let valueAmount, let valueCurrency, let valueUsdAmount, let themePeer, let peerColor, let hostId, let offerMinStars):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1329630181)
|
||||
buffer.appendInt32(1453155529)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
|
|
@ -346,19 +349,21 @@ public extension Api {
|
|||
if Int(flags) & Int(1 << 5) != 0 {releasedBy!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 8) != 0 {serializeInt64(valueAmount!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 8) != 0 {serializeString(valueCurrency!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 8) != 0 {serializeInt64(valueUsdAmount!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 10) != 0 {themePeer!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 11) != 0 {peerColor!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 12) != 0 {hostId!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 13) != 0 {serializeInt32(offerMinStars!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let availabilityResale, let convertStars, let firstSaleDate, let lastSaleDate, let upgradeStars, let resellMinStars, let title, let releasedBy, let perUserTotal, let perUserRemains, let lockedUntilDate, let auctionSlug, let giftsPerRound):
|
||||
return ("starGift", [("flags", flags as Any), ("id", id as Any), ("sticker", sticker as Any), ("stars", stars as Any), ("availabilityRemains", availabilityRemains as Any), ("availabilityTotal", availabilityTotal as Any), ("availabilityResale", availabilityResale as Any), ("convertStars", convertStars as Any), ("firstSaleDate", firstSaleDate as Any), ("lastSaleDate", lastSaleDate as Any), ("upgradeStars", upgradeStars as Any), ("resellMinStars", resellMinStars as Any), ("title", title as Any), ("releasedBy", releasedBy as Any), ("perUserTotal", perUserTotal as Any), ("perUserRemains", perUserRemains as Any), ("lockedUntilDate", lockedUntilDate as Any), ("auctionSlug", auctionSlug as Any), ("giftsPerRound", giftsPerRound as Any)])
|
||||
case .starGiftUnique(let flags, let id, let giftId, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellAmount, let releasedBy, let valueAmount, let valueCurrency, let themePeer, let peerColor, let hostId):
|
||||
return ("starGiftUnique", [("flags", flags as Any), ("id", id as Any), ("giftId", giftId as Any), ("title", title as Any), ("slug", slug as Any), ("num", num as Any), ("ownerId", ownerId as Any), ("ownerName", ownerName as Any), ("ownerAddress", ownerAddress as Any), ("attributes", attributes as Any), ("availabilityIssued", availabilityIssued as Any), ("availabilityTotal", availabilityTotal as Any), ("giftAddress", giftAddress as Any), ("resellAmount", resellAmount as Any), ("releasedBy", releasedBy as Any), ("valueAmount", valueAmount as Any), ("valueCurrency", valueCurrency as Any), ("themePeer", themePeer as Any), ("peerColor", peerColor as Any), ("hostId", hostId as Any)])
|
||||
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let availabilityResale, let convertStars, let firstSaleDate, let lastSaleDate, let upgradeStars, let resellMinStars, let title, let releasedBy, let perUserTotal, let perUserRemains, let lockedUntilDate, let auctionSlug, let giftsPerRound, let auctionStartDate, let upgradeVariants, let background):
|
||||
return ("starGift", [("flags", flags as Any), ("id", id as Any), ("sticker", sticker as Any), ("stars", stars as Any), ("availabilityRemains", availabilityRemains as Any), ("availabilityTotal", availabilityTotal as Any), ("availabilityResale", availabilityResale as Any), ("convertStars", convertStars as Any), ("firstSaleDate", firstSaleDate as Any), ("lastSaleDate", lastSaleDate as Any), ("upgradeStars", upgradeStars as Any), ("resellMinStars", resellMinStars as Any), ("title", title as Any), ("releasedBy", releasedBy as Any), ("perUserTotal", perUserTotal as Any), ("perUserRemains", perUserRemains as Any), ("lockedUntilDate", lockedUntilDate as Any), ("auctionSlug", auctionSlug as Any), ("giftsPerRound", giftsPerRound as Any), ("auctionStartDate", auctionStartDate as Any), ("upgradeVariants", upgradeVariants as Any), ("background", background as Any)])
|
||||
case .starGiftUnique(let flags, let id, let giftId, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellAmount, let releasedBy, let valueAmount, let valueCurrency, let valueUsdAmount, let themePeer, let peerColor, let hostId, let offerMinStars):
|
||||
return ("starGiftUnique", [("flags", flags as Any), ("id", id as Any), ("giftId", giftId as Any), ("title", title as Any), ("slug", slug as Any), ("num", num as Any), ("ownerId", ownerId as Any), ("ownerName", ownerName as Any), ("ownerAddress", ownerAddress as Any), ("attributes", attributes as Any), ("availabilityIssued", availabilityIssued as Any), ("availabilityTotal", availabilityTotal as Any), ("giftAddress", giftAddress as Any), ("resellAmount", resellAmount as Any), ("releasedBy", releasedBy as Any), ("valueAmount", valueAmount as Any), ("valueCurrency", valueCurrency as Any), ("valueUsdAmount", valueUsdAmount as Any), ("themePeer", themePeer as Any), ("peerColor", peerColor as Any), ("hostId", hostId as Any), ("offerMinStars", offerMinStars as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -405,6 +410,14 @@ public extension Api {
|
|||
if Int(_1!) & Int(1 << 11) != 0 {_18 = parseString(reader) }
|
||||
var _19: Int32?
|
||||
if Int(_1!) & Int(1 << 11) != 0 {_19 = reader.readInt32() }
|
||||
var _20: Int32?
|
||||
if Int(_1!) & Int(1 << 11) != 0 {_20 = reader.readInt32() }
|
||||
var _21: Int32?
|
||||
if Int(_1!) & Int(1 << 12) != 0 {_21 = reader.readInt32() }
|
||||
var _22: Api.StarGiftBackground?
|
||||
if Int(_1!) & Int(1 << 13) != 0 {if let signature = reader.readInt32() {
|
||||
_22 = Api.parse(reader, signature: signature) as? Api.StarGiftBackground
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
|
|
@ -424,8 +437,11 @@ public extension Api {
|
|||
let _c17 = (Int(_1!) & Int(1 << 9) == 0) || _17 != nil
|
||||
let _c18 = (Int(_1!) & Int(1 << 11) == 0) || _18 != nil
|
||||
let _c19 = (Int(_1!) & Int(1 << 11) == 0) || _19 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 {
|
||||
return Api.StarGift.starGift(flags: _1!, id: _2!, sticker: _3!, stars: _4!, availabilityRemains: _5, availabilityTotal: _6, availabilityResale: _7, convertStars: _8!, firstSaleDate: _9, lastSaleDate: _10, upgradeStars: _11, resellMinStars: _12, title: _13, releasedBy: _14, perUserTotal: _15, perUserRemains: _16, lockedUntilDate: _17, auctionSlug: _18, giftsPerRound: _19)
|
||||
let _c20 = (Int(_1!) & Int(1 << 11) == 0) || _20 != nil
|
||||
let _c21 = (Int(_1!) & Int(1 << 12) == 0) || _21 != nil
|
||||
let _c22 = (Int(_1!) & Int(1 << 13) == 0) || _22 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 {
|
||||
return Api.StarGift.starGift(flags: _1!, id: _2!, sticker: _3!, stars: _4!, availabilityRemains: _5, availabilityTotal: _6, availabilityResale: _7, convertStars: _8!, firstSaleDate: _9, lastSaleDate: _10, upgradeStars: _11, resellMinStars: _12, title: _13, releasedBy: _14, perUserTotal: _15, perUserRemains: _16, lockedUntilDate: _17, auctionSlug: _18, giftsPerRound: _19, auctionStartDate: _20, upgradeVariants: _21, background: _22)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
@ -474,18 +490,22 @@ public extension Api {
|
|||
if Int(_1!) & Int(1 << 8) != 0 {_16 = reader.readInt64() }
|
||||
var _17: String?
|
||||
if Int(_1!) & Int(1 << 8) != 0 {_17 = parseString(reader) }
|
||||
var _18: Api.Peer?
|
||||
var _18: Int64?
|
||||
if Int(_1!) & Int(1 << 8) != 0 {_18 = reader.readInt64() }
|
||||
var _19: Api.Peer?
|
||||
if Int(_1!) & Int(1 << 10) != 0 {if let signature = reader.readInt32() {
|
||||
_18 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
_19 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
} }
|
||||
var _19: Api.PeerColor?
|
||||
var _20: Api.PeerColor?
|
||||
if Int(_1!) & Int(1 << 11) != 0 {if let signature = reader.readInt32() {
|
||||
_19 = Api.parse(reader, signature: signature) as? Api.PeerColor
|
||||
_20 = Api.parse(reader, signature: signature) as? Api.PeerColor
|
||||
} }
|
||||
var _20: Api.Peer?
|
||||
var _21: Api.Peer?
|
||||
if Int(_1!) & Int(1 << 12) != 0 {if let signature = reader.readInt32() {
|
||||
_20 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
_21 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
} }
|
||||
var _22: Int32?
|
||||
if Int(_1!) & Int(1 << 13) != 0 {_22 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
|
|
@ -503,11 +523,13 @@ public extension Api {
|
|||
let _c15 = (Int(_1!) & Int(1 << 5) == 0) || _15 != nil
|
||||
let _c16 = (Int(_1!) & Int(1 << 8) == 0) || _16 != nil
|
||||
let _c17 = (Int(_1!) & Int(1 << 8) == 0) || _17 != nil
|
||||
let _c18 = (Int(_1!) & Int(1 << 10) == 0) || _18 != nil
|
||||
let _c19 = (Int(_1!) & Int(1 << 11) == 0) || _19 != nil
|
||||
let _c20 = (Int(_1!) & Int(1 << 12) == 0) || _20 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 {
|
||||
return Api.StarGift.starGiftUnique(flags: _1!, id: _2!, giftId: _3!, title: _4!, slug: _5!, num: _6!, ownerId: _7, ownerName: _8, ownerAddress: _9, attributes: _10!, availabilityIssued: _11!, availabilityTotal: _12!, giftAddress: _13, resellAmount: _14, releasedBy: _15, valueAmount: _16, valueCurrency: _17, themePeer: _18, peerColor: _19, hostId: _20)
|
||||
let _c18 = (Int(_1!) & Int(1 << 8) == 0) || _18 != nil
|
||||
let _c19 = (Int(_1!) & Int(1 << 10) == 0) || _19 != nil
|
||||
let _c20 = (Int(_1!) & Int(1 << 11) == 0) || _20 != nil
|
||||
let _c21 = (Int(_1!) & Int(1 << 12) == 0) || _21 != nil
|
||||
let _c22 = (Int(_1!) & Int(1 << 13) == 0) || _22 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 {
|
||||
return Api.StarGift.starGiftUnique(flags: _1!, id: _2!, giftId: _3!, title: _4!, slug: _5!, num: _6!, ownerId: _7, ownerName: _8, ownerAddress: _9, attributes: _10!, availabilityIssued: _11!, availabilityTotal: _12!, giftAddress: _13, resellAmount: _14, releasedBy: _15, valueAmount: _16, valueCurrency: _17, valueUsdAmount: _18, themePeer: _19, peerColor: _20, hostId: _21, offerMinStars: _22)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
@ -848,13 +870,13 @@ public extension Api {
|
|||
}
|
||||
public extension Api {
|
||||
enum StarGiftAuctionAcquiredGift: TypeConstructorDescription {
|
||||
case starGiftAuctionAcquiredGift(flags: Int32, peer: Api.Peer, date: Int32, bidAmount: Int64, round: Int32, pos: Int32, message: Api.TextWithEntities?)
|
||||
case starGiftAuctionAcquiredGift(flags: Int32, peer: Api.Peer, date: Int32, bidAmount: Int64, round: Int32, pos: Int32, message: Api.TextWithEntities?, giftNum: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starGiftAuctionAcquiredGift(let flags, let peer, let date, let bidAmount, let round, let pos, let message):
|
||||
case .starGiftAuctionAcquiredGift(let flags, let peer, let date, let bidAmount, let round, let pos, let message, let giftNum):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1419714037)
|
||||
buffer.appendInt32(1118831432)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
peer.serialize(buffer, true)
|
||||
|
|
@ -863,14 +885,15 @@ public extension Api {
|
|||
serializeInt32(round, buffer: buffer, boxed: false)
|
||||
serializeInt32(pos, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {message!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(giftNum!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starGiftAuctionAcquiredGift(let flags, let peer, let date, let bidAmount, let round, let pos, let message):
|
||||
return ("starGiftAuctionAcquiredGift", [("flags", flags as Any), ("peer", peer as Any), ("date", date as Any), ("bidAmount", bidAmount as Any), ("round", round as Any), ("pos", pos as Any), ("message", message as Any)])
|
||||
case .starGiftAuctionAcquiredGift(let flags, let peer, let date, let bidAmount, let round, let pos, let message, let giftNum):
|
||||
return ("starGiftAuctionAcquiredGift", [("flags", flags as Any), ("peer", peer as Any), ("date", date as Any), ("bidAmount", bidAmount as Any), ("round", round as Any), ("pos", pos as Any), ("message", message as Any), ("giftNum", giftNum as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -893,6 +916,8 @@ public extension Api {
|
|||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.TextWithEntities
|
||||
} }
|
||||
var _8: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_8 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
|
|
@ -900,8 +925,81 @@ public extension Api {
|
|||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 1) == 0) || _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.StarGiftAuctionAcquiredGift.starGiftAuctionAcquiredGift(flags: _1!, peer: _2!, date: _3!, bidAmount: _4!, round: _5!, pos: _6!, message: _7)
|
||||
let _c8 = (Int(_1!) & Int(1 << 2) == 0) || _8 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
|
||||
return Api.StarGiftAuctionAcquiredGift.starGiftAuctionAcquiredGift(flags: _1!, peer: _2!, date: _3!, bidAmount: _4!, round: _5!, pos: _6!, message: _7, giftNum: _8)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarGiftAuctionRound: TypeConstructorDescription {
|
||||
case starGiftAuctionRound(num: Int32, duration: Int32)
|
||||
case starGiftAuctionRoundExtendable(num: Int32, duration: Int32, extendTop: Int32, extendWindow: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starGiftAuctionRound(let num, let duration):
|
||||
if boxed {
|
||||
buffer.appendInt32(984483112)
|
||||
}
|
||||
serializeInt32(num, buffer: buffer, boxed: false)
|
||||
serializeInt32(duration, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .starGiftAuctionRoundExtendable(let num, let duration, let extendTop, let extendWindow):
|
||||
if boxed {
|
||||
buffer.appendInt32(178266597)
|
||||
}
|
||||
serializeInt32(num, buffer: buffer, boxed: false)
|
||||
serializeInt32(duration, buffer: buffer, boxed: false)
|
||||
serializeInt32(extendTop, buffer: buffer, boxed: false)
|
||||
serializeInt32(extendWindow, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starGiftAuctionRound(let num, let duration):
|
||||
return ("starGiftAuctionRound", [("num", num as Any), ("duration", duration as Any)])
|
||||
case .starGiftAuctionRoundExtendable(let num, let duration, let extendTop, let extendWindow):
|
||||
return ("starGiftAuctionRoundExtendable", [("num", num as Any), ("duration", duration as Any), ("extendTop", extendTop as Any), ("extendWindow", extendWindow as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starGiftAuctionRound(_ reader: BufferReader) -> StarGiftAuctionRound? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.StarGiftAuctionRound.starGiftAuctionRound(num: _1!, duration: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_starGiftAuctionRoundExtendable(_ reader: BufferReader) -> StarGiftAuctionRound? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.StarGiftAuctionRound.starGiftAuctionRoundExtendable(num: _1!, duration: _2!, extendTop: _3!, extendWindow: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
@ -912,15 +1010,15 @@ public extension Api {
|
|||
}
|
||||
public extension Api {
|
||||
enum StarGiftAuctionState: TypeConstructorDescription {
|
||||
case starGiftAuctionState(version: Int32, startDate: Int32, endDate: Int32, minBidAmount: Int64, bidLevels: [Api.AuctionBidLevel], topBidders: [Int64], nextRoundAt: Int32, giftsLeft: Int32, currentRound: Int32, totalRounds: Int32)
|
||||
case starGiftAuctionStateFinished(startDate: Int32, endDate: Int32, averagePrice: Int64)
|
||||
case starGiftAuctionState(version: Int32, startDate: Int32, endDate: Int32, minBidAmount: Int64, bidLevels: [Api.AuctionBidLevel], topBidders: [Int64], nextRoundAt: Int32, lastGiftNum: Int32, giftsLeft: Int32, currentRound: Int32, totalRounds: Int32, rounds: [Api.StarGiftAuctionRound])
|
||||
case starGiftAuctionStateFinished(flags: Int32, startDate: Int32, endDate: Int32, averagePrice: Int64, listedCount: Int32?, fragmentListedCount: Int32?, fragmentListedUrl: String?)
|
||||
case starGiftAuctionStateNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starGiftAuctionState(let version, let startDate, let endDate, let minBidAmount, let bidLevels, let topBidders, let nextRoundAt, let giftsLeft, let currentRound, let totalRounds):
|
||||
case .starGiftAuctionState(let version, let startDate, let endDate, let minBidAmount, let bidLevels, let topBidders, let nextRoundAt, let lastGiftNum, let giftsLeft, let currentRound, let totalRounds, let rounds):
|
||||
if boxed {
|
||||
buffer.appendInt32(1571835723)
|
||||
buffer.appendInt32(1998212710)
|
||||
}
|
||||
serializeInt32(version, buffer: buffer, boxed: false)
|
||||
serializeInt32(startDate, buffer: buffer, boxed: false)
|
||||
|
|
@ -937,17 +1035,27 @@ public extension Api {
|
|||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
serializeInt32(nextRoundAt, buffer: buffer, boxed: false)
|
||||
serializeInt32(lastGiftNum, buffer: buffer, boxed: false)
|
||||
serializeInt32(giftsLeft, buffer: buffer, boxed: false)
|
||||
serializeInt32(currentRound, buffer: buffer, boxed: false)
|
||||
serializeInt32(totalRounds, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .starGiftAuctionStateFinished(let startDate, let endDate, let averagePrice):
|
||||
if boxed {
|
||||
buffer.appendInt32(2107014202)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(rounds.count))
|
||||
for item in rounds {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .starGiftAuctionStateFinished(let flags, let startDate, let endDate, let averagePrice, let listedCount, let fragmentListedCount, let fragmentListedUrl):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1758614593)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(startDate, buffer: buffer, boxed: false)
|
||||
serializeInt32(endDate, buffer: buffer, boxed: false)
|
||||
serializeInt64(averagePrice, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(listedCount!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(fragmentListedCount!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(fragmentListedUrl!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .starGiftAuctionStateNotModified:
|
||||
if boxed {
|
||||
|
|
@ -960,10 +1068,10 @@ public extension Api {
|
|||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starGiftAuctionState(let version, let startDate, let endDate, let minBidAmount, let bidLevels, let topBidders, let nextRoundAt, let giftsLeft, let currentRound, let totalRounds):
|
||||
return ("starGiftAuctionState", [("version", version as Any), ("startDate", startDate as Any), ("endDate", endDate as Any), ("minBidAmount", minBidAmount as Any), ("bidLevels", bidLevels as Any), ("topBidders", topBidders as Any), ("nextRoundAt", nextRoundAt as Any), ("giftsLeft", giftsLeft as Any), ("currentRound", currentRound as Any), ("totalRounds", totalRounds as Any)])
|
||||
case .starGiftAuctionStateFinished(let startDate, let endDate, let averagePrice):
|
||||
return ("starGiftAuctionStateFinished", [("startDate", startDate as Any), ("endDate", endDate as Any), ("averagePrice", averagePrice as Any)])
|
||||
case .starGiftAuctionState(let version, let startDate, let endDate, let minBidAmount, let bidLevels, let topBidders, let nextRoundAt, let lastGiftNum, let giftsLeft, let currentRound, let totalRounds, let rounds):
|
||||
return ("starGiftAuctionState", [("version", version as Any), ("startDate", startDate as Any), ("endDate", endDate as Any), ("minBidAmount", minBidAmount as Any), ("bidLevels", bidLevels as Any), ("topBidders", topBidders as Any), ("nextRoundAt", nextRoundAt as Any), ("lastGiftNum", lastGiftNum as Any), ("giftsLeft", giftsLeft as Any), ("currentRound", currentRound as Any), ("totalRounds", totalRounds as Any), ("rounds", rounds as Any)])
|
||||
case .starGiftAuctionStateFinished(let flags, let startDate, let endDate, let averagePrice, let listedCount, let fragmentListedCount, let fragmentListedUrl):
|
||||
return ("starGiftAuctionStateFinished", [("flags", flags as Any), ("startDate", startDate as Any), ("endDate", endDate as Any), ("averagePrice", averagePrice as Any), ("listedCount", listedCount as Any), ("fragmentListedCount", fragmentListedCount as Any), ("fragmentListedUrl", fragmentListedUrl as Any)])
|
||||
case .starGiftAuctionStateNotModified:
|
||||
return ("starGiftAuctionStateNotModified", [])
|
||||
}
|
||||
|
|
@ -994,6 +1102,12 @@ public extension Api {
|
|||
_9 = reader.readInt32()
|
||||
var _10: Int32?
|
||||
_10 = reader.readInt32()
|
||||
var _11: Int32?
|
||||
_11 = reader.readInt32()
|
||||
var _12: [Api.StarGiftAuctionRound]?
|
||||
if let _ = reader.readInt32() {
|
||||
_12 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarGiftAuctionRound.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
|
|
@ -1004,8 +1118,10 @@ public extension Api {
|
|||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
let _c10 = _10 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
|
||||
return Api.StarGiftAuctionState.starGiftAuctionState(version: _1!, startDate: _2!, endDate: _3!, minBidAmount: _4!, bidLevels: _5!, topBidders: _6!, nextRoundAt: _7!, giftsLeft: _8!, currentRound: _9!, totalRounds: _10!)
|
||||
let _c11 = _11 != nil
|
||||
let _c12 = _12 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 {
|
||||
return Api.StarGiftAuctionState.starGiftAuctionState(version: _1!, startDate: _2!, endDate: _3!, minBidAmount: _4!, bidLevels: _5!, topBidders: _6!, nextRoundAt: _7!, lastGiftNum: _8!, giftsLeft: _9!, currentRound: _10!, totalRounds: _11!, rounds: _12!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
@ -1016,13 +1132,25 @@ public extension Api {
|
|||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int64?
|
||||
_4 = reader.readInt64()
|
||||
var _5: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt32() }
|
||||
var _6: Int32?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_6 = reader.readInt32() }
|
||||
var _7: String?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_7 = parseString(reader) }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.StarGiftAuctionState.starGiftAuctionStateFinished(startDate: _1!, endDate: _2!, averagePrice: _3!)
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 1) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 1) == 0) || _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.StarGiftAuctionState.starGiftAuctionStateFinished(flags: _1!, startDate: _2!, endDate: _3!, averagePrice: _4!, listedCount: _5, fragmentListedCount: _6, fragmentListedUrl: _7)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
@ -1092,6 +1220,50 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarGiftBackground: TypeConstructorDescription {
|
||||
case starGiftBackground(centerColor: Int32, edgeColor: Int32, textColor: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starGiftBackground(let centerColor, let edgeColor, let textColor):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1342872680)
|
||||
}
|
||||
serializeInt32(centerColor, buffer: buffer, boxed: false)
|
||||
serializeInt32(edgeColor, buffer: buffer, boxed: false)
|
||||
serializeInt32(textColor, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starGiftBackground(let centerColor, let edgeColor, let textColor):
|
||||
return ("starGiftBackground", [("centerColor", centerColor as Any), ("edgeColor", edgeColor as Any), ("textColor", textColor as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starGiftBackground(_ reader: BufferReader) -> StarGiftBackground? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.StarGiftBackground.starGiftBackground(centerColor: _1!, edgeColor: _2!, textColor: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarGiftCollection: TypeConstructorDescription {
|
||||
case starGiftCollection(flags: Int32, collectionId: Int32, title: String, icon: Api.Document?, giftsCount: Int32, hash: Int64)
|
||||
|
|
@ -1470,187 +1642,3 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarsRating: TypeConstructorDescription {
|
||||
case starsRating(flags: Int32, level: Int32, currentLevelStars: Int64, stars: Int64, nextLevelStars: Int64?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsRating(let flags, let level, let currentLevelStars, let stars, let nextLevelStars):
|
||||
if boxed {
|
||||
buffer.appendInt32(453922567)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(level, buffer: buffer, boxed: false)
|
||||
serializeInt64(currentLevelStars, buffer: buffer, boxed: false)
|
||||
serializeInt64(stars, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(nextLevelStars!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsRating(let flags, let level, let currentLevelStars, let stars, let nextLevelStars):
|
||||
return ("starsRating", [("flags", flags as Any), ("level", level as Any), ("currentLevelStars", currentLevelStars as Any), ("stars", stars as Any), ("nextLevelStars", nextLevelStars as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsRating(_ reader: BufferReader) -> StarsRating? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
var _4: Int64?
|
||||
_4 = reader.readInt64()
|
||||
var _5: Int64?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt64() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.StarsRating.starsRating(flags: _1!, level: _2!, currentLevelStars: _3!, stars: _4!, nextLevelStars: _5)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarsRevenueStatus: TypeConstructorDescription {
|
||||
case starsRevenueStatus(flags: Int32, currentBalance: Api.StarsAmount, availableBalance: Api.StarsAmount, overallRevenue: Api.StarsAmount, nextWithdrawalAt: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsRevenueStatus(let flags, let currentBalance, let availableBalance, let overallRevenue, let nextWithdrawalAt):
|
||||
if boxed {
|
||||
buffer.appendInt32(-21080943)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
currentBalance.serialize(buffer, true)
|
||||
availableBalance.serialize(buffer, true)
|
||||
overallRevenue.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(nextWithdrawalAt!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsRevenueStatus(let flags, let currentBalance, let availableBalance, let overallRevenue, let nextWithdrawalAt):
|
||||
return ("starsRevenueStatus", [("flags", flags as Any), ("currentBalance", currentBalance as Any), ("availableBalance", availableBalance as Any), ("overallRevenue", overallRevenue as Any), ("nextWithdrawalAt", nextWithdrawalAt as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsRevenueStatus(_ reader: BufferReader) -> StarsRevenueStatus? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.StarsAmount?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StarsAmount
|
||||
}
|
||||
var _3: Api.StarsAmount?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StarsAmount
|
||||
}
|
||||
var _4: Api.StarsAmount?
|
||||
if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.StarsAmount
|
||||
}
|
||||
var _5: Int32?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_5 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.StarsRevenueStatus.starsRevenueStatus(flags: _1!, currentBalance: _2!, availableBalance: _3!, overallRevenue: _4!, nextWithdrawalAt: _5)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarsSubscription: TypeConstructorDescription {
|
||||
case starsSubscription(flags: Int32, id: String, peer: Api.Peer, untilDate: Int32, pricing: Api.StarsSubscriptionPricing, chatInviteHash: String?, title: String?, photo: Api.WebDocument?, invoiceSlug: String?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsSubscription(let flags, let id, let peer, let untilDate, let pricing, let chatInviteHash, let title, let photo, let invoiceSlug):
|
||||
if boxed {
|
||||
buffer.appendInt32(779004698)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(id, buffer: buffer, boxed: false)
|
||||
peer.serialize(buffer, true)
|
||||
serializeInt32(untilDate, buffer: buffer, boxed: false)
|
||||
pricing.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeString(chatInviteHash!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 5) != 0 {photo!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 6) != 0 {serializeString(invoiceSlug!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsSubscription(let flags, let id, let peer, let untilDate, let pricing, let chatInviteHash, let title, let photo, let invoiceSlug):
|
||||
return ("starsSubscription", [("flags", flags as Any), ("id", id as Any), ("peer", peer as Any), ("untilDate", untilDate as Any), ("pricing", pricing as Any), ("chatInviteHash", chatInviteHash as Any), ("title", title as Any), ("photo", photo as Any), ("invoiceSlug", invoiceSlug as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsSubscription(_ reader: BufferReader) -> StarsSubscription? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
var _5: Api.StarsSubscriptionPricing?
|
||||
if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.StarsSubscriptionPricing
|
||||
}
|
||||
var _6: String?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_6 = parseString(reader) }
|
||||
var _7: String?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_7 = parseString(reader) }
|
||||
var _8: Api.WebDocument?
|
||||
if Int(_1!) & Int(1 << 5) != 0 {if let signature = reader.readInt32() {
|
||||
_8 = Api.parse(reader, signature: signature) as? Api.WebDocument
|
||||
} }
|
||||
var _9: String?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {_9 = parseString(reader) }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 4) == 0) || _7 != nil
|
||||
let _c8 = (Int(_1!) & Int(1 << 5) == 0) || _8 != nil
|
||||
let _c9 = (Int(_1!) & Int(1 << 6) == 0) || _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.StarsSubscription.starsSubscription(flags: _1!, id: _2!, peer: _3!, untilDate: _4!, pricing: _5!, chatInviteHash: _6, title: _7, photo: _8, invoiceSlug: _9)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,187 @@
|
|||
public extension Api {
|
||||
enum StarsRating: TypeConstructorDescription {
|
||||
case starsRating(flags: Int32, level: Int32, currentLevelStars: Int64, stars: Int64, nextLevelStars: Int64?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsRating(let flags, let level, let currentLevelStars, let stars, let nextLevelStars):
|
||||
if boxed {
|
||||
buffer.appendInt32(453922567)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(level, buffer: buffer, boxed: false)
|
||||
serializeInt64(currentLevelStars, buffer: buffer, boxed: false)
|
||||
serializeInt64(stars, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(nextLevelStars!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsRating(let flags, let level, let currentLevelStars, let stars, let nextLevelStars):
|
||||
return ("starsRating", [("flags", flags as Any), ("level", level as Any), ("currentLevelStars", currentLevelStars as Any), ("stars", stars as Any), ("nextLevelStars", nextLevelStars as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsRating(_ reader: BufferReader) -> StarsRating? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
var _4: Int64?
|
||||
_4 = reader.readInt64()
|
||||
var _5: Int64?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt64() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.StarsRating.starsRating(flags: _1!, level: _2!, currentLevelStars: _3!, stars: _4!, nextLevelStars: _5)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarsRevenueStatus: TypeConstructorDescription {
|
||||
case starsRevenueStatus(flags: Int32, currentBalance: Api.StarsAmount, availableBalance: Api.StarsAmount, overallRevenue: Api.StarsAmount, nextWithdrawalAt: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsRevenueStatus(let flags, let currentBalance, let availableBalance, let overallRevenue, let nextWithdrawalAt):
|
||||
if boxed {
|
||||
buffer.appendInt32(-21080943)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
currentBalance.serialize(buffer, true)
|
||||
availableBalance.serialize(buffer, true)
|
||||
overallRevenue.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(nextWithdrawalAt!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsRevenueStatus(let flags, let currentBalance, let availableBalance, let overallRevenue, let nextWithdrawalAt):
|
||||
return ("starsRevenueStatus", [("flags", flags as Any), ("currentBalance", currentBalance as Any), ("availableBalance", availableBalance as Any), ("overallRevenue", overallRevenue as Any), ("nextWithdrawalAt", nextWithdrawalAt as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsRevenueStatus(_ reader: BufferReader) -> StarsRevenueStatus? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.StarsAmount?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StarsAmount
|
||||
}
|
||||
var _3: Api.StarsAmount?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StarsAmount
|
||||
}
|
||||
var _4: Api.StarsAmount?
|
||||
if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.StarsAmount
|
||||
}
|
||||
var _5: Int32?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_5 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.StarsRevenueStatus.starsRevenueStatus(flags: _1!, currentBalance: _2!, availableBalance: _3!, overallRevenue: _4!, nextWithdrawalAt: _5)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarsSubscription: TypeConstructorDescription {
|
||||
case starsSubscription(flags: Int32, id: String, peer: Api.Peer, untilDate: Int32, pricing: Api.StarsSubscriptionPricing, chatInviteHash: String?, title: String?, photo: Api.WebDocument?, invoiceSlug: String?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsSubscription(let flags, let id, let peer, let untilDate, let pricing, let chatInviteHash, let title, let photo, let invoiceSlug):
|
||||
if boxed {
|
||||
buffer.appendInt32(779004698)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(id, buffer: buffer, boxed: false)
|
||||
peer.serialize(buffer, true)
|
||||
serializeInt32(untilDate, buffer: buffer, boxed: false)
|
||||
pricing.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeString(chatInviteHash!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 5) != 0 {photo!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 6) != 0 {serializeString(invoiceSlug!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsSubscription(let flags, let id, let peer, let untilDate, let pricing, let chatInviteHash, let title, let photo, let invoiceSlug):
|
||||
return ("starsSubscription", [("flags", flags as Any), ("id", id as Any), ("peer", peer as Any), ("untilDate", untilDate as Any), ("pricing", pricing as Any), ("chatInviteHash", chatInviteHash as Any), ("title", title as Any), ("photo", photo as Any), ("invoiceSlug", invoiceSlug as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsSubscription(_ reader: BufferReader) -> StarsSubscription? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
var _5: Api.StarsSubscriptionPricing?
|
||||
if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.StarsSubscriptionPricing
|
||||
}
|
||||
var _6: String?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_6 = parseString(reader) }
|
||||
var _7: String?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_7 = parseString(reader) }
|
||||
var _8: Api.WebDocument?
|
||||
if Int(_1!) & Int(1 << 5) != 0 {if let signature = reader.readInt32() {
|
||||
_8 = Api.parse(reader, signature: signature) as? Api.WebDocument
|
||||
} }
|
||||
var _9: String?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {_9 = parseString(reader) }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 4) == 0) || _7 != nil
|
||||
let _c8 = (Int(_1!) & Int(1 << 5) == 0) || _8 != nil
|
||||
let _c9 = (Int(_1!) & Int(1 << 6) == 0) || _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.StarsSubscription.starsSubscription(flags: _1!, id: _2!, peer: _3!, untilDate: _4!, pricing: _5!, chatInviteHash: _6, title: _7, photo: _8, invoiceSlug: _9)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarsSubscriptionPricing: TypeConstructorDescription {
|
||||
case starsSubscriptionPricing(period: Int32, amount: Int64)
|
||||
|
|
@ -1104,283 +1288,3 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StoryAlbum: TypeConstructorDescription {
|
||||
case storyAlbum(flags: Int32, albumId: Int32, title: String, iconPhoto: Api.Photo?, iconVideo: Api.Document?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyAlbum(let flags, let albumId, let title, let iconPhoto, let iconVideo):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1826262950)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(albumId, buffer: buffer, boxed: false)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {iconPhoto!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {iconVideo!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyAlbum(let flags, let albumId, let title, let iconPhoto, let iconVideo):
|
||||
return ("storyAlbum", [("flags", flags as Any), ("albumId", albumId as Any), ("title", title as Any), ("iconPhoto", iconPhoto as Any), ("iconVideo", iconVideo as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyAlbum(_ reader: BufferReader) -> StoryAlbum? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: Api.Photo?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.Photo
|
||||
} }
|
||||
var _5: Api.Document?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.Document
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.StoryAlbum.storyAlbum(flags: _1!, albumId: _2!, title: _3!, iconPhoto: _4, iconVideo: _5)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StoryFwdHeader: TypeConstructorDescription {
|
||||
case storyFwdHeader(flags: Int32, from: Api.Peer?, fromName: String?, storyId: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyFwdHeader(let flags, let from, let fromName, let storyId):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1205411504)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {from!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(fromName!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(storyId!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyFwdHeader(let flags, let from, let fromName, let storyId):
|
||||
return ("storyFwdHeader", [("flags", flags as Any), ("from", from as Any), ("fromName", fromName as Any), ("storyId", storyId as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyFwdHeader(_ reader: BufferReader) -> StoryFwdHeader? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Peer?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
} }
|
||||
var _3: String?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_3 = parseString(reader) }
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.StoryFwdHeader.storyFwdHeader(flags: _1!, from: _2, fromName: _3, storyId: _4)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
indirect enum StoryItem: TypeConstructorDescription {
|
||||
case storyItem(flags: Int32, id: Int32, date: Int32, fromId: Api.Peer?, fwdFrom: Api.StoryFwdHeader?, expireDate: Int32, caption: String?, entities: [Api.MessageEntity]?, media: Api.MessageMedia, mediaAreas: [Api.MediaArea]?, privacy: [Api.PrivacyRule]?, views: Api.StoryViews?, sentReaction: Api.Reaction?, albums: [Int32]?)
|
||||
case storyItemDeleted(id: Int32)
|
||||
case storyItemSkipped(flags: Int32, id: Int32, date: Int32, expireDate: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyItem(let flags, let id, let date, let fromId, let fwdFrom, let expireDate, let caption, let entities, let media, let mediaAreas, let privacy, let views, let sentReaction, let albums):
|
||||
if boxed {
|
||||
buffer.appendInt32(-302947087)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(id, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 18) != 0 {fromId!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 17) != 0 {fwdFrom!.serialize(buffer, true)}
|
||||
serializeInt32(expireDate, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(caption!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(entities!.count))
|
||||
for item in entities! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
media.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 14) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(mediaAreas!.count))
|
||||
for item in mediaAreas! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 2) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(privacy!.count))
|
||||
for item in privacy! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 3) != 0 {views!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 15) != 0 {sentReaction!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 19) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(albums!.count))
|
||||
for item in albums! {
|
||||
serializeInt32(item, buffer: buffer, boxed: false)
|
||||
}}
|
||||
break
|
||||
case .storyItemDeleted(let id):
|
||||
if boxed {
|
||||
buffer.appendInt32(1374088783)
|
||||
}
|
||||
serializeInt32(id, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .storyItemSkipped(let flags, let id, let date, let expireDate):
|
||||
if boxed {
|
||||
buffer.appendInt32(-5388013)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(id, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
serializeInt32(expireDate, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyItem(let flags, let id, let date, let fromId, let fwdFrom, let expireDate, let caption, let entities, let media, let mediaAreas, let privacy, let views, let sentReaction, let albums):
|
||||
return ("storyItem", [("flags", flags as Any), ("id", id as Any), ("date", date as Any), ("fromId", fromId as Any), ("fwdFrom", fwdFrom as Any), ("expireDate", expireDate as Any), ("caption", caption as Any), ("entities", entities as Any), ("media", media as Any), ("mediaAreas", mediaAreas as Any), ("privacy", privacy as Any), ("views", views as Any), ("sentReaction", sentReaction as Any), ("albums", albums as Any)])
|
||||
case .storyItemDeleted(let id):
|
||||
return ("storyItemDeleted", [("id", id as Any)])
|
||||
case .storyItemSkipped(let flags, let id, let date, let expireDate):
|
||||
return ("storyItemSkipped", [("flags", flags as Any), ("id", id as Any), ("date", date as Any), ("expireDate", expireDate as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyItem(_ reader: BufferReader) -> StoryItem? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Api.Peer?
|
||||
if Int(_1!) & Int(1 << 18) != 0 {if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
} }
|
||||
var _5: Api.StoryFwdHeader?
|
||||
if Int(_1!) & Int(1 << 17) != 0 {if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.StoryFwdHeader
|
||||
} }
|
||||
var _6: Int32?
|
||||
_6 = reader.readInt32()
|
||||
var _7: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_7 = parseString(reader) }
|
||||
var _8: [Api.MessageEntity]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||
} }
|
||||
var _9: Api.MessageMedia?
|
||||
if let signature = reader.readInt32() {
|
||||
_9 = Api.parse(reader, signature: signature) as? Api.MessageMedia
|
||||
}
|
||||
var _10: [Api.MediaArea]?
|
||||
if Int(_1!) & Int(1 << 14) != 0 {if let _ = reader.readInt32() {
|
||||
_10 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MediaArea.self)
|
||||
} }
|
||||
var _11: [Api.PrivacyRule]?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let _ = reader.readInt32() {
|
||||
_11 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PrivacyRule.self)
|
||||
} }
|
||||
var _12: Api.StoryViews?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
|
||||
_12 = Api.parse(reader, signature: signature) as? Api.StoryViews
|
||||
} }
|
||||
var _13: Api.Reaction?
|
||||
if Int(_1!) & Int(1 << 15) != 0 {if let signature = reader.readInt32() {
|
||||
_13 = Api.parse(reader, signature: signature) as? Api.Reaction
|
||||
} }
|
||||
var _14: [Int32]?
|
||||
if Int(_1!) & Int(1 << 19) != 0 {if let _ = reader.readInt32() {
|
||||
_14 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 18) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 17) == 0) || _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 0) == 0) || _7 != nil
|
||||
let _c8 = (Int(_1!) & Int(1 << 1) == 0) || _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
let _c10 = (Int(_1!) & Int(1 << 14) == 0) || _10 != nil
|
||||
let _c11 = (Int(_1!) & Int(1 << 2) == 0) || _11 != nil
|
||||
let _c12 = (Int(_1!) & Int(1 << 3) == 0) || _12 != nil
|
||||
let _c13 = (Int(_1!) & Int(1 << 15) == 0) || _13 != nil
|
||||
let _c14 = (Int(_1!) & Int(1 << 19) == 0) || _14 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 {
|
||||
return Api.StoryItem.storyItem(flags: _1!, id: _2!, date: _3!, fromId: _4, fwdFrom: _5, expireDate: _6!, caption: _7, entities: _8, media: _9!, mediaAreas: _10, privacy: _11, views: _12, sentReaction: _13, albums: _14)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_storyItemDeleted(_ reader: BufferReader) -> StoryItem? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.StoryItem.storyItemDeleted(id: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_storyItemSkipped(_ reader: BufferReader) -> StoryItem? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.StoryItem.storyItemSkipped(flags: _1!, id: _2!, date: _3!, expireDate: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,283 @@
|
|||
public extension Api {
|
||||
enum StoryAlbum: TypeConstructorDescription {
|
||||
case storyAlbum(flags: Int32, albumId: Int32, title: String, iconPhoto: Api.Photo?, iconVideo: Api.Document?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyAlbum(let flags, let albumId, let title, let iconPhoto, let iconVideo):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1826262950)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(albumId, buffer: buffer, boxed: false)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {iconPhoto!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {iconVideo!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyAlbum(let flags, let albumId, let title, let iconPhoto, let iconVideo):
|
||||
return ("storyAlbum", [("flags", flags as Any), ("albumId", albumId as Any), ("title", title as Any), ("iconPhoto", iconPhoto as Any), ("iconVideo", iconVideo as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyAlbum(_ reader: BufferReader) -> StoryAlbum? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: Api.Photo?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.Photo
|
||||
} }
|
||||
var _5: Api.Document?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.Document
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.StoryAlbum.storyAlbum(flags: _1!, albumId: _2!, title: _3!, iconPhoto: _4, iconVideo: _5)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StoryFwdHeader: TypeConstructorDescription {
|
||||
case storyFwdHeader(flags: Int32, from: Api.Peer?, fromName: String?, storyId: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyFwdHeader(let flags, let from, let fromName, let storyId):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1205411504)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {from!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(fromName!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(storyId!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyFwdHeader(let flags, let from, let fromName, let storyId):
|
||||
return ("storyFwdHeader", [("flags", flags as Any), ("from", from as Any), ("fromName", fromName as Any), ("storyId", storyId as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyFwdHeader(_ reader: BufferReader) -> StoryFwdHeader? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Peer?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
} }
|
||||
var _3: String?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_3 = parseString(reader) }
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.StoryFwdHeader.storyFwdHeader(flags: _1!, from: _2, fromName: _3, storyId: _4)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
indirect enum StoryItem: TypeConstructorDescription {
|
||||
case storyItem(flags: Int32, id: Int32, date: Int32, fromId: Api.Peer?, fwdFrom: Api.StoryFwdHeader?, expireDate: Int32, caption: String?, entities: [Api.MessageEntity]?, media: Api.MessageMedia, mediaAreas: [Api.MediaArea]?, privacy: [Api.PrivacyRule]?, views: Api.StoryViews?, sentReaction: Api.Reaction?, albums: [Int32]?)
|
||||
case storyItemDeleted(id: Int32)
|
||||
case storyItemSkipped(flags: Int32, id: Int32, date: Int32, expireDate: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyItem(let flags, let id, let date, let fromId, let fwdFrom, let expireDate, let caption, let entities, let media, let mediaAreas, let privacy, let views, let sentReaction, let albums):
|
||||
if boxed {
|
||||
buffer.appendInt32(-302947087)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(id, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 18) != 0 {fromId!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 17) != 0 {fwdFrom!.serialize(buffer, true)}
|
||||
serializeInt32(expireDate, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(caption!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(entities!.count))
|
||||
for item in entities! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
media.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 14) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(mediaAreas!.count))
|
||||
for item in mediaAreas! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 2) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(privacy!.count))
|
||||
for item in privacy! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 3) != 0 {views!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 15) != 0 {sentReaction!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 19) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(albums!.count))
|
||||
for item in albums! {
|
||||
serializeInt32(item, buffer: buffer, boxed: false)
|
||||
}}
|
||||
break
|
||||
case .storyItemDeleted(let id):
|
||||
if boxed {
|
||||
buffer.appendInt32(1374088783)
|
||||
}
|
||||
serializeInt32(id, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .storyItemSkipped(let flags, let id, let date, let expireDate):
|
||||
if boxed {
|
||||
buffer.appendInt32(-5388013)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(id, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
serializeInt32(expireDate, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyItem(let flags, let id, let date, let fromId, let fwdFrom, let expireDate, let caption, let entities, let media, let mediaAreas, let privacy, let views, let sentReaction, let albums):
|
||||
return ("storyItem", [("flags", flags as Any), ("id", id as Any), ("date", date as Any), ("fromId", fromId as Any), ("fwdFrom", fwdFrom as Any), ("expireDate", expireDate as Any), ("caption", caption as Any), ("entities", entities as Any), ("media", media as Any), ("mediaAreas", mediaAreas as Any), ("privacy", privacy as Any), ("views", views as Any), ("sentReaction", sentReaction as Any), ("albums", albums as Any)])
|
||||
case .storyItemDeleted(let id):
|
||||
return ("storyItemDeleted", [("id", id as Any)])
|
||||
case .storyItemSkipped(let flags, let id, let date, let expireDate):
|
||||
return ("storyItemSkipped", [("flags", flags as Any), ("id", id as Any), ("date", date as Any), ("expireDate", expireDate as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyItem(_ reader: BufferReader) -> StoryItem? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Api.Peer?
|
||||
if Int(_1!) & Int(1 << 18) != 0 {if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
} }
|
||||
var _5: Api.StoryFwdHeader?
|
||||
if Int(_1!) & Int(1 << 17) != 0 {if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.StoryFwdHeader
|
||||
} }
|
||||
var _6: Int32?
|
||||
_6 = reader.readInt32()
|
||||
var _7: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_7 = parseString(reader) }
|
||||
var _8: [Api.MessageEntity]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||
} }
|
||||
var _9: Api.MessageMedia?
|
||||
if let signature = reader.readInt32() {
|
||||
_9 = Api.parse(reader, signature: signature) as? Api.MessageMedia
|
||||
}
|
||||
var _10: [Api.MediaArea]?
|
||||
if Int(_1!) & Int(1 << 14) != 0 {if let _ = reader.readInt32() {
|
||||
_10 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MediaArea.self)
|
||||
} }
|
||||
var _11: [Api.PrivacyRule]?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let _ = reader.readInt32() {
|
||||
_11 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PrivacyRule.self)
|
||||
} }
|
||||
var _12: Api.StoryViews?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
|
||||
_12 = Api.parse(reader, signature: signature) as? Api.StoryViews
|
||||
} }
|
||||
var _13: Api.Reaction?
|
||||
if Int(_1!) & Int(1 << 15) != 0 {if let signature = reader.readInt32() {
|
||||
_13 = Api.parse(reader, signature: signature) as? Api.Reaction
|
||||
} }
|
||||
var _14: [Int32]?
|
||||
if Int(_1!) & Int(1 << 19) != 0 {if let _ = reader.readInt32() {
|
||||
_14 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 18) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 17) == 0) || _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 0) == 0) || _7 != nil
|
||||
let _c8 = (Int(_1!) & Int(1 << 1) == 0) || _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
let _c10 = (Int(_1!) & Int(1 << 14) == 0) || _10 != nil
|
||||
let _c11 = (Int(_1!) & Int(1 << 2) == 0) || _11 != nil
|
||||
let _c12 = (Int(_1!) & Int(1 << 3) == 0) || _12 != nil
|
||||
let _c13 = (Int(_1!) & Int(1 << 15) == 0) || _13 != nil
|
||||
let _c14 = (Int(_1!) & Int(1 << 19) == 0) || _14 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 {
|
||||
return Api.StoryItem.storyItem(flags: _1!, id: _2!, date: _3!, fromId: _4, fwdFrom: _5, expireDate: _6!, caption: _7, entities: _8, media: _9!, mediaAreas: _10, privacy: _11, views: _12, sentReaction: _13, albums: _14)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_storyItemDeleted(_ reader: BufferReader) -> StoryItem? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.StoryItem.storyItemDeleted(id: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_storyItemSkipped(_ reader: BufferReader) -> StoryItem? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.StoryItem.storyItemSkipped(flags: _1!, id: _2!, date: _3!, expireDate: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
indirect enum StoryReaction: TypeConstructorDescription {
|
||||
case storyReaction(peerId: Api.Peer, date: Int32, reaction: Api.Reaction)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
public extension Api {
|
||||
indirect enum WebPageAttribute: TypeConstructorDescription {
|
||||
case webPageAttributeStarGiftAuction(gift: Api.StarGift, endDate: Int32, centerColor: Int32, edgeColor: Int32, textColor: Int32)
|
||||
case webPageAttributeStarGiftAuction(gift: Api.StarGift, endDate: Int32)
|
||||
case webPageAttributeStarGiftCollection(icons: [Api.Document])
|
||||
case webPageAttributeStickerSet(flags: Int32, stickers: [Api.Document])
|
||||
case webPageAttributeStory(flags: Int32, peer: Api.Peer, id: Int32, story: Api.StoryItem?)
|
||||
|
|
@ -9,15 +9,12 @@ public extension Api {
|
|||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .webPageAttributeStarGiftAuction(let gift, let endDate, let centerColor, let edgeColor, let textColor):
|
||||
case .webPageAttributeStarGiftAuction(let gift, let endDate):
|
||||
if boxed {
|
||||
buffer.appendInt32(55150251)
|
||||
buffer.appendInt32(29770178)
|
||||
}
|
||||
gift.serialize(buffer, true)
|
||||
serializeInt32(endDate, buffer: buffer, boxed: false)
|
||||
serializeInt32(centerColor, buffer: buffer, boxed: false)
|
||||
serializeInt32(edgeColor, buffer: buffer, boxed: false)
|
||||
serializeInt32(textColor, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .webPageAttributeStarGiftCollection(let icons):
|
||||
if boxed {
|
||||
|
|
@ -72,8 +69,8 @@ public extension Api {
|
|||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .webPageAttributeStarGiftAuction(let gift, let endDate, let centerColor, let edgeColor, let textColor):
|
||||
return ("webPageAttributeStarGiftAuction", [("gift", gift as Any), ("endDate", endDate as Any), ("centerColor", centerColor as Any), ("edgeColor", edgeColor as Any), ("textColor", textColor as Any)])
|
||||
case .webPageAttributeStarGiftAuction(let gift, let endDate):
|
||||
return ("webPageAttributeStarGiftAuction", [("gift", gift as Any), ("endDate", endDate as Any)])
|
||||
case .webPageAttributeStarGiftCollection(let icons):
|
||||
return ("webPageAttributeStarGiftCollection", [("icons", icons as Any)])
|
||||
case .webPageAttributeStickerSet(let flags, let stickers):
|
||||
|
|
@ -94,19 +91,10 @@ public extension Api {
|
|||
}
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
var _5: Int32?
|
||||
_5 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.WebPageAttribute.webPageAttributeStarGiftAuction(gift: _1!, endDate: _2!, centerColor: _3!, edgeColor: _4!, textColor: _5!)
|
||||
if _c1 && _c2 {
|
||||
return Api.WebPageAttribute.webPageAttributeStarGiftAuction(gift: _1!, endDate: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
@ -936,6 +924,86 @@ public extension Api.account {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum PasskeyRegistrationOptions: TypeConstructorDescription {
|
||||
case passkeyRegistrationOptions(options: Api.DataJSON)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .passkeyRegistrationOptions(let options):
|
||||
if boxed {
|
||||
buffer.appendInt32(-513057567)
|
||||
}
|
||||
options.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .passkeyRegistrationOptions(let options):
|
||||
return ("passkeyRegistrationOptions", [("options", options as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_passkeyRegistrationOptions(_ reader: BufferReader) -> PasskeyRegistrationOptions? {
|
||||
var _1: Api.DataJSON?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.account.PasskeyRegistrationOptions.passkeyRegistrationOptions(options: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum Passkeys: TypeConstructorDescription {
|
||||
case passkeys(passkeys: [Api.Passkey])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .passkeys(let passkeys):
|
||||
if boxed {
|
||||
buffer.appendInt32(-119494116)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(passkeys.count))
|
||||
for item in passkeys {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .passkeys(let passkeys):
|
||||
return ("passkeys", [("passkeys", passkeys as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_passkeys(_ reader: BufferReader) -> Passkeys? {
|
||||
var _1: [Api.Passkey]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Passkey.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.account.Passkeys.passkeys(passkeys: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum Password: TypeConstructorDescription {
|
||||
case password(flags: Int32, currentAlgo: Api.PasswordKdfAlgo?, srpB: Buffer?, srpId: Int64?, hint: String?, emailUnconfirmedPattern: String?, newAlgo: Api.PasswordKdfAlgo, newSecureAlgo: Api.SecurePasswordKdfAlgo, secureRandom: Buffer, pendingResetDate: Int32?, loginEmailPattern: String?)
|
||||
|
|
@ -1330,57 +1398,3 @@ public extension Api.account {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum SavedMusicIds: TypeConstructorDescription {
|
||||
case savedMusicIds(ids: [Int64])
|
||||
case savedMusicIdsNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .savedMusicIds(let ids):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1718786506)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(ids.count))
|
||||
for item in ids {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .savedMusicIdsNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(1338514798)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .savedMusicIds(let ids):
|
||||
return ("savedMusicIds", [("ids", ids as Any)])
|
||||
case .savedMusicIdsNotModified:
|
||||
return ("savedMusicIdsNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_savedMusicIds(_ reader: BufferReader) -> SavedMusicIds? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.account.SavedMusicIds.savedMusicIds(ids: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_savedMusicIdsNotModified(_ reader: BufferReader) -> SavedMusicIds? {
|
||||
return Api.account.SavedMusicIds.savedMusicIdsNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,57 @@
|
|||
public extension Api.account {
|
||||
enum SavedMusicIds: TypeConstructorDescription {
|
||||
case savedMusicIds(ids: [Int64])
|
||||
case savedMusicIdsNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .savedMusicIds(let ids):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1718786506)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(ids.count))
|
||||
for item in ids {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .savedMusicIdsNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(1338514798)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .savedMusicIds(let ids):
|
||||
return ("savedMusicIds", [("ids", ids as Any)])
|
||||
case .savedMusicIdsNotModified:
|
||||
return ("savedMusicIdsNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_savedMusicIds(_ reader: BufferReader) -> SavedMusicIds? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.account.SavedMusicIds.savedMusicIds(ids: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_savedMusicIdsNotModified(_ reader: BufferReader) -> SavedMusicIds? {
|
||||
return Api.account.SavedMusicIds.savedMusicIdsNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum SavedRingtone: TypeConstructorDescription {
|
||||
case savedRingtone
|
||||
|
|
@ -712,6 +766,44 @@ public extension Api.auth {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.auth {
|
||||
enum PasskeyLoginOptions: TypeConstructorDescription {
|
||||
case passkeyLoginOptions(options: Api.DataJSON)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .passkeyLoginOptions(let options):
|
||||
if boxed {
|
||||
buffer.appendInt32(-503089271)
|
||||
}
|
||||
options.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .passkeyLoginOptions(let options):
|
||||
return ("passkeyLoginOptions", [("options", options as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_passkeyLoginOptions(_ reader: BufferReader) -> PasskeyLoginOptions? {
|
||||
var _1: Api.DataJSON?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.auth.PasskeyLoginOptions.passkeyLoginOptions(options: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.auth {
|
||||
enum PasswordRecovery: TypeConstructorDescription {
|
||||
case passwordRecovery(emailPattern: String)
|
||||
|
|
|
|||
|
|
@ -278,14 +278,14 @@ public extension Api.payments {
|
|||
}
|
||||
public extension Api.payments {
|
||||
enum StarGiftActiveAuctions: TypeConstructorDescription {
|
||||
case starGiftActiveAuctions(auctions: [Api.StarGiftActiveAuctionState], users: [Api.User])
|
||||
case starGiftActiveAuctions(auctions: [Api.StarGiftActiveAuctionState], users: [Api.User], chats: [Api.Chat])
|
||||
case starGiftActiveAuctionsNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starGiftActiveAuctions(let auctions, let users):
|
||||
case .starGiftActiveAuctions(let auctions, let users, let chats):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1745778728)
|
||||
buffer.appendInt32(-1359565892)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(auctions.count))
|
||||
|
|
@ -297,6 +297,11 @@ public extension Api.payments {
|
|||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .starGiftActiveAuctionsNotModified:
|
||||
if boxed {
|
||||
|
|
@ -309,8 +314,8 @@ public extension Api.payments {
|
|||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starGiftActiveAuctions(let auctions, let users):
|
||||
return ("starGiftActiveAuctions", [("auctions", auctions as Any), ("users", users as Any)])
|
||||
case .starGiftActiveAuctions(let auctions, let users, let chats):
|
||||
return ("starGiftActiveAuctions", [("auctions", auctions as Any), ("users", users as Any), ("chats", chats as Any)])
|
||||
case .starGiftActiveAuctionsNotModified:
|
||||
return ("starGiftActiveAuctionsNotModified", [])
|
||||
}
|
||||
|
|
@ -325,10 +330,15 @@ public extension Api.payments {
|
|||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _3: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.payments.StarGiftActiveAuctions.starGiftActiveAuctions(auctions: _1!, users: _2!)
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.payments.StarGiftActiveAuctions.starGiftActiveAuctions(auctions: _1!, users: _2!, chats: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
@ -404,13 +414,13 @@ public extension Api.payments {
|
|||
}
|
||||
public extension Api.payments {
|
||||
enum StarGiftAuctionState: TypeConstructorDescription {
|
||||
case starGiftAuctionState(gift: Api.StarGift, state: Api.StarGiftAuctionState, userState: Api.StarGiftAuctionUserState, timeout: Int32, users: [Api.User])
|
||||
case starGiftAuctionState(gift: Api.StarGift, state: Api.StarGiftAuctionState, userState: Api.StarGiftAuctionUserState, timeout: Int32, users: [Api.User], chats: [Api.Chat])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starGiftAuctionState(let gift, let state, let userState, let timeout, let users):
|
||||
case .starGiftAuctionState(let gift, let state, let userState, let timeout, let users, let chats):
|
||||
if boxed {
|
||||
buffer.appendInt32(244900980)
|
||||
buffer.appendInt32(1798960364)
|
||||
}
|
||||
gift.serialize(buffer, true)
|
||||
state.serialize(buffer, true)
|
||||
|
|
@ -421,14 +431,19 @@ public extension Api.payments {
|
|||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starGiftAuctionState(let gift, let state, let userState, let timeout, let users):
|
||||
return ("starGiftAuctionState", [("gift", gift as Any), ("state", state as Any), ("userState", userState as Any), ("timeout", timeout as Any), ("users", users as Any)])
|
||||
case .starGiftAuctionState(let gift, let state, let userState, let timeout, let users, let chats):
|
||||
return ("starGiftAuctionState", [("gift", gift as Any), ("state", state as Any), ("userState", userState as Any), ("timeout", timeout as Any), ("users", users as Any), ("chats", chats as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -451,13 +466,18 @@ public extension Api.payments {
|
|||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _6: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.payments.StarGiftAuctionState.starGiftAuctionState(gift: _1!, state: _2!, userState: _3!, timeout: _4!, users: _5!)
|
||||
let _c6 = _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.payments.StarGiftAuctionState.starGiftAuctionState(gift: _1!, state: _2!, userState: _3!, timeout: _4!, users: _5!, chats: _6!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
@ -520,6 +540,48 @@ public extension Api.payments {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum StarGiftUpgradeAttributes: TypeConstructorDescription {
|
||||
case starGiftUpgradeAttributes(attributes: [Api.StarGiftAttribute])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starGiftUpgradeAttributes(let attributes):
|
||||
if boxed {
|
||||
buffer.appendInt32(1187439471)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(attributes.count))
|
||||
for item in attributes {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starGiftUpgradeAttributes(let attributes):
|
||||
return ("starGiftUpgradeAttributes", [("attributes", attributes as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starGiftUpgradeAttributes(_ reader: BufferReader) -> StarGiftUpgradeAttributes? {
|
||||
var _1: [Api.StarGiftAttribute]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarGiftAttribute.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.payments.StarGiftUpgradeAttributes.starGiftUpgradeAttributes(attributes: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum StarGiftUpgradePreview: TypeConstructorDescription {
|
||||
case starGiftUpgradePreview(sampleAttributes: [Api.StarGiftAttribute], prices: [Api.StarGiftUpgradePrice], nextPrices: [Api.StarGiftUpgradePrice])
|
||||
|
|
@ -1616,51 +1678,3 @@ public extension Api.phone {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.photos {
|
||||
enum Photo: TypeConstructorDescription {
|
||||
case photo(photo: Api.Photo, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .photo(let photo, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(539045032)
|
||||
}
|
||||
photo.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .photo(let photo, let users):
|
||||
return ("photo", [("photo", photo as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_photo(_ reader: BufferReader) -> Photo? {
|
||||
var _1: Api.Photo?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.Photo
|
||||
}
|
||||
var _2: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.photos.Photo.photo(photo: _1!, users: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,51 @@
|
|||
public extension Api.photos {
|
||||
enum Photo: TypeConstructorDescription {
|
||||
case photo(photo: Api.Photo, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .photo(let photo, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(539045032)
|
||||
}
|
||||
photo.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .photo(let photo, let users):
|
||||
return ("photo", [("photo", photo as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_photo(_ reader: BufferReader) -> Photo? {
|
||||
var _1: Api.Photo?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.Photo
|
||||
}
|
||||
var _2: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.photos.Photo.photo(photo: _1!, users: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.photos {
|
||||
enum Photos: TypeConstructorDescription {
|
||||
case photos(photos: [Api.Photo], users: [Api.User])
|
||||
|
|
@ -1474,77 +1522,3 @@ public extension Api.stories {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.stories {
|
||||
enum StoryReactionsList: TypeConstructorDescription {
|
||||
case storyReactionsList(flags: Int32, count: Int32, reactions: [Api.StoryReaction], chats: [Api.Chat], users: [Api.User], nextOffset: String?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyReactionsList(let flags, let count, let reactions, let chats, let users, let nextOffset):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1436583780)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(reactions.count))
|
||||
for item in reactions {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyReactionsList(let flags, let count, let reactions, let chats, let users, let nextOffset):
|
||||
return ("storyReactionsList", [("flags", flags as Any), ("count", count as Any), ("reactions", reactions as Any), ("chats", chats as Any), ("users", users as Any), ("nextOffset", nextOffset as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyReactionsList(_ reader: BufferReader) -> StoryReactionsList? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: [Api.StoryReaction]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StoryReaction.self)
|
||||
}
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _6: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_6 = parseString(reader) }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.stories.StoryReactionsList.storyReactionsList(flags: _1!, count: _2!, reactions: _3!, chats: _4!, users: _5!, nextOffset: _6)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,77 @@
|
|||
public extension Api.stories {
|
||||
enum StoryReactionsList: TypeConstructorDescription {
|
||||
case storyReactionsList(flags: Int32, count: Int32, reactions: [Api.StoryReaction], chats: [Api.Chat], users: [Api.User], nextOffset: String?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyReactionsList(let flags, let count, let reactions, let chats, let users, let nextOffset):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1436583780)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(reactions.count))
|
||||
for item in reactions {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyReactionsList(let flags, let count, let reactions, let chats, let users, let nextOffset):
|
||||
return ("storyReactionsList", [("flags", flags as Any), ("count", count as Any), ("reactions", reactions as Any), ("chats", chats as Any), ("users", users as Any), ("nextOffset", nextOffset as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyReactionsList(_ reader: BufferReader) -> StoryReactionsList? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: [Api.StoryReaction]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StoryReaction.self)
|
||||
}
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _6: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_6 = parseString(reader) }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.stories.StoryReactionsList.storyReactionsList(flags: _1!, count: _2!, reactions: _3!, chats: _4!, users: _5!, nextOffset: _6)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stories {
|
||||
enum StoryViews: TypeConstructorDescription {
|
||||
case storyViews(views: [Api.StoryViews], users: [Api.User])
|
||||
|
|
|
|||
|
|
@ -232,6 +232,21 @@ public extension Api.functions.account {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func deletePasskey(id: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-172665281)
|
||||
serializeString(id, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "account.deletePasskey", parameters: [("id", String(describing: id))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Bool?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Bool
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func deleteSecureValue(types: [Api.SecureValueType]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -666,6 +681,21 @@ public extension Api.functions.account {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func getPasskeys() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.account.Passkeys>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-367063982)
|
||||
|
||||
return (FunctionDescription(name: "account.getPasskeys", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.account.Passkeys? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.account.Passkeys?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.account.Passkeys
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func getPassword() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.account.Password>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -900,6 +930,21 @@ public extension Api.functions.account {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func initPasskeyRegistration() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.account.PasskeyRegistrationOptions>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(1117079528)
|
||||
|
||||
return (FunctionDescription(name: "account.initPasskeyRegistration", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.account.PasskeyRegistrationOptions? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.account.PasskeyRegistrationOptions?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.account.PasskeyRegistrationOptions
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func initTakeoutSession(flags: Int32, fileMaxSize: Int64?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.account.Takeout>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -993,6 +1038,21 @@ public extension Api.functions.account {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func registerPasskey(credential: Api.InputPasskeyCredential) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Passkey>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(1437867990)
|
||||
credential.serialize(buffer, true)
|
||||
return (FunctionDescription(name: "account.registerPasskey", parameters: [("credential", String(describing: credential))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Passkey? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Passkey?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Passkey
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func reorderUsernames(order: [String]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -2075,6 +2135,24 @@ public extension Api.functions.auth {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.auth {
|
||||
static func finishPasskeyLogin(flags: Int32, credential: Api.InputPasskeyCredential, fromDcId: Int32?, fromAuthKeyId: Int64?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.auth.Authorization>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-1739084537)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
credential.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(fromDcId!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(fromAuthKeyId!, buffer: buffer, boxed: false)}
|
||||
return (FunctionDescription(name: "auth.finishPasskeyLogin", parameters: [("flags", String(describing: flags)), ("credential", String(describing: credential)), ("fromDcId", String(describing: fromDcId)), ("fromAuthKeyId", String(describing: fromAuthKeyId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.auth.Authorization? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.auth.Authorization?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.auth.Authorization
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.auth {
|
||||
static func importAuthorization(id: Int64, bytes: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.auth.Authorization>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -2141,6 +2219,22 @@ public extension Api.functions.auth {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.auth {
|
||||
static func initPasskeyLogin(apiId: Int32, apiHash: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.auth.PasskeyLoginOptions>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(1368051895)
|
||||
serializeInt32(apiId, buffer: buffer, boxed: false)
|
||||
serializeString(apiHash, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "auth.initPasskeyLogin", parameters: [("apiId", String(describing: apiId)), ("apiHash", String(describing: apiHash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.auth.PasskeyLoginOptions? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.auth.PasskeyLoginOptions?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.auth.PasskeyLoginOptions
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.auth {
|
||||
static func logOut() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.auth.LoggedOut>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -5736,9 +5830,9 @@ public extension Api.functions.messages {
|
|||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func forwardMessages(flags: Int32, fromPeer: Api.InputPeer, id: [Int32], randomId: [Int64], toPeer: Api.InputPeer, topMsgId: Int32?, replyTo: Api.InputReplyTo?, scheduleDate: Int32?, scheduleRepeatPeriod: Int32?, sendAs: Api.InputPeer?, quickReplyShortcut: Api.InputQuickReplyShortcut?, videoTimestamp: Int32?, allowPaidStars: Int64?, suggestedPost: Api.SuggestedPost?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||
static func forwardMessages(flags: Int32, fromPeer: Api.InputPeer, id: [Int32], randomId: [Int64], toPeer: Api.InputPeer, topMsgId: Int32?, replyTo: Api.InputReplyTo?, scheduleDate: Int32?, scheduleRepeatPeriod: Int32?, sendAs: Api.InputPeer?, quickReplyShortcut: Api.InputQuickReplyShortcut?, effect: Int64?, videoTimestamp: Int32?, allowPaidStars: Int64?, suggestedPost: Api.SuggestedPost?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(1104419550)
|
||||
buffer.appendInt32(326126204)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
fromPeer.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
|
|
@ -5758,10 +5852,11 @@ public extension Api.functions.messages {
|
|||
if Int(flags) & Int(1 << 24) != 0 {serializeInt32(scheduleRepeatPeriod!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 17) != 0 {quickReplyShortcut!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 18) != 0 {serializeInt64(effect!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 20) != 0 {serializeInt32(videoTimestamp!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 21) != 0 {serializeInt64(allowPaidStars!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 23) != 0 {suggestedPost!.serialize(buffer, true)}
|
||||
return (FunctionDescription(name: "messages.forwardMessages", parameters: [("flags", String(describing: flags)), ("fromPeer", String(describing: fromPeer)), ("id", String(describing: id)), ("randomId", String(describing: randomId)), ("toPeer", String(describing: toPeer)), ("topMsgId", String(describing: topMsgId)), ("replyTo", String(describing: replyTo)), ("scheduleDate", String(describing: scheduleDate)), ("scheduleRepeatPeriod", String(describing: scheduleRepeatPeriod)), ("sendAs", String(describing: sendAs)), ("quickReplyShortcut", String(describing: quickReplyShortcut)), ("videoTimestamp", String(describing: videoTimestamp)), ("allowPaidStars", String(describing: allowPaidStars)), ("suggestedPost", String(describing: suggestedPost))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||
return (FunctionDescription(name: "messages.forwardMessages", parameters: [("flags", String(describing: flags)), ("fromPeer", String(describing: fromPeer)), ("id", String(describing: id)), ("randomId", String(describing: randomId)), ("toPeer", String(describing: toPeer)), ("topMsgId", String(describing: topMsgId)), ("replyTo", String(describing: replyTo)), ("scheduleDate", String(describing: scheduleDate)), ("scheduleRepeatPeriod", String(describing: scheduleRepeatPeriod)), ("sendAs", String(describing: sendAs)), ("quickReplyShortcut", String(describing: quickReplyShortcut)), ("effect", String(describing: effect)), ("videoTimestamp", String(describing: videoTimestamp)), ("allowPaidStars", String(describing: allowPaidStars)), ("suggestedPost", String(describing: suggestedPost))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Updates?
|
||||
if let signature = reader.readInt32() {
|
||||
|
|
@ -9816,6 +9911,21 @@ public extension Api.functions.payments {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func getStarGiftUpgradeAttributes(giftId: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.StarGiftUpgradeAttributes>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(1828948824)
|
||||
serializeInt64(giftId, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "payments.getStarGiftUpgradeAttributes", parameters: [("giftId", String(describing: giftId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.StarGiftUpgradeAttributes? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.payments.StarGiftUpgradeAttributes?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.payments.StarGiftUpgradeAttributes
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func getStarGiftUpgradePreview(giftId: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.StarGiftUpgradePreview>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -10131,6 +10241,22 @@ public extension Api.functions.payments {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func resolveStarGiftOffer(flags: Int32, offerMsgId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-372344804)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(offerMsgId, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "payments.resolveStarGiftOffer", parameters: [("flags", String(describing: flags)), ("offerMsgId", String(describing: offerMsgId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Updates?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Updates
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func saveStarGift(flags: Int32, stargift: Api.InputSavedStarGift) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -10168,6 +10294,27 @@ public extension Api.functions.payments {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func sendStarGiftOffer(flags: Int32, peer: Api.InputPeer, slug: String, price: Api.StarsAmount, duration: Int32, randomId: Int64, allowPaidStars: Int64?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-1883739327)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
peer.serialize(buffer, true)
|
||||
serializeString(slug, buffer: buffer, boxed: false)
|
||||
price.serialize(buffer, true)
|
||||
serializeInt32(duration, buffer: buffer, boxed: false)
|
||||
serializeInt64(randomId, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(allowPaidStars!, buffer: buffer, boxed: false)}
|
||||
return (FunctionDescription(name: "payments.sendStarGiftOffer", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("slug", String(describing: slug)), ("price", String(describing: price)), ("duration", String(describing: duration)), ("randomId", String(describing: randomId)), ("allowPaidStars", String(describing: allowPaidStars))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Updates?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Updates
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func sendStarsForm(formId: Int64, invoice: Api.InputInvoice) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.PaymentResult>) {
|
||||
let buffer = Buffer()
|
||||
|
|
|
|||
|
|
@ -103,8 +103,9 @@ final class GiftAuctionAccessoryPanel: ASDisplayNode {
|
|||
}
|
||||
}
|
||||
|
||||
let titleText: String = self.strings.ChatList_Auctions_ActiveAuction(Int32(self.states.count))
|
||||
titleItems.append(AnyComponentWithIdentity(id: "label", component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: titleText, font: titleFont, textColor: self.theme.rootController.navigationBar.primaryTextColor))))))
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
|
||||
var titleText: String = self.strings.ChatList_Auctions_ActiveAuction(Int32(self.states.count))
|
||||
|
||||
let subtitleText: String
|
||||
var subtitleTextColor = self.theme.rootController.navigationBar.secondaryTextColor
|
||||
|
|
@ -113,8 +114,21 @@ final class GiftAuctionAccessoryPanel: ASDisplayNode {
|
|||
var buttonAnimatedTitleItems: [AnimatedTextComponent.Item] = []
|
||||
|
||||
if self.states.count == 1, let auctionState = self.states.first {
|
||||
var isUpcoming = false
|
||||
var startTime = currentTime
|
||||
var endTime = currentTime
|
||||
if case let .ongoing(_, startDate, _, _, _, _, nextRoundDate, _, _, _, _, _) = auctionState.auctionState {
|
||||
startTime = startDate
|
||||
endTime = nextRoundDate
|
||||
if currentTime < startDate {
|
||||
isUpcoming = true
|
||||
}
|
||||
}
|
||||
|
||||
let place = auctionState.place ?? 1
|
||||
if case let .generic(gift) = auctionState.gift, let auctionGiftsPerRound = gift.auctionGiftsPerRound, place > auctionGiftsPerRound {
|
||||
if isUpcoming {
|
||||
subtitleText = self.strings.ChatList_Auctions_Status_UpcomingBid
|
||||
} else if case let .generic(gift) = auctionState.gift, let auctionGiftsPerRound = gift.auctionGiftsPerRound, place > auctionGiftsPerRound {
|
||||
subtitleText = self.strings.ChatList_Auctions_Status_Single_Outbid
|
||||
subtitleTextColor = self.theme.list.itemDestructiveColor
|
||||
isOutbid = true
|
||||
|
|
@ -134,14 +148,14 @@ final class GiftAuctionAccessoryPanel: ASDisplayNode {
|
|||
subtitleText = self.strings.ChatList_Auctions_Status_Single_Winning(placeText).string
|
||||
}
|
||||
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
var endTime = currentTime
|
||||
if case let .ongoing(_, _, _, _, _, _, nextRoundDate, _, _, _) = auctionState.auctionState {
|
||||
endTime = nextRoundDate
|
||||
let endTimeout: Int32
|
||||
if currentTime < startTime {
|
||||
endTimeout = max(0, startTime - currentTime)
|
||||
titleText = self.strings.ChatList_Auctions_UpcomingAuction
|
||||
} else {
|
||||
endTimeout = max(0, endTime - currentTime)
|
||||
}
|
||||
|
||||
let endTimeout = max(0, endTime - currentTime)
|
||||
|
||||
let hours = Int(endTimeout / 3600)
|
||||
let minutes = Int((endTimeout % 3600) / 60)
|
||||
let seconds = Int(endTimeout % 60)
|
||||
|
|
@ -179,6 +193,8 @@ final class GiftAuctionAccessoryPanel: ASDisplayNode {
|
|||
buttonAnimatedTitleItems.append(AnimatedTextComponent.Item(id: "view", content: .text(self.strings.ChatList_Auctions_View)))
|
||||
}
|
||||
|
||||
titleItems.append(AnyComponentWithIdentity(id: "label", component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: titleText, font: titleFont, textColor: self.theme.rootController.navigationBar.primaryTextColor))))))
|
||||
|
||||
let buttonSize = self.button.update(
|
||||
transition: .spring(duration: 0.2),
|
||||
component: AnyComponent(
|
||||
|
|
|
|||
|
|
@ -340,7 +340,13 @@ public func accountWithId(accountManager: AccountManager<TelegramAccountManagerT
|
|||
}
|
||||
}
|
||||
|
||||
return initializedNetwork(accountId: id, arguments: networkArguments, supplementary: supplementary, datacenterId: 2, keychain: keychain, basePath: path, testingEnvironment: beginWithTestingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil, useRequestTimeoutTimers: useRequestTimeoutTimers, appConfiguration: appConfig)
|
||||
#if DEBUG
|
||||
let initialDatacenterId: Int = 1
|
||||
#else
|
||||
let initialDatacenterId: Int = 2
|
||||
#endif
|
||||
|
||||
return initializedNetwork(accountId: id, arguments: networkArguments, supplementary: supplementary, datacenterId: initialDatacenterId, keychain: keychain, basePath: path, testingEnvironment: beginWithTestingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil, useRequestTimeoutTimers: useRequestTimeoutTimers, appConfiguration: appConfig)
|
||||
|> map { network -> AccountResult in
|
||||
return .unauthorized(UnauthorizedAccount(accountManager: accountManager, networkArguments: networkArguments, id: id, rootPath: rootPath, basePath: path, testingEnvironment: beginWithTestingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection))
|
||||
}
|
||||
|
|
@ -453,6 +459,131 @@ func _internal_twoStepAuthData(_ network: Network) -> Signal<TwoStepAuthData, MT
|
|||
}
|
||||
}
|
||||
|
||||
public final class TelegramPasskey: Equatable {
|
||||
public let id: String
|
||||
public let name: String
|
||||
public let date: Int32
|
||||
public let emojiId: Int64?
|
||||
public let lastUsageDate: Int32?
|
||||
|
||||
public init(id: String, name: String, date: Int32, emojiId: Int64?, lastUsageDate: Int32?) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.date = date
|
||||
self.emojiId = emojiId
|
||||
self.lastUsageDate = lastUsageDate
|
||||
}
|
||||
|
||||
public static func ==(lhs: TelegramPasskey, rhs: TelegramPasskey) -> Bool {
|
||||
if lhs.id != rhs.id {
|
||||
return false
|
||||
}
|
||||
if lhs.name != rhs.name {
|
||||
return false
|
||||
}
|
||||
if lhs.date != rhs.date {
|
||||
return false
|
||||
}
|
||||
if lhs.emojiId != rhs.emojiId {
|
||||
return false
|
||||
}
|
||||
if lhs.lastUsageDate != rhs.lastUsageDate {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension TelegramPasskey {
|
||||
convenience init(apiPasskey: Api.Passkey) {
|
||||
switch apiPasskey {
|
||||
case let .passkey(_, id, name, date, softwareEmojiId, lastUsageDate):
|
||||
self.init(id: id, name: name, date: date, emojiId: softwareEmojiId, lastUsageDate: lastUsageDate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_passkeysData(network: Network) -> Signal<[TelegramPasskey], NoError> {
|
||||
return network.request(Api.functions.account.getPasskeys())
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.account.Passkeys?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> map { passkeys -> [TelegramPasskey] in
|
||||
guard let passkeys else {
|
||||
return []
|
||||
}
|
||||
switch passkeys {
|
||||
case let .passkeys(passkeys):
|
||||
return passkeys.map { passkey in
|
||||
return TelegramPasskey(apiPasskey: passkey)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_requestPasskeyRegistration(network: Network) -> Signal<String?, NoError> {
|
||||
return network.request(Api.functions.account.initPasskeyRegistration())
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.account.PasskeyRegistrationOptions?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> map { options -> String? in
|
||||
guard let options else {
|
||||
return nil
|
||||
}
|
||||
switch options {
|
||||
case let .passkeyRegistrationOptions(options):
|
||||
switch options {
|
||||
case let .dataJSON(data):
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_requestCreatePasskey(network: Network, id: String, clientData: String, attestationObject: Data) -> Signal<TelegramPasskey?, NoError> {
|
||||
return network.request(Api.functions.account.registerPasskey(credential: .inputPasskeyCredentialPublicKey(id: id, rawId: id, response: .inputPasskeyResponseRegister(clientData: .dataJSON(data: clientData), attestationData: Buffer(data: attestationObject)))))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Passkey?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> map { result -> TelegramPasskey? in
|
||||
guard let result else {
|
||||
return nil
|
||||
}
|
||||
return TelegramPasskey(apiPasskey: result)
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_deletePasskey(network: Network, id: String) -> Signal<Never, NoError> {
|
||||
return network.request(Api.functions.account.deletePasskey(id: id))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
|
||||
func _internal_requestPasskeyLoginData(network: Network, apiId: Int32, apiHash: String) -> Signal<String?, NoError> {
|
||||
return network.request(Api.functions.auth.initPasskeyLogin(apiId: apiId, apiHash: apiHash))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.auth.PasskeyLoginOptions?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> map { result -> String? in
|
||||
guard let result else {
|
||||
return nil
|
||||
}
|
||||
switch result {
|
||||
case let .passkeyLoginOptions(options):
|
||||
switch options {
|
||||
case let .dataJSON(data):
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func hexString(_ data: Data) -> String {
|
||||
let hexString = NSMutableString()
|
||||
data.withUnsafeBytes { rawBytes -> Void in
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
|
|||
}
|
||||
|
||||
switch action {
|
||||
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions, .messageActionTodoAppendTasks, .messageActionSuggestedPostApproval, .messageActionGiftTon, .messageActionSuggestedPostSuccess, .messageActionSuggestedPostRefund, .messageActionSuggestBirthday:
|
||||
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions, .messageActionTodoAppendTasks, .messageActionSuggestedPostApproval, .messageActionGiftTon, .messageActionSuggestedPostSuccess, .messageActionSuggestedPostRefund, .messageActionSuggestBirthday, .messageActionStarGiftPurchaseOffer, .messageActionStarGiftPurchaseOfferDeclined:
|
||||
break
|
||||
case let .messageActionChannelMigrateFrom(_, chatId):
|
||||
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId)))
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
|
|||
return TelegramMediaAction(action: .paymentRefunded(peerId: peer.peerId, currency: currency, totalAmount: totalAmount, payload: payload?.makeData(), transactionId: transactionId))
|
||||
case let .messageActionPrizeStars(flags, stars, transactionId, boostPeer, giveawayMsgId):
|
||||
return TelegramMediaAction(action: .prizeStars(amount: stars, isUnclaimed: (flags & (1 << 2)) != 0, boostPeerId: boostPeer.peerId, transactionId: transactionId, giveawayMessageId: MessageId(peerId: boostPeer.peerId, namespace: Namespaces.Message.Cloud, id: giveawayMsgId)))
|
||||
case let .messageActionStarGift(flags, apiGift, message, convertStars, upgradeMessageId, upgradeStars, fromId, peer, savedId, prepaidUpgradeHash, giftMessageId, toId):
|
||||
case let .messageActionStarGift(flags, apiGift, message, convertStars, upgradeMessageId, upgradeStars, fromId, peer, savedId, prepaidUpgradeHash, giftMessageId, toId, number):
|
||||
let text: String?
|
||||
let entities: [MessageTextEntity]?
|
||||
switch message {
|
||||
|
|
@ -195,12 +195,12 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
|
|||
guard let gift = StarGift(apiStarGift: apiGift) else {
|
||||
return nil
|
||||
}
|
||||
return TelegramMediaAction(action: .starGift(gift: gift, convertStars: convertStars, text: text, entities: entities, nameHidden: (flags & (1 << 0)) != 0, savedToProfile: (flags & (1 << 2)) != 0, converted: (flags & (1 << 3)) != 0, upgraded: (flags & (1 << 5)) != 0, canUpgrade: (flags & (1 << 10)) != 0, upgradeStars: upgradeStars, isRefunded: (flags & (1 << 9)) != 0, isPrepaidUpgrade: (flags & (1 << 13)) != 0, upgradeMessageId: upgradeMessageId, peerId: peer?.peerId, senderId: fromId?.peerId, savedId: savedId, prepaidUpgradeHash: prepaidUpgradeHash, giftMessageId: giftMessageId, upgradeSeparate: (flags & (1 << 16)) != 0, isAuctionAcquired: (flags & (1 << 17)) != 0, toPeerId: toId?.peerId))
|
||||
return TelegramMediaAction(action: .starGift(gift: gift, convertStars: convertStars, text: text, entities: entities, nameHidden: (flags & (1 << 0)) != 0, savedToProfile: (flags & (1 << 2)) != 0, converted: (flags & (1 << 3)) != 0, upgraded: (flags & (1 << 5)) != 0, canUpgrade: (flags & (1 << 10)) != 0, upgradeStars: upgradeStars, isRefunded: (flags & (1 << 9)) != 0, isPrepaidUpgrade: (flags & (1 << 13)) != 0, upgradeMessageId: upgradeMessageId, peerId: peer?.peerId, senderId: fromId?.peerId, savedId: savedId, prepaidUpgradeHash: prepaidUpgradeHash, giftMessageId: giftMessageId, upgradeSeparate: (flags & (1 << 16)) != 0, isAuctionAcquired: (flags & (1 << 17)) != 0, toPeerId: toId?.peerId, number: number))
|
||||
case let .messageActionStarGiftUnique(flags, apiGift, canExportAt, transferStars, fromId, peer, savedId, resaleAmount, canTransferDate, canResaleDate, dropOriginalDetailsStars):
|
||||
guard let gift = StarGift(apiStarGift: apiGift) else {
|
||||
return nil
|
||||
}
|
||||
return TelegramMediaAction(action: .starGiftUnique(gift: gift, isUpgrade: (flags & (1 << 0)) != 0, isTransferred: (flags & (1 << 1)) != 0, savedToProfile: (flags & (1 << 2)) != 0, canExportDate: canExportAt, transferStars: transferStars, isRefunded: (flags & (1 << 5)) != 0, isPrepaidUpgrade: (flags & (1 << 11)) != 0, peerId: peer?.peerId, senderId: fromId?.peerId, savedId: savedId, resaleAmount: resaleAmount.flatMap { CurrencyAmount(apiAmount: $0) }, canTransferDate: canTransferDate, canResaleDate: canResaleDate, dropOriginalDetailsStars: dropOriginalDetailsStars, assigned: (flags & (1 << 13)) != 0))
|
||||
return TelegramMediaAction(action: .starGiftUnique(gift: gift, isUpgrade: (flags & (1 << 0)) != 0, isTransferred: (flags & (1 << 1)) != 0, savedToProfile: (flags & (1 << 2)) != 0, canExportDate: canExportAt, transferStars: transferStars, isRefunded: (flags & (1 << 5)) != 0, isPrepaidUpgrade: (flags & (1 << 11)) != 0, peerId: peer?.peerId, senderId: fromId?.peerId, savedId: savedId, resaleAmount: resaleAmount.flatMap { CurrencyAmount(apiAmount: $0) }, canTransferDate: canTransferDate, canResaleDate: canResaleDate, dropOriginalDetailsStars: dropOriginalDetailsStars, assigned: (flags & (1 << 13)) != 0, fromOffer: (flags & (1 << 14)) != 0))
|
||||
case let .messageActionPaidMessagesRefunded(count, stars):
|
||||
return TelegramMediaAction(action: .paidMessagesRefunded(count: count, stars: stars))
|
||||
case let .messageActionPaidMessagesPrice(flags, stars):
|
||||
|
|
@ -274,6 +274,17 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
|
|||
return TelegramMediaAction(action: .suggestedPostRefund(TelegramMediaActionType.SuggestedPostRefund(isUserInitiated: (flags & (1 << 0)) != 0)))
|
||||
case let .messageActionSuggestBirthday(birthday):
|
||||
return TelegramMediaAction(action: .suggestedBirthday(TelegramBirthday(apiBirthday: birthday)))
|
||||
|
||||
case let .messageActionStarGiftPurchaseOffer(flags, apiGift, price, expiresAt):
|
||||
guard let gift = StarGift(apiStarGift: apiGift) else {
|
||||
return nil
|
||||
}
|
||||
return TelegramMediaAction(action: .starGiftPurchaseOffer(gift: gift, amount: CurrencyAmount(apiAmount: price), expireDate: expiresAt, isAccepted: (flags & (1 << 0)) != 0, isDeclined: (flags & (1 << 1)) != 0))
|
||||
case let .messageActionStarGiftPurchaseOfferDeclined(flags, apiGift, price):
|
||||
guard let gift = StarGift(apiStarGift: apiGift) else {
|
||||
return nil
|
||||
}
|
||||
return TelegramMediaAction(action: .starGiftPurchaseOfferDeclined(gift: gift, amount: CurrencyAmount(apiAmount: price), hasExpired: (flags & (1 << 0)) != 0))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,11 +32,11 @@ func telegramMediaWebpageAttributeFromApiWebpageAttribute(_ attribute: Api.WebPa
|
|||
var files: [TelegramMediaFile] = []
|
||||
files = icons.compactMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
|
||||
return .giftCollection(TelegramMediaWebpageGiftCollectionAttribute(files: files))
|
||||
case let .webPageAttributeStarGiftAuction(apiGift, endDate, centerColor, edgeColor, textColor):
|
||||
case let .webPageAttributeStarGiftAuction(apiGift, endDate):
|
||||
guard let gift = StarGift(apiStarGift: apiGift) else {
|
||||
return nil
|
||||
}
|
||||
return .giftAuction(TelegramMediaWebpageGiftAuctionAttribute(gift: gift, endDate: endDate, centerColor: centerColor, edgeColor: edgeColor, textColor: textColor))
|
||||
return .giftAuction(TelegramMediaWebpageGiftAuctionAttribute(gift: gift, endDate: endDate))
|
||||
case .webPageAttributeStory:
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1167,6 +1167,135 @@ public func authorizeWithPassword(accountManager: AccountManager<TelegramAccount
|
|||
}
|
||||
}
|
||||
|
||||
public final class AuthorizationPasskeyData {
|
||||
public let id: String
|
||||
public let clientData: String
|
||||
public let authenticatorData: Data
|
||||
public let signature: Data
|
||||
public let userHandle: String
|
||||
|
||||
public init(id: String, clientData: String, authenticatorData: Data, signature: Data, userHandle: String) {
|
||||
self.id = id
|
||||
self.clientData = clientData
|
||||
self.authenticatorData = authenticatorData
|
||||
self.signature = signature
|
||||
self.userHandle = userHandle
|
||||
}
|
||||
}
|
||||
|
||||
public final class AuthorizeWithPasskeyResult {
|
||||
public let updatedAccount: UnauthorizedAccount
|
||||
|
||||
init(updatedAccount: UnauthorizedAccount) {
|
||||
self.updatedAccount = updatedAccount
|
||||
}
|
||||
}
|
||||
|
||||
public func authorizeWithPasskey(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, passkey: AuthorizationPasskeyData, foreignDatacenter: (id: Int, authKeyId: Int64)?, forcedPasswordSetupNotice: @escaping (Int32) -> (NoticeEntryKey, CodableEntry)?, syncContacts: Bool) -> Signal<AuthorizeWithPasskeyResult, AuthorizationCodeVerificationError> {
|
||||
let userHandle = passkey.userHandle.components(separatedBy: ":")
|
||||
var targetDatacenterId: Int?
|
||||
if foreignDatacenter == nil && userHandle.count >= 2 {
|
||||
targetDatacenterId = Int(userHandle[0])
|
||||
}
|
||||
|
||||
if let targetDatacenterId, account.masterDatacenterId != Int32(targetDatacenterId) {
|
||||
let initialDatacenterId = account.masterDatacenterId
|
||||
return account.network.getAuthKeyId()
|
||||
|> castError(AuthorizationCodeVerificationError.self)
|
||||
|> mapToSignal { sourceAuthKeyId -> Signal<AuthorizeWithPasskeyResult, AuthorizationCodeVerificationError> in
|
||||
let updatedAccount = account.changedMasterDatacenterId(accountManager: accountManager, masterDatacenterId: Int32(targetDatacenterId))
|
||||
return updatedAccount
|
||||
|> mapToSignalPromotingError { updatedAccount -> Signal<AuthorizeWithPasskeyResult, AuthorizationCodeVerificationError> in
|
||||
return authorizeWithPasskey(accountManager: accountManager, account: updatedAccount, passkey: passkey, foreignDatacenter: (Int(initialDatacenterId), sourceAuthKeyId), forcedPasswordSetupNotice: forcedPasswordSetupNotice, syncContacts: syncContacts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var flags: Int32 = 0
|
||||
if foreignDatacenter != nil {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
return account.network.request(Api.functions.auth.finishPasskeyLogin(flags: flags, credential: .inputPasskeyCredentialPublicKey(id: passkey.id, rawId: passkey.id, response: .inputPasskeyResponseLogin(clientData: .dataJSON(data: passkey.clientData), authenticatorData: Buffer(data: passkey.authenticatorData), signature: Buffer(data: passkey.signature), userHandle: passkey.userHandle)), fromDcId: (foreignDatacenter?.id).flatMap(Int32.init), fromAuthKeyId: foreignDatacenter?.authKeyId), automaticFloodWait: false)
|
||||
|> map { authorization in
|
||||
return .authorization(authorization)
|
||||
}
|
||||
|> `catch` { error -> Signal<AuthorizationCodeResult, AuthorizationCodeVerificationError> in
|
||||
switch (error.errorCode, error.errorDescription ?? "") {
|
||||
case (401, "SESSION_PASSWORD_NEEDED"):
|
||||
return account.network.request(Api.functions.account.getPassword(), automaticFloodWait: false)
|
||||
|> mapError { error -> AuthorizationCodeVerificationError in
|
||||
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||
return .limitExceeded
|
||||
} else {
|
||||
return .generic
|
||||
}
|
||||
}
|
||||
|> mapToSignal { result -> Signal<AuthorizationCodeResult, AuthorizationCodeVerificationError> in
|
||||
switch result {
|
||||
case let .password(_, _, _, _, hint, _, _, _, _, _, _):
|
||||
return .single(.password(hint: hint ?? ""))
|
||||
}
|
||||
}
|
||||
case let (_, errorDescription):
|
||||
if errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||
return .fail(.limitExceeded)
|
||||
} else if errorDescription == "PHONE_CODE_INVALID" || errorDescription == "EMAIL_CODE_INVALID" {
|
||||
return .fail(.invalidCode)
|
||||
} else if errorDescription == "CODE_HASH_EXPIRED" || errorDescription == "PHONE_CODE_EXPIRED" {
|
||||
return .fail(.codeExpired)
|
||||
} else if errorDescription == "PHONE_NUMBER_UNOCCUPIED" {
|
||||
return .single(.signUp)
|
||||
} else if errorDescription == "EMAIL_TOKEN_INVALID" {
|
||||
return .fail(.invalidEmailToken)
|
||||
} else if errorDescription == "EMAIL_ADDRESS_INVALID" {
|
||||
return .fail(.invalidEmailAddress)
|
||||
} else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
}
|
||||
}
|
||||
|> mapToSignal { result -> Signal<AuthorizeWithPasskeyResult, AuthorizationCodeVerificationError> in
|
||||
return account.postbox.transaction { transaction -> Signal<AuthorizeWithPasskeyResult, AuthorizationCodeVerificationError> in
|
||||
switch result {
|
||||
case .signUp:
|
||||
return .fail(.generic)
|
||||
case let .password(hint):
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: nil, code: nil, suggestReset: false, syncContacts: syncContacts)))
|
||||
return .single(AuthorizeWithPasskeyResult(updatedAccount: account))
|
||||
case let .authorization(authorization):
|
||||
switch authorization {
|
||||
case let .authorization(_, otherwiseReloginDays, _, futureAuthToken, user):
|
||||
if let futureAuthToken = futureAuthToken {
|
||||
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
|
||||
}
|
||||
|
||||
let user = TelegramUser(user: user)
|
||||
var isSupportUser = false
|
||||
if let phone = user.phone, phone.hasPrefix("42") {
|
||||
isSupportUser = true
|
||||
}
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil, invalidatedChannels: [])
|
||||
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
|
||||
transaction.setState(state)
|
||||
if let otherwiseReloginDays = otherwiseReloginDays, let value = forcedPasswordSetupNotice(otherwiseReloginDays) {
|
||||
transaction.setNoticeEntry(key: value.0, value: value.1)
|
||||
}
|
||||
return accountManager.transaction { transaction -> AuthorizeWithPasskeyResult in
|
||||
switchToAuthorizedAccount(transaction: transaction, account: account, isSupportUser: isSupportUser)
|
||||
return AuthorizeWithPasskeyResult(updatedAccount: account)
|
||||
}
|
||||
|> castError(AuthorizationCodeVerificationError.self)
|
||||
case .authorizationSignUpRequired:
|
||||
return .fail(.generic)
|
||||
}
|
||||
}
|
||||
}
|
||||
|> mapError { _ -> AuthorizationCodeVerificationError in
|
||||
}
|
||||
|> switchToLatest
|
||||
}
|
||||
}
|
||||
|
||||
public enum PasswordRecoveryRequestError {
|
||||
case limitExceeded
|
||||
case generic
|
||||
|
|
@ -1466,3 +1595,4 @@ func _internal_reportMissingCode(network: Network, phoneNumber: String, phoneCod
|
|||
return .complete()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1065,6 +1065,22 @@ public final class Network: NSObject, MTRequestMessageServiceDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
public func getAuthKeyId() -> Signal<Int64, NoError> {
|
||||
let mtContext = self.mtProto.context
|
||||
let datacenterId = self.datacenterId
|
||||
return Signal { subscriber in
|
||||
MTContext.contextQueue().dispatch(onQueue: {
|
||||
var result: Int64 = 0
|
||||
if let authInfo = mtContext?.authInfoForDatacenter(withId: datacenterId, selector: .persistent) {
|
||||
result = authInfo.authKeyId
|
||||
}
|
||||
subscriber.putNext(result)
|
||||
})
|
||||
|
||||
return EmptyDisposable
|
||||
}
|
||||
}
|
||||
|
||||
public func requestWithAdditionalInfo<T>(_ data: (FunctionDescription, Buffer, DeserializeFunctionResponse<T>), info: NetworkRequestAdditionalInfo, tag: NetworkRequestDependencyTag? = nil, automaticFloodWait: Bool = true, onFloodWaitError: ((String) -> Void)? = nil) -> Signal<NetworkRequestResult<T>, MTRpcError> {
|
||||
let requestService = self.requestService
|
||||
return Signal { subscriber in
|
||||
|
|
|
|||
|
|
@ -499,7 +499,7 @@ private func sendUploadedMessageContent(
|
|||
}
|
||||
|
||||
if let forwardSourceInfoAttribute = forwardSourceInfoAttribute, let sourcePeer = transaction.getPeer(forwardSourceInfoAttribute.messageId.peerId), let sourceInputPeer = apiInputPeer(sourcePeer) {
|
||||
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, replyTo: nil, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: nil, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars, suggestedPost: nil), tag: dependencyTag)
|
||||
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, replyTo: nil, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars, suggestedPost: nil), tag: dependencyTag)
|
||||
|> map(NetworkRequestResult.result)
|
||||
} else {
|
||||
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal"))
|
||||
|
|
|
|||
|
|
@ -360,10 +360,12 @@ func managedUniqueStarGifts(accountPeerId: PeerId, postbox: Postbox, network: Ne
|
|||
releasedBy: nil,
|
||||
valueAmount: nil,
|
||||
valueCurrency: nil,
|
||||
valueUsdAmount: nil,
|
||||
flags: [],
|
||||
themePeerId: nil,
|
||||
peerColor: nil,
|
||||
hostPeerId: nil
|
||||
hostPeerId: nil,
|
||||
minOfferStars: nil
|
||||
)
|
||||
if let entry = CodableEntry(RecentStarGiftItem(gift)) {
|
||||
items.append(OrderedItemListEntry(id: RecentStarGiftItemId(id).rawValue, contents: entry))
|
||||
|
|
|
|||
|
|
@ -1133,7 +1133,7 @@ public final class PendingMessageManager {
|
|||
} else if let inputSourcePeerId = forwardPeerIds.first, let inputSourcePeer = transaction.getPeer(inputSourcePeerId).flatMap(apiInputPeer) {
|
||||
let dependencyTag = PendingMessageRequestDependencyTag(messageId: messages[0].0.id)
|
||||
|
||||
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: inputSourcePeer, id: forwardIds.map { $0.0.id }, randomId: forwardIds.map { $0.1 }, toPeer: inputPeer, topMsgId: topMsgId, replyTo: replyTo, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars, suggestedPost: suggestedPost), tag: dependencyTag)
|
||||
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: inputSourcePeer, id: forwardIds.map { $0.0.id }, randomId: forwardIds.map { $0.1 }, toPeer: inputPeer, topMsgId: topMsgId, replyTo: replyTo, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, effect: nil, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars, suggestedPost: suggestedPost), tag: dependencyTag)
|
||||
} else {
|
||||
assertionFailure()
|
||||
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "Invalid forward source"))
|
||||
|
|
@ -1831,7 +1831,7 @@ public final class PendingMessageManager {
|
|||
}
|
||||
|
||||
if let forwardSourceInfoAttribute = forwardSourceInfoAttribute, let sourcePeer = transaction.getPeer(forwardSourceInfoAttribute.messageId.peerId), let sourceInputPeer = apiInputPeer(sourcePeer) {
|
||||
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, replyTo: replyTo, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars, suggestedPost: suggestedPost), tag: dependencyTag)
|
||||
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, replyTo: replyTo, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, effect: nil, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars, suggestedPost: suggestedPost), tag: dependencyTag)
|
||||
|> map(NetworkRequestResult.result)
|
||||
} else {
|
||||
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal"))
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
|
|||
|
||||
public class Serialization: NSObject, MTSerialization {
|
||||
public func currentLayer() -> UInt {
|
||||
return 218
|
||||
return 220
|
||||
}
|
||||
|
||||
public func parseMessage(_ data: Data!) -> Any! {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ public enum ServerProvidedSuggestion: Equatable {
|
|||
case setupPhoto
|
||||
case setupLoginEmail
|
||||
case setupLoginEmailBlocking
|
||||
case setupPasskey
|
||||
case link(id: String, url: String, title: ServerSuggestionInfo.Item.Text, subtitle: ServerSuggestionInfo.Item.Text)
|
||||
|
||||
init?(string: String) {
|
||||
|
|
@ -56,6 +57,8 @@ public enum ServerProvidedSuggestion: Equatable {
|
|||
self = .setupLoginEmail
|
||||
case "SETUP_LOGIN_EMAIL_NOSKIP":
|
||||
self = .setupLoginEmailBlocking
|
||||
case "SETUP_PASSKEY":
|
||||
self = .setupPasskey
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
|
@ -95,6 +98,8 @@ public enum ServerProvidedSuggestion: Equatable {
|
|||
return "SETUP_LOGIN_EMAIL"
|
||||
case .setupLoginEmailBlocking:
|
||||
return "SETUP_LOGIN_EMAIL_NOSKIP"
|
||||
case .setupPasskey:
|
||||
return "SETUP_PASSKEY"
|
||||
case let .link(id, _, _, _):
|
||||
return id
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ public struct Namespaces {
|
|||
public static let cachedProfileSavedMusic: Int8 = 49
|
||||
public static let cachedChatThemes: Int8 = 50
|
||||
public static let cachedLiveStorySendAsPeers: Int8 = 51
|
||||
public static let cachedGiftUpgradesAttributes: Int8 = 52
|
||||
}
|
||||
|
||||
public struct UnorderedItemList {
|
||||
|
|
|
|||
|
|
@ -255,8 +255,8 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
case paymentRefunded(peerId: PeerId, currency: String, totalAmount: Int64, payload: Data?, transactionId: String)
|
||||
case giftStars(currency: String, amount: Int64, count: Int64, cryptoCurrency: String?, cryptoAmount: Int64?, transactionId: String?)
|
||||
case prizeStars(amount: Int64, isUnclaimed: Bool, boostPeerId: PeerId?, transactionId: String?, giveawayMessageId: MessageId?)
|
||||
case starGift(gift: StarGift, convertStars: Int64?, text: String?, entities: [MessageTextEntity]?, nameHidden: Bool, savedToProfile: Bool, converted: Bool, upgraded: Bool, canUpgrade: Bool, upgradeStars: Int64?, isRefunded: Bool, isPrepaidUpgrade: Bool, upgradeMessageId: Int32?, peerId: EnginePeer.Id?, senderId: EnginePeer.Id?, savedId: Int64?, prepaidUpgradeHash: String?, giftMessageId: Int32?, upgradeSeparate: Bool, isAuctionAcquired: Bool, toPeerId: EnginePeer.Id?)
|
||||
case starGiftUnique(gift: StarGift, isUpgrade: Bool, isTransferred: Bool, savedToProfile: Bool, canExportDate: Int32?, transferStars: Int64?, isRefunded: Bool, isPrepaidUpgrade: Bool, peerId: EnginePeer.Id?, senderId: EnginePeer.Id?, savedId: Int64?, resaleAmount: CurrencyAmount?, canTransferDate: Int32?, canResaleDate: Int32?, dropOriginalDetailsStars: Int64?, assigned: Bool)
|
||||
case starGift(gift: StarGift, convertStars: Int64?, text: String?, entities: [MessageTextEntity]?, nameHidden: Bool, savedToProfile: Bool, converted: Bool, upgraded: Bool, canUpgrade: Bool, upgradeStars: Int64?, isRefunded: Bool, isPrepaidUpgrade: Bool, upgradeMessageId: Int32?, peerId: EnginePeer.Id?, senderId: EnginePeer.Id?, savedId: Int64?, prepaidUpgradeHash: String?, giftMessageId: Int32?, upgradeSeparate: Bool, isAuctionAcquired: Bool, toPeerId: EnginePeer.Id?, number: Int32?)
|
||||
case starGiftUnique(gift: StarGift, isUpgrade: Bool, isTransferred: Bool, savedToProfile: Bool, canExportDate: Int32?, transferStars: Int64?, isRefunded: Bool, isPrepaidUpgrade: Bool, peerId: EnginePeer.Id?, senderId: EnginePeer.Id?, savedId: Int64?, resaleAmount: CurrencyAmount?, canTransferDate: Int32?, canResaleDate: Int32?, dropOriginalDetailsStars: Int64?, assigned: Bool, fromOffer: Bool)
|
||||
case paidMessagesRefunded(count: Int32, stars: Int64)
|
||||
case paidMessagesPriceEdited(stars: Int64, broadcastMessagesAllowed: Bool)
|
||||
case conferenceCall(ConferenceCall)
|
||||
|
|
@ -267,6 +267,8 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
case suggestedPostSuccess(amount: CurrencyAmount)
|
||||
case suggestedPostRefund(SuggestedPostRefund)
|
||||
case suggestedBirthday(TelegramBirthday)
|
||||
case starGiftPurchaseOffer(gift: StarGift, amount: CurrencyAmount, expireDate: Int32, isAccepted: Bool, isDeclined: Bool)
|
||||
case starGiftPurchaseOfferDeclined(gift: StarGift, amount: CurrencyAmount, hasExpired: Bool)
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
|
||||
|
|
@ -394,7 +396,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
}
|
||||
self = .prizeStars(amount: decoder.decodeInt64ForKey("amount", orElse: 0), isUnclaimed: decoder.decodeBoolForKey("unclaimed", orElse: false), boostPeerId: boostPeerId, transactionId: decoder.decodeOptionalStringForKey("transactionId"), giveawayMessageId: giveawayMessageId)
|
||||
case 44:
|
||||
self = .starGift(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, convertStars: decoder.decodeOptionalInt64ForKey("convertStars"), text: decoder.decodeOptionalStringForKey("text"), entities: decoder.decodeOptionalObjectArrayWithDecoderForKey("entities"), nameHidden: decoder.decodeBoolForKey("nameHidden", orElse: false), savedToProfile: decoder.decodeBoolForKey("savedToProfile", orElse: false), converted: decoder.decodeBoolForKey("converted", orElse: false), upgraded: decoder.decodeBoolForKey("upgraded", orElse: false), canUpgrade: decoder.decodeBoolForKey("canUpgrade", orElse: false), upgradeStars: decoder.decodeOptionalInt64ForKey("upgradeStars"), isRefunded: decoder.decodeBoolForKey("isRefunded", orElse: false), isPrepaidUpgrade: decoder.decodeBoolForKey("isPrepaidUpgrade", orElse: false), upgradeMessageId: decoder.decodeOptionalInt32ForKey("upgradeMessageId"), peerId: decoder.decodeOptionalInt64ForKey("peerId").flatMap { EnginePeer.Id($0) }, senderId: decoder.decodeOptionalInt64ForKey("senderId").flatMap { EnginePeer.Id($0) }, savedId: decoder.decodeOptionalInt64ForKey("savedId"), prepaidUpgradeHash: decoder.decodeOptionalStringForKey("prepaidUpgradeHash"), giftMessageId: decoder.decodeOptionalInt32ForKey("giftMessageId"), upgradeSeparate: decoder.decodeOptionalBoolForKey("upgradeSeparate") ?? false, isAuctionAcquired: decoder.decodeOptionalBoolForKey("isAuctionAcquired") ?? false, toPeerId: decoder.decodeOptionalInt64ForKey("toPeerId").flatMap { EnginePeer.Id($0) })
|
||||
self = .starGift(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, convertStars: decoder.decodeOptionalInt64ForKey("convertStars"), text: decoder.decodeOptionalStringForKey("text"), entities: decoder.decodeOptionalObjectArrayWithDecoderForKey("entities"), nameHidden: decoder.decodeBoolForKey("nameHidden", orElse: false), savedToProfile: decoder.decodeBoolForKey("savedToProfile", orElse: false), converted: decoder.decodeBoolForKey("converted", orElse: false), upgraded: decoder.decodeBoolForKey("upgraded", orElse: false), canUpgrade: decoder.decodeBoolForKey("canUpgrade", orElse: false), upgradeStars: decoder.decodeOptionalInt64ForKey("upgradeStars"), isRefunded: decoder.decodeBoolForKey("isRefunded", orElse: false), isPrepaidUpgrade: decoder.decodeBoolForKey("isPrepaidUpgrade", orElse: false), upgradeMessageId: decoder.decodeOptionalInt32ForKey("upgradeMessageId"), peerId: decoder.decodeOptionalInt64ForKey("peerId").flatMap { EnginePeer.Id($0) }, senderId: decoder.decodeOptionalInt64ForKey("senderId").flatMap { EnginePeer.Id($0) }, savedId: decoder.decodeOptionalInt64ForKey("savedId"), prepaidUpgradeHash: decoder.decodeOptionalStringForKey("prepaidUpgradeHash"), giftMessageId: decoder.decodeOptionalInt32ForKey("giftMessageId"), upgradeSeparate: decoder.decodeOptionalBoolForKey("upgradeSeparate") ?? false, isAuctionAcquired: decoder.decodeOptionalBoolForKey("isAuctionAcquired") ?? false, toPeerId: decoder.decodeOptionalInt64ForKey("toPeerId").flatMap { EnginePeer.Id($0) }, number: decoder.decodeOptionalInt32ForKey("number"))
|
||||
case 45:
|
||||
var resaleAmount: CurrencyAmount?
|
||||
if let amount = decoder.decodeCodable(CurrencyAmount.self, forKey: "resaleAmount") {
|
||||
|
|
@ -402,7 +404,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
} else if let stars = decoder.decodeOptionalInt64ForKey("resaleStars") {
|
||||
resaleAmount = CurrencyAmount(amount: StarsAmount(value: stars, nanos: 0), currency: .stars)
|
||||
}
|
||||
self = .starGiftUnique(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, isUpgrade: decoder.decodeBoolForKey("isUpgrade", orElse: false), isTransferred: decoder.decodeBoolForKey("isTransferred", orElse: false), savedToProfile: decoder.decodeBoolForKey("savedToProfile", orElse: false), canExportDate: decoder.decodeOptionalInt32ForKey("canExportDate"), transferStars: decoder.decodeOptionalInt64ForKey("transferStars"), isRefunded: decoder.decodeBoolForKey("isRefunded", orElse: false), isPrepaidUpgrade: decoder.decodeBoolForKey("isPrepaidUpgrade", orElse: false), peerId: decoder.decodeOptionalInt64ForKey("peerId").flatMap { EnginePeer.Id($0) }, senderId: decoder.decodeOptionalInt64ForKey("senderId").flatMap { EnginePeer.Id($0) }, savedId: decoder.decodeOptionalInt64ForKey("savedId"), resaleAmount: resaleAmount, canTransferDate: decoder.decodeOptionalInt32ForKey("canTransferDate"), canResaleDate: decoder.decodeOptionalInt32ForKey("canResaleDate"), dropOriginalDetailsStars: decoder.decodeOptionalInt64ForKey("dropOriginalDetailsStars"), assigned: decoder.decodeBoolForKey("assigned", orElse: false))
|
||||
self = .starGiftUnique(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, isUpgrade: decoder.decodeBoolForKey("isUpgrade", orElse: false), isTransferred: decoder.decodeBoolForKey("isTransferred", orElse: false), savedToProfile: decoder.decodeBoolForKey("savedToProfile", orElse: false), canExportDate: decoder.decodeOptionalInt32ForKey("canExportDate"), transferStars: decoder.decodeOptionalInt64ForKey("transferStars"), isRefunded: decoder.decodeBoolForKey("isRefunded", orElse: false), isPrepaidUpgrade: decoder.decodeBoolForKey("isPrepaidUpgrade", orElse: false), peerId: decoder.decodeOptionalInt64ForKey("peerId").flatMap { EnginePeer.Id($0) }, senderId: decoder.decodeOptionalInt64ForKey("senderId").flatMap { EnginePeer.Id($0) }, savedId: decoder.decodeOptionalInt64ForKey("savedId"), resaleAmount: resaleAmount, canTransferDate: decoder.decodeOptionalInt32ForKey("canTransferDate"), canResaleDate: decoder.decodeOptionalInt32ForKey("canResaleDate"), dropOriginalDetailsStars: decoder.decodeOptionalInt64ForKey("dropOriginalDetailsStars"), assigned: decoder.decodeBoolForKey("assigned", orElse: false), fromOffer: decoder.decodeBoolForKey("fromOffer", orElse: false))
|
||||
case 46:
|
||||
self = .paidMessagesRefunded(count: decoder.decodeInt32ForKey("count", orElse: 0), stars: decoder.decodeInt64ForKey("stars", orElse: 0))
|
||||
case 47:
|
||||
|
|
@ -434,6 +436,10 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
self = .suggestedPostRefund(decoder.decodeCodable(SuggestedPostRefund.self, forKey: "s") ?? SuggestedPostRefund(isUserInitiated: true))
|
||||
case 55:
|
||||
self = .suggestedBirthday(decoder.decodeCodable(TelegramBirthday.self, forKey: "birthday") ?? TelegramBirthday(day: 1, month: 1, year: nil))
|
||||
case 56:
|
||||
self = .starGiftPurchaseOffer(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, amount: decoder.decodeCodable(CurrencyAmount.self, forKey: "amount")!, expireDate: decoder.decodeInt32ForKey("expireDate", orElse: 0), isAccepted: decoder.decodeBoolForKey("isAccepted", orElse: false), isDeclined: decoder.decodeBoolForKey("isDeclined", orElse: false))
|
||||
case 57:
|
||||
self = .starGiftPurchaseOfferDeclined(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, amount: decoder.decodeCodable(CurrencyAmount.self, forKey: "amount")!, hasExpired: decoder.decodeBoolForKey("hasExpired", orElse: false))
|
||||
default:
|
||||
self = .unknown
|
||||
}
|
||||
|
|
@ -728,7 +734,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
} else {
|
||||
encoder.encodeNil(forKey: "giveawayMsgId")
|
||||
}
|
||||
case let .starGift(gift, convertStars, text, entities, nameHidden, savedToProfile, converted, upgraded, canUpgrade, upgradeStars, isRefunded, isPrepaidUpgrade, upgradeMessageId, peerId, senderId, savedId, prepaidUpgradeHash, giftMessageId, upgradeSeparate, isAuctionAcquired, toPeerId):
|
||||
case let .starGift(gift, convertStars, text, entities, nameHidden, savedToProfile, converted, upgraded, canUpgrade, upgradeStars, isRefunded, isPrepaidUpgrade, upgradeMessageId, peerId, senderId, savedId, prepaidUpgradeHash, giftMessageId, upgradeSeparate, isAuctionAcquired, toPeerId, number):
|
||||
encoder.encodeInt32(44, forKey: "_rawValue")
|
||||
encoder.encodeObject(gift, forKey: "gift")
|
||||
if let convertStars {
|
||||
|
|
@ -792,7 +798,12 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
} else {
|
||||
encoder.encodeNil(forKey: "toPeerId")
|
||||
}
|
||||
case let .starGiftUnique(gift, isUpgrade, isTransferred, savedToProfile, canExportDate, transferStars, isRefunded, isPrepaidUpgrade, peerId, senderId, savedId, resaleAmount, canTransferDate, canResaleDate, dropOriginalDetailsStars, assigned):
|
||||
if let number {
|
||||
encoder.encodeInt32(number, forKey: "number")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "number")
|
||||
}
|
||||
case let .starGiftUnique(gift, isUpgrade, isTransferred, savedToProfile, canExportDate, transferStars, isRefunded, isPrepaidUpgrade, peerId, senderId, savedId, resaleAmount, canTransferDate, canResaleDate, dropOriginalDetailsStars, assigned, fromOffer):
|
||||
encoder.encodeInt32(45, forKey: "_rawValue")
|
||||
encoder.encodeObject(gift, forKey: "gift")
|
||||
encoder.encodeBool(isUpgrade, forKey: "isUpgrade")
|
||||
|
|
@ -846,6 +857,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
encoder.encodeNil(forKey: "dropOriginalDetailsStars")
|
||||
}
|
||||
encoder.encodeBool(assigned, forKey: "assigned")
|
||||
encoder.encodeBool(fromOffer, forKey: "fromOffer")
|
||||
case let .paidMessagesRefunded(count, stars):
|
||||
encoder.encodeInt32(46, forKey: "_rawValue")
|
||||
encoder.encodeInt32(count, forKey: "count")
|
||||
|
|
@ -899,6 +911,18 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
case let .suggestedBirthday(birthday):
|
||||
encoder.encodeInt32(55, forKey: "_rawValue")
|
||||
encoder.encodeCodable(birthday, forKey: "birthday")
|
||||
case let .starGiftPurchaseOffer(gift, amount, expireDate, isAccepted, isDeclined):
|
||||
encoder.encodeInt32(56, forKey: "_rawValue")
|
||||
encoder.encodeObject(gift, forKey: "gift")
|
||||
encoder.encodeCodable(amount, forKey: "amount")
|
||||
encoder.encodeInt32(expireDate, forKey: "expireDate")
|
||||
encoder.encodeBool(isAccepted, forKey: "isAccepted")
|
||||
encoder.encodeBool(isDeclined, forKey: "isDeclined")
|
||||
case let .starGiftPurchaseOfferDeclined(gift, amount, hasExpired):
|
||||
encoder.encodeInt32(57, forKey: "_rawValue")
|
||||
encoder.encodeObject(gift, forKey: "gift")
|
||||
encoder.encodeCodable(amount, forKey: "amount")
|
||||
encoder.encodeBool(hasExpired, forKey: "hasExpired")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -926,7 +950,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
return [peerId]
|
||||
case let .prizeStars(_, _, boostPeerId, _, _):
|
||||
return boostPeerId.flatMap { [$0] } ?? []
|
||||
case let .starGift(gift, _, _, _, _, _, _, _, _, _, _, _, _, peerId, senderId, _, _, _, _, _, toPeerId):
|
||||
case let .starGift(gift, _, _, _, _, _, _, _, _, _, _, _, _, peerId, senderId, _, _, _, _, _, toPeerId, _):
|
||||
var peerIds: [PeerId] = []
|
||||
if let peerId {
|
||||
peerIds.append(peerId)
|
||||
|
|
@ -941,7 +965,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
peerIds.append(toPeerId)
|
||||
}
|
||||
return peerIds
|
||||
case let .starGiftUnique(gift, _, _, _, _, _, _, _, peerId, senderId, _, _, _, _, _, _):
|
||||
case let .starGiftUnique(gift, _, _, _, _, _, _, _, peerId, senderId, _, _, _, _, _, _, _):
|
||||
var peerIds: [PeerId] = []
|
||||
if let peerId {
|
||||
peerIds.append(peerId)
|
||||
|
|
|
|||
|
|
@ -210,52 +210,28 @@ public final class TelegramMediaWebpageGiftAuctionAttribute: PostboxCoding, Equa
|
|||
if lhs.endDate != rhs.endDate {
|
||||
return false
|
||||
}
|
||||
if lhs.centerColor != rhs.centerColor {
|
||||
return false
|
||||
}
|
||||
if lhs.edgeColor != rhs.edgeColor {
|
||||
return false
|
||||
}
|
||||
if lhs.textColor != rhs.textColor {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public let gift: StarGift
|
||||
public let endDate: Int32
|
||||
public let centerColor: Int32
|
||||
public let edgeColor: Int32
|
||||
public let textColor: Int32
|
||||
|
||||
|
||||
public init(
|
||||
gift: StarGift,
|
||||
endDate: Int32,
|
||||
centerColor: Int32,
|
||||
edgeColor: Int32,
|
||||
textColor: Int32
|
||||
endDate: Int32
|
||||
) {
|
||||
self.gift = gift
|
||||
self.endDate = endDate
|
||||
self.centerColor = centerColor
|
||||
self.edgeColor = edgeColor
|
||||
self.textColor = textColor
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.gift = decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift
|
||||
self.endDate = decoder.decodeInt32ForKey("endDate", orElse: 0)
|
||||
self.centerColor = decoder.decodeInt32ForKey("centerColor", orElse: 0)
|
||||
self.edgeColor = decoder.decodeInt32ForKey("edgeColor", orElse: 0)
|
||||
self.textColor = decoder.decodeInt32ForKey("textColor", orElse: 0)
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeObject(self.gift, forKey: "gift")
|
||||
encoder.encodeInt32(self.endDate, forKey: "endDate")
|
||||
encoder.encodeInt32(self.centerColor, forKey: "centerColor")
|
||||
encoder.encodeInt32(self.edgeColor, forKey: "edgeColor")
|
||||
encoder.encodeInt32(self.textColor, forKey: "textColor")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,10 +25,9 @@ public class TranslationMessageAttribute: MessageAttribute, Equatable {
|
|||
public let entities: [MessageTextEntity]
|
||||
public let toLang: String
|
||||
|
||||
public let additional:[Additional]
|
||||
public let additional: [Additional]
|
||||
public let pollSolution: Additional?
|
||||
|
||||
|
||||
public var associatedPeerIds: [PeerId] {
|
||||
return []
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ public extension TelegramEngineUnauthorized {
|
|||
return _internal_reportMissingCode(network: self.account.network, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, mnc: mnc)
|
||||
}
|
||||
|
||||
public func requestPasskeyLoginData(apiId: Int32, apiHash: String) -> Signal<String?, NoError> {
|
||||
return _internal_requestPasskeyLoginData(network: self.account.network, apiId: apiId, apiHash: apiHash)
|
||||
}
|
||||
|
||||
public func state() -> Signal<TelegramEngineAuthorizationState?, NoError> {
|
||||
return self.account.postbox.stateView()
|
||||
|> map { view -> TelegramEngineAuthorizationState? in
|
||||
|
|
@ -210,6 +214,22 @@ public extension TelegramEngine {
|
|||
public func reportMissingCode(phoneNumber: String, phoneCodeHash: String, mnc: String) -> Signal<Never, ReportMissingCodeError> {
|
||||
return _internal_reportMissingCode(network: self.account.network, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, mnc: mnc)
|
||||
}
|
||||
|
||||
public func passkeysData() -> Signal<[TelegramPasskey], NoError> {
|
||||
return _internal_passkeysData(network: self.account.network)
|
||||
}
|
||||
|
||||
public func requestPasskeyRegistration() -> Signal<String?, NoError> {
|
||||
return _internal_requestPasskeyRegistration(network: self.account.network)
|
||||
}
|
||||
|
||||
public func requestCreatePasskey(id: String, clientData: String, attestationObject: Data) -> Signal<TelegramPasskey?, NoError> {
|
||||
return _internal_requestCreatePasskey(network: self.account.network, id: id, clientData: clientData, attestationObject: attestationObject)
|
||||
}
|
||||
|
||||
public func deletePasskey(id: String) -> Signal<Never, NoError> {
|
||||
return _internal_deletePasskey(network: self.account.network, id: id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ func _internal_clearHistoryInteractively(postbox: Postbox, peerId: PeerId, threa
|
|||
func _internal_clearAuthorHistory(account: Account, peerId: PeerId, memberId: PeerId) -> Signal<Void, NoError> {
|
||||
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||
if let peer = transaction.getPeer(peerId), let memberPeer = transaction.getPeer(memberId), let inputChannel = apiInputChannel(peer), let inputUser = apiInputPeer(memberPeer) {
|
||||
let signal = account.network.request(Api.functions.channels.deleteParticipantHistory(channel: inputChannel, participant: inputUser))
|
||||
let signal = peer.isMonoForum ? .fail(true) : account.network.request(Api.functions.channels.deleteParticipantHistory(channel: inputChannel, participant: inputUser))
|
||||
|> map { result -> Api.messages.AffectedHistory? in
|
||||
return result
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ func _internal_forwardGameWithScore(account: Account, messageId: MessageId, to p
|
|||
flags |= (1 << 13)
|
||||
}
|
||||
|
||||
return account.network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: fromInputPeer, id: [messageId.id], randomId: [Int64.random(in: Int64.min ... Int64.max)], toPeer: toInputPeer, topMsgId: threadId.flatMap { Int32(clamping: $0) }, replyTo: nil, scheduleDate: nil, scheduleRepeatPeriod: nil, sendAs: sendAsInputPeer, quickReplyShortcut: nil, videoTimestamp: nil, allowPaidStars: nil, suggestedPost: nil))
|
||||
return account.network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: fromInputPeer, id: [messageId.id], randomId: [Int64.random(in: Int64.min ... Int64.max)], toPeer: toInputPeer, topMsgId: threadId.flatMap { Int32(clamping: $0) }, replyTo: nil, scheduleDate: nil, scheduleRepeatPeriod: nil, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, videoTimestamp: nil, allowPaidStars: nil, suggestedPost: nil))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
|
|
|
|||
|
|
@ -593,7 +593,7 @@ public extension TelegramEngine {
|
|||
}
|
||||
|
||||
public func translate(texts: [(String, [MessageTextEntity])], toLang: String) -> Signal<[(String, [MessageTextEntity])], TranslationError> {
|
||||
return _internal_translate_texts(network: self.account.network, texts: texts, toLang: toLang)
|
||||
return _internal_translateTexts(network: self.account.network, texts: texts, toLang: toLang)
|
||||
}
|
||||
|
||||
public func translateMessages(messageIds: [EngineMessage.Id], fromLang: String?, toLang: String, enableLocalIfPossible: Bool) -> Signal<Never, TranslationError> {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func _internal_translate(network: Network, text: String, toLang: String, entitie
|
|||
}
|
||||
}
|
||||
|
||||
func _internal_translate_texts(network: Network, texts: [(String, [MessageTextEntity])], toLang: String) -> Signal<[(String, [MessageTextEntity])], TranslationError> {
|
||||
func _internal_translateTexts(network: Network, texts: [(String, [MessageTextEntity])], toLang: String) -> Signal<[(String, [MessageTextEntity])], TranslationError> {
|
||||
var flags: Int32 = 0
|
||||
flags |= (1 << 1)
|
||||
|
||||
|
|
@ -112,9 +112,9 @@ private func _internal_translateMessagesByPeerId(account: Account, peerId: Engin
|
|||
return .never()
|
||||
}
|
||||
|
||||
let polls = messages.compactMap { msg in
|
||||
if let poll = msg.media.first as? TelegramMediaPoll {
|
||||
return (poll, msg.id)
|
||||
let polls = messages.compactMap { message in
|
||||
if let poll = message.media.first as? TelegramMediaPoll {
|
||||
return (poll, message.id)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -128,9 +128,19 @@ private func _internal_translateMessagesByPeerId(account: Account, peerId: Engin
|
|||
if let solution = poll.results.solution {
|
||||
texts.append((solution.text, solution.entities))
|
||||
}
|
||||
return _internal_translate_texts(network: account.network, texts: texts, toLang: toLang)
|
||||
return _internal_translateTexts(network: account.network, texts: texts, toLang: toLang)
|
||||
}
|
||||
|
||||
let audioTranscriptions = messages.compactMap { message in
|
||||
if let audioTranscription = message.attributes.first(where: { $0 is AudioTranscriptionMessageAttribute }) as? AudioTranscriptionMessageAttribute, !audioTranscription.text.isEmpty && !audioTranscription.isPending {
|
||||
return (audioTranscription.text, message.id)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
let audioTranscriptionsSignals = audioTranscriptions.map { (text, id) in
|
||||
return _internal_translate(network: account.network, text: text, toLang: toLang)
|
||||
}
|
||||
|
||||
var flags: Int32 = 0
|
||||
flags |= (1 << 0)
|
||||
|
|
@ -197,8 +207,8 @@ private func _internal_translateMessagesByPeerId(account: Account, peerId: Engin
|
|||
}
|
||||
}
|
||||
|
||||
return combineLatest(msgs, combineLatest(pollSignals))
|
||||
|> mapToSignal { (result, pollResults) -> Signal<Void, TranslationError> in
|
||||
return combineLatest(msgs, combineLatest(pollSignals), combineLatest(audioTranscriptionsSignals))
|
||||
|> mapToSignal { (result, pollResults, audioTranscriptionsResults) -> Signal<Void, TranslationError> in
|
||||
return account.postbox.transaction { transaction in
|
||||
if case let .translateResult(results) = result {
|
||||
var index = 0
|
||||
|
|
@ -218,6 +228,7 @@ private func _internal_translateMessagesByPeerId(account: Account, peerId: Engin
|
|||
index += 1
|
||||
}
|
||||
}
|
||||
|
||||
if !pollResults.isEmpty {
|
||||
for (i, poll) in polls.enumerated() {
|
||||
let result = pollResults[i]
|
||||
|
|
@ -231,12 +242,12 @@ private func _internal_translateMessagesByPeerId(account: Account, peerId: Engin
|
|||
if translated.0.isEmpty {
|
||||
translated = (poll.0.options[i].text, poll.0.options[i].entities)
|
||||
}
|
||||
attrOptions.append(.init(text: translated.0, entities: translated.1))
|
||||
attrOptions.append(TranslationMessageAttribute.Additional(text: translated.0, entities: translated.1))
|
||||
}
|
||||
|
||||
let solution: TranslationMessageAttribute.Additional?
|
||||
if result.count > 1 + poll.0.options.count, !result[result.count - 1].0.isEmpty {
|
||||
solution = .init(text: result[result.count - 1].0, entities: result[result.count - 1].1)
|
||||
solution = TranslationMessageAttribute.Additional(text: result[result.count - 1].0, entities: result[result.count - 1].1)
|
||||
} else {
|
||||
solution = nil
|
||||
}
|
||||
|
|
@ -251,6 +262,22 @@ private func _internal_translateMessagesByPeerId(account: Account, peerId: Engin
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !audioTranscriptionsResults.isEmpty {
|
||||
for (i, audioTranscription) in audioTranscriptions.enumerated() {
|
||||
if let result = audioTranscriptionsResults[i] {
|
||||
transaction.updateMessage(audioTranscription.1, update: { currentMessage in
|
||||
let storeForwardInfo = currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init)
|
||||
var attributes = currentMessage.attributes.filter { !($0 is TranslationMessageAttribute) }
|
||||
|
||||
let updatedAttribute: TranslationMessageAttribute = TranslationMessageAttribute(text: result.0, entities: result.1, additional: [], pollSolution: nil, toLang: toLang)
|
||||
attributes.append(updatedAttribute)
|
||||
|
||||
return .update(StoreMessage(id: currentMessage.id, customStableId: nil, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|> castError(TranslationError.self)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
case lockedUntilDate
|
||||
case auctionSlug
|
||||
case auctionGiftsPerRound
|
||||
case auctionStartDate
|
||||
case upgradeVariantsCount
|
||||
case background
|
||||
}
|
||||
|
||||
public struct Availability: Equatable, Codable, PostboxCoding {
|
||||
|
|
@ -169,6 +172,40 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
}
|
||||
}
|
||||
|
||||
public struct Background: Equatable, Codable, PostboxCoding {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case centerColor
|
||||
case edgeColor
|
||||
case textColor
|
||||
}
|
||||
|
||||
public let centerColor: Int32
|
||||
public let edgeColor: Int32
|
||||
public let textColor: Int32
|
||||
|
||||
public init(
|
||||
centerColor: Int32,
|
||||
edgeColor: Int32,
|
||||
textColor: Int32
|
||||
) {
|
||||
self.centerColor = centerColor
|
||||
self.edgeColor = edgeColor
|
||||
self.textColor = textColor
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.centerColor = decoder.decodeInt32ForKey(CodingKeys.centerColor.rawValue, orElse: 0)
|
||||
self.edgeColor = decoder.decodeInt32ForKey(CodingKeys.edgeColor.rawValue, orElse: 0)
|
||||
self.textColor = decoder.decodeInt32ForKey(CodingKeys.textColor.rawValue, orElse: 0)
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeInt32(self.centerColor, forKey: CodingKeys.centerColor.rawValue)
|
||||
encoder.encodeInt32(self.edgeColor, forKey: CodingKeys.edgeColor.rawValue)
|
||||
encoder.encodeInt32(self.textColor, forKey: CodingKeys.textColor.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
public enum DecodingError: Error {
|
||||
case generic
|
||||
}
|
||||
|
|
@ -187,8 +224,11 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
public let lockedUntilDate: Int32?
|
||||
public let auctionSlug: String?
|
||||
public let auctionGiftsPerRound: Int32?
|
||||
public let auctionStartDate: Int32?
|
||||
public let upgradeVariantsCount: Int32?
|
||||
public let background: Background?
|
||||
|
||||
public init(id: Int64, title: String?, file: TelegramMediaFile, price: Int64, convertStars: Int64, availability: Availability?, soldOut: SoldOut?, flags: Flags, upgradeStars: Int64?, releasedBy: EnginePeer.Id?, perUserLimit: PerUserLimit?, lockedUntilDate: Int32?, auctionSlug: String?, auctionGiftsPerRound: Int32?) {
|
||||
public init(id: Int64, title: String?, file: TelegramMediaFile, price: Int64, convertStars: Int64, availability: Availability?, soldOut: SoldOut?, flags: Flags, upgradeStars: Int64?, releasedBy: EnginePeer.Id?, perUserLimit: PerUserLimit?, lockedUntilDate: Int32?, auctionSlug: String?, auctionGiftsPerRound: Int32?, auctionStartDate: Int32?, upgradeVariantsCount: Int32?, background: Background?) {
|
||||
self.id = id
|
||||
self.title = title
|
||||
self.file = file
|
||||
|
|
@ -203,6 +243,9 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
self.lockedUntilDate = lockedUntilDate
|
||||
self.auctionSlug = auctionSlug
|
||||
self.auctionGiftsPerRound = auctionGiftsPerRound
|
||||
self.auctionStartDate = auctionStartDate
|
||||
self.upgradeVariantsCount = upgradeVariantsCount
|
||||
self.background = background
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
|
|
@ -227,6 +270,9 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
self.lockedUntilDate = try container.decodeIfPresent(Int32.self, forKey: .lockedUntilDate)
|
||||
self.auctionSlug = try container.decodeIfPresent(String.self, forKey: .auctionSlug)
|
||||
self.auctionGiftsPerRound = try container.decodeIfPresent(Int32.self, forKey: .auctionGiftsPerRound)
|
||||
self.auctionStartDate = try container.decodeIfPresent(Int32.self, forKey: .auctionStartDate)
|
||||
self.upgradeVariantsCount = try container.decodeIfPresent(Int32.self, forKey: .upgradeVariantsCount)
|
||||
self.background = try container.decodeIfPresent(Background.self, forKey: .background)
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
|
|
@ -244,6 +290,9 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
self.lockedUntilDate = decoder.decodeOptionalInt32ForKey(CodingKeys.lockedUntilDate.rawValue)
|
||||
self.auctionSlug = decoder.decodeOptionalStringForKey(CodingKeys.auctionSlug.rawValue)
|
||||
self.auctionGiftsPerRound = decoder.decodeOptionalInt32ForKey(CodingKeys.auctionGiftsPerRound.rawValue)
|
||||
self.auctionStartDate = decoder.decodeOptionalInt32ForKey(CodingKeys.auctionStartDate.rawValue)
|
||||
self.upgradeVariantsCount = decoder.decodeOptionalInt32ForKey(CodingKeys.upgradeVariantsCount.rawValue)
|
||||
self.background = decoder.decodeObjectForKey(CodingKeys.background.rawValue, decoder: { StarGift.Gift.Background(decoder: $0) }) as? StarGift.Gift.Background
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
|
|
@ -267,6 +316,9 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
try container.encodeIfPresent(self.lockedUntilDate, forKey: .lockedUntilDate)
|
||||
try container.encodeIfPresent(self.auctionSlug, forKey: .auctionSlug)
|
||||
try container.encodeIfPresent(self.auctionGiftsPerRound, forKey: .auctionGiftsPerRound)
|
||||
try container.encodeIfPresent(self.auctionStartDate, forKey: .auctionStartDate)
|
||||
try container.encodeIfPresent(self.upgradeVariantsCount, forKey: .upgradeVariantsCount)
|
||||
try container.encodeIfPresent(self.background, forKey: .background)
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
|
|
@ -320,6 +372,21 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
} else {
|
||||
encoder.encodeNil(forKey: CodingKeys.auctionGiftsPerRound.rawValue)
|
||||
}
|
||||
if let auctionStartDate = self.auctionStartDate {
|
||||
encoder.encodeInt32(auctionStartDate, forKey: CodingKeys.auctionStartDate.rawValue)
|
||||
} else {
|
||||
encoder.encodeNil(forKey: CodingKeys.auctionStartDate.rawValue)
|
||||
}
|
||||
if let upgradeVariantsCount = self.upgradeVariantsCount {
|
||||
encoder.encodeInt32(upgradeVariantsCount, forKey: CodingKeys.upgradeVariantsCount.rawValue)
|
||||
} else {
|
||||
encoder.encodeNil(forKey: CodingKeys.upgradeVariantsCount.rawValue)
|
||||
}
|
||||
if let background = self.background {
|
||||
encoder.encodeObject(background, forKey: CodingKeys.background.rawValue)
|
||||
} else {
|
||||
encoder.encodeNil(forKey: CodingKeys.background.rawValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -342,10 +409,12 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
case releasedBy
|
||||
case valueAmount
|
||||
case valueCurrency
|
||||
case valueUsdAmount
|
||||
case flags
|
||||
case themePeerId
|
||||
case peerColor
|
||||
case hostPeerId
|
||||
case minOfferStars
|
||||
}
|
||||
|
||||
public struct Flags: OptionSet {
|
||||
|
|
@ -631,12 +700,14 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
public let releasedBy: EnginePeer.Id?
|
||||
public let valueAmount: Int64?
|
||||
public let valueCurrency: String?
|
||||
public let valueUsdAmount: Int64?
|
||||
public let flags: Flags
|
||||
public let themePeerId: EnginePeer.Id?
|
||||
public let peerColor: PeerCollectibleColor?
|
||||
public let hostPeerId: EnginePeer.Id?
|
||||
public let minOfferStars: Int64?
|
||||
|
||||
public init(id: Int64, giftId: Int64, title: String, number: Int32, slug: String, owner: Owner, attributes: [Attribute], availability: Availability, giftAddress: String?, resellAmounts: [CurrencyAmount]?, resellForTonOnly: Bool, releasedBy: EnginePeer.Id?, valueAmount: Int64?, valueCurrency: String?, flags: Flags, themePeerId: EnginePeer.Id?, peerColor: PeerCollectibleColor?, hostPeerId: EnginePeer.Id?) {
|
||||
public init(id: Int64, giftId: Int64, title: String, number: Int32, slug: String, owner: Owner, attributes: [Attribute], availability: Availability, giftAddress: String?, resellAmounts: [CurrencyAmount]?, resellForTonOnly: Bool, releasedBy: EnginePeer.Id?, valueAmount: Int64?, valueCurrency: String?, valueUsdAmount: Int64?, flags: Flags, themePeerId: EnginePeer.Id?, peerColor: PeerCollectibleColor?, hostPeerId: EnginePeer.Id?, minOfferStars: Int64?) {
|
||||
self.id = id
|
||||
self.giftId = giftId
|
||||
self.title = title
|
||||
|
|
@ -651,10 +722,12 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
self.releasedBy = releasedBy
|
||||
self.valueAmount = valueAmount
|
||||
self.valueCurrency = valueCurrency
|
||||
self.valueUsdAmount = valueUsdAmount
|
||||
self.flags = flags
|
||||
self.themePeerId = themePeerId
|
||||
self.peerColor = peerColor
|
||||
self.hostPeerId = hostPeerId
|
||||
self.minOfferStars = minOfferStars
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
|
|
@ -687,10 +760,12 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
self.releasedBy = try container.decodeIfPresent(EnginePeer.Id.self, forKey: .releasedBy)
|
||||
self.valueAmount = try container.decodeIfPresent(Int64.self, forKey: .valueAmount)
|
||||
self.valueCurrency = try container.decodeIfPresent(String.self, forKey: .valueCurrency)
|
||||
self.valueUsdAmount = try container.decodeIfPresent(Int64.self, forKey: .valueUsdAmount)
|
||||
self.flags = try container.decodeIfPresent(Int32.self, forKey: .flags).flatMap { Flags(rawValue: $0) } ?? []
|
||||
self.themePeerId = try container.decodeIfPresent(Int64.self, forKey: .themePeerId).flatMap { EnginePeer.Id($0) }
|
||||
self.peerColor = try container.decodeIfPresent(PeerCollectibleColor.self, forKey: .peerColor)
|
||||
self.hostPeerId = try container.decodeIfPresent(Int64.self, forKey: .hostPeerId).flatMap { EnginePeer.Id($0) }
|
||||
self.minOfferStars = try container.decodeIfPresent(Int64.self, forKey: .minOfferStars)
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
|
|
@ -722,10 +797,12 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
self.releasedBy = decoder.decodeOptionalInt64ForKey(CodingKeys.releasedBy.rawValue).flatMap { EnginePeer.Id($0) }
|
||||
self.valueAmount = decoder.decodeOptionalInt64ForKey(CodingKeys.valueAmount.rawValue)
|
||||
self.valueCurrency = decoder.decodeOptionalStringForKey(CodingKeys.valueCurrency.rawValue)
|
||||
self.valueUsdAmount = decoder.decodeOptionalInt64ForKey(CodingKeys.valueUsdAmount.rawValue)
|
||||
self.flags = decoder.decodeOptionalInt32ForKey(CodingKeys.flags.rawValue).flatMap { Flags(rawValue: $0) } ?? []
|
||||
self.themePeerId = decoder.decodeOptionalInt64ForKey(CodingKeys.themePeerId.rawValue).flatMap { EnginePeer.Id($0) }
|
||||
self.peerColor = decoder.decodeCodable(PeerCollectibleColor.self, forKey: CodingKeys.peerColor.rawValue)
|
||||
self.hostPeerId = decoder.decodeOptionalInt64ForKey(CodingKeys.hostPeerId.rawValue).flatMap { EnginePeer.Id($0) }
|
||||
self.minOfferStars = decoder.decodeOptionalInt64ForKey(CodingKeys.minOfferStars.rawValue)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
|
|
@ -751,10 +828,12 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
try container.encodeIfPresent(self.releasedBy, forKey: .releasedBy)
|
||||
try container.encodeIfPresent(self.valueAmount, forKey: .valueAmount)
|
||||
try container.encodeIfPresent(self.valueCurrency, forKey: .valueCurrency)
|
||||
try container.encodeIfPresent(self.valueUsdAmount, forKey: .valueUsdAmount)
|
||||
try container.encode(self.flags.rawValue, forKey: .flags)
|
||||
try container.encodeIfPresent(self.themePeerId?.toInt64(), forKey: .themePeerId)
|
||||
try container.encodeIfPresent(self.peerColor, forKey: .peerColor)
|
||||
try container.encodeIfPresent(self.hostPeerId?.toInt64(), forKey: .hostPeerId)
|
||||
try container.encodeIfPresent(self.minOfferStars, forKey: .minOfferStars)
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
|
|
@ -796,6 +875,11 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
encoder.encodeNil(forKey: CodingKeys.valueAmount.rawValue)
|
||||
encoder.encodeNil(forKey: CodingKeys.valueCurrency.rawValue)
|
||||
}
|
||||
if let valueUsdAmount = self.valueUsdAmount {
|
||||
encoder.encodeInt64(valueUsdAmount, forKey: CodingKeys.valueUsdAmount.rawValue)
|
||||
} else {
|
||||
encoder.encodeNil(forKey: CodingKeys.valueUsdAmount.rawValue)
|
||||
}
|
||||
encoder.encodeInt32(self.flags.rawValue, forKey: CodingKeys.flags.rawValue)
|
||||
if let themePeerId = self.themePeerId {
|
||||
encoder.encodeInt64(themePeerId.toInt64(), forKey: CodingKeys.themePeerId.rawValue)
|
||||
|
|
@ -812,6 +896,11 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
} else {
|
||||
encoder.encodeNil(forKey: CodingKeys.hostPeerId.rawValue)
|
||||
}
|
||||
if let minOfferStars = self.minOfferStars {
|
||||
encoder.encodeInt64(minOfferStars, forKey: CodingKeys.minOfferStars.rawValue)
|
||||
} else {
|
||||
encoder.encodeNil(forKey: CodingKeys.minOfferStars.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
public func withResellAmounts(_ resellAmounts: [CurrencyAmount]?) -> UniqueGift {
|
||||
|
|
@ -830,10 +919,12 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
releasedBy: self.releasedBy,
|
||||
valueAmount: self.valueAmount,
|
||||
valueCurrency: self.valueCurrency,
|
||||
valueUsdAmount: self.valueUsdAmount,
|
||||
flags: self.flags,
|
||||
themePeerId: self.themePeerId,
|
||||
peerColor: self.peerColor,
|
||||
hostPeerId: self.hostPeerId
|
||||
hostPeerId: self.hostPeerId,
|
||||
minOfferStars: self.minOfferStars
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -853,10 +944,12 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
releasedBy: self.releasedBy,
|
||||
valueAmount: self.valueAmount,
|
||||
valueCurrency: self.valueCurrency,
|
||||
valueUsdAmount: self.valueUsdAmount,
|
||||
flags: self.flags,
|
||||
themePeerId: self.themePeerId,
|
||||
peerColor: self.peerColor,
|
||||
hostPeerId: self.hostPeerId
|
||||
hostPeerId: self.hostPeerId,
|
||||
minOfferStars: self.minOfferStars
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -876,10 +969,12 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
releasedBy: self.releasedBy,
|
||||
valueAmount: self.valueAmount,
|
||||
valueCurrency: self.valueCurrency,
|
||||
valueUsdAmount: self.valueUsdAmount,
|
||||
flags: self.flags,
|
||||
themePeerId: themePeerId,
|
||||
peerColor: self.peerColor,
|
||||
hostPeerId: self.hostPeerId
|
||||
hostPeerId: self.hostPeerId,
|
||||
minOfferStars: self.minOfferStars
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -899,10 +994,12 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
releasedBy: self.releasedBy,
|
||||
valueAmount: self.valueAmount,
|
||||
valueCurrency: self.valueCurrency,
|
||||
valueUsdAmount: self.valueUsdAmount,
|
||||
flags: self.flags,
|
||||
themePeerId: self.themePeerId,
|
||||
peerColor: self.peerColor,
|
||||
hostPeerId: self.hostPeerId
|
||||
hostPeerId: self.hostPeerId,
|
||||
minOfferStars: self.minOfferStars
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -978,6 +1075,15 @@ public extension StarGift {
|
|||
}
|
||||
}
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
case let .generic(gift):
|
||||
return gift.title ?? ""
|
||||
case let .unique(gift):
|
||||
return gift.title
|
||||
}
|
||||
}
|
||||
|
||||
var releasedBy: EnginePeer.Id? {
|
||||
switch self {
|
||||
case let .generic(gift):
|
||||
|
|
@ -991,7 +1097,7 @@ public extension StarGift {
|
|||
extension StarGift {
|
||||
init?(apiStarGift: Api.StarGift) {
|
||||
switch apiStarGift {
|
||||
case let .starGift(apiFlags, id, sticker, stars, availabilityRemains, availabilityTotal, availabilityResale, convertStars, firstSale, lastSale, upgradeStars, minResaleStars, title, releasedBy, perUserTotal, perUserRemains, lockedUntilDate, auctionSlug, giftsPerRound):
|
||||
case let .starGift(apiFlags, id, sticker, stars, availabilityRemains, availabilityTotal, availabilityResale, convertStars, firstSale, lastSale, upgradeStars, minResaleStars, title, releasedBy, perUserTotal, perUserRemains, lockedUntilDate, auctionSlug, giftsPerRound, auctionStartDate, upgradeVariantsCount, apiBackground):
|
||||
var flags = StarGift.Gift.Flags()
|
||||
if (apiFlags & (1 << 2)) != 0 {
|
||||
flags.insert(.isBirthdayGift)
|
||||
|
|
@ -1023,11 +1129,36 @@ extension StarGift {
|
|||
if let perUserTotal, let perUserRemains {
|
||||
perUserLimit = StarGift.Gift.PerUserLimit(total: perUserTotal, remains: perUserRemains)
|
||||
}
|
||||
var background: StarGift.Gift.Background?
|
||||
switch apiBackground {
|
||||
case let .starGiftBackground(centerColor, edgeColor, textColor):
|
||||
background = StarGift.Gift.Background(centerColor: centerColor, edgeColor: edgeColor, textColor: textColor)
|
||||
default:
|
||||
break
|
||||
}
|
||||
guard let file = telegramMediaFileFromApiDocument(sticker, altDocuments: nil) else {
|
||||
return nil
|
||||
}
|
||||
self = .generic(StarGift.Gift(id: id, title: title, file: file, price: stars, convertStars: convertStars, availability: availability, soldOut: soldOut, flags: flags, upgradeStars: upgradeStars, releasedBy: releasedBy?.peerId, perUserLimit: perUserLimit, lockedUntilDate: lockedUntilDate, auctionSlug: auctionSlug, auctionGiftsPerRound: giftsPerRound))
|
||||
case let .starGiftUnique(apiFlags, id, giftId, title, slug, num, ownerPeerId, ownerName, ownerAddress, attributes, availabilityIssued, availabilityTotal, giftAddress, resellAmounts, releasedBy, valueAmount, valueCurrency, themePeer, peerColor, hostPeerId):
|
||||
self = .generic(StarGift.Gift(
|
||||
id: id,
|
||||
title: title,
|
||||
file: file,
|
||||
price: stars,
|
||||
convertStars: convertStars,
|
||||
availability: availability,
|
||||
soldOut: soldOut,
|
||||
flags: flags,
|
||||
upgradeStars: upgradeStars,
|
||||
releasedBy: releasedBy?.peerId,
|
||||
perUserLimit: perUserLimit,
|
||||
lockedUntilDate: lockedUntilDate,
|
||||
auctionSlug: auctionSlug,
|
||||
auctionGiftsPerRound: giftsPerRound,
|
||||
auctionStartDate: auctionStartDate,
|
||||
upgradeVariantsCount: upgradeVariantsCount,
|
||||
background: background
|
||||
))
|
||||
case let .starGiftUnique(apiFlags, id, giftId, title, slug, num, ownerPeerId, ownerName, ownerAddress, attributes, availabilityIssued, availabilityTotal, giftAddress, resellAmounts, releasedBy, valueAmount, valueCurrency, valueUsdAmount, themePeer, peerColor, hostPeerId, minOfferStars):
|
||||
let owner: StarGift.UniqueGift.Owner
|
||||
if let ownerAddress {
|
||||
owner = .address(ownerAddress)
|
||||
|
|
@ -1059,7 +1190,29 @@ extension StarGift {
|
|||
break
|
||||
}
|
||||
|
||||
self = .unique(StarGift.UniqueGift(id: id, giftId: giftId, title: title, number: num, slug: slug, owner: owner, attributes: attributes.compactMap { UniqueGift.Attribute(apiAttribute: $0) }, availability: UniqueGift.Availability(issued: availabilityIssued, total: availabilityTotal), giftAddress: giftAddress, resellAmounts: resellAmounts, resellForTonOnly: (apiFlags & (1 << 7)) != 0, releasedBy: releasedBy?.peerId, valueAmount: valueAmount, valueCurrency: valueCurrency, flags: flags, themePeerId: themePeer?.peerId, peerColor: peerCollectibleColor, hostPeerId: hostPeerId?.peerId))
|
||||
self = .unique(StarGift.UniqueGift(
|
||||
id: id,
|
||||
giftId: giftId,
|
||||
title: title,
|
||||
number: num,
|
||||
slug: slug,
|
||||
owner: owner,
|
||||
attributes: attributes.compactMap { UniqueGift.Attribute(apiAttribute: $0)
|
||||
},
|
||||
availability: UniqueGift.Availability(issued: availabilityIssued, total: availabilityTotal),
|
||||
giftAddress: giftAddress,
|
||||
resellAmounts: resellAmounts,
|
||||
resellForTonOnly: (apiFlags & (1 << 7)) != 0,
|
||||
releasedBy: releasedBy?.peerId,
|
||||
valueAmount: valueAmount,
|
||||
valueCurrency: valueCurrency,
|
||||
valueUsdAmount: valueUsdAmount,
|
||||
flags: flags,
|
||||
themePeerId: themePeer?.peerId,
|
||||
peerColor: peerCollectibleColor,
|
||||
hostPeerId: hostPeerId?.peerId,
|
||||
minOfferStars: minOfferStars.flatMap { Int64($0) }
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1270,7 +1423,7 @@ func _internal_dropStarGiftOriginalDetails(account: Account, reference: StarGift
|
|||
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author?.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date, authorSignature: forwardInfo.authorSignature, psaType: forwardInfo.psaType, flags: forwardInfo.flags)
|
||||
}
|
||||
var media = currentMessage.media
|
||||
if let action = media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case let .starGiftUnique(gift, isUpgrade, isTransferred, savedToProfile, canExportDate, transferStars, isRefunded, isPrepaidUpgrade, peerId, senderId, savedId, resaleAmount, canTransferDate, canResaleDate, _, assigned) = action.action, case let .unique(uniqueGift) = gift {
|
||||
if let action = media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case let .starGiftUnique(gift, isUpgrade, isTransferred, savedToProfile, canExportDate, transferStars, isRefunded, isPrepaidUpgrade, peerId, senderId, savedId, resaleAmount, canTransferDate, canResaleDate, _, assigned, fromOffer) = action.action, case let .unique(uniqueGift) = gift {
|
||||
let updatedAttributes = uniqueGift.attributes.filter { $0.attributeType != .originalInfo }
|
||||
media = [
|
||||
TelegramMediaAction(
|
||||
|
|
@ -1290,7 +1443,9 @@ func _internal_dropStarGiftOriginalDetails(account: Account, reference: StarGift
|
|||
canTransferDate: canTransferDate,
|
||||
canResaleDate: canResaleDate,
|
||||
dropOriginalDetailsStars: nil,
|
||||
assigned: assigned)
|
||||
assigned: assigned,
|
||||
fromOffer: fromOffer
|
||||
)
|
||||
)
|
||||
]
|
||||
}
|
||||
|
|
@ -1395,7 +1550,7 @@ func _internal_upgradeStarGift(account: Account, formId: Int64?, reference: Star
|
|||
case let .updateNewMessage(message, _, _):
|
||||
if let message = StoreMessage(apiMessage: message, accountPeerId: account.peerId, peerIsForum: false) {
|
||||
for media in message.media {
|
||||
if let action = media as? TelegramMediaAction, case let .starGiftUnique(gift, _, _, savedToProfile, canExportDate, transferStars, _, _, peerId, _, savedId, _, canTransferDate, canResaleDate, dropOriginalDetailsStars, _) = action.action, case let .Id(messageId) = message.id {
|
||||
if let action = media as? TelegramMediaAction, case let .starGiftUnique(gift, _, _, savedToProfile, canExportDate, transferStars, _, _, peerId, _, savedId, _, canTransferDate, canResaleDate, dropOriginalDetailsStars, _, _) = action.action, case let .Id(messageId) = message.id {
|
||||
let reference: StarGiftReference
|
||||
if let peerId, let savedId {
|
||||
reference = .peer(peerId: peerId, id: savedId)
|
||||
|
|
@ -1422,7 +1577,8 @@ func _internal_upgradeStarGift(account: Account, formId: Int64?, reference: Star
|
|||
collectionIds: nil,
|
||||
prepaidUpgradeHash: nil,
|
||||
upgradeSeparate: false,
|
||||
dropOriginalDetailsStars: dropOriginalDetailsStars
|
||||
dropOriginalDetailsStars: dropOriginalDetailsStars,
|
||||
number: nil
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
@ -2376,6 +2532,7 @@ public final class ProfileGiftsContext {
|
|||
case prepaidUpgradeHash
|
||||
case upgradeSeparate
|
||||
case dropOriginalDetailsStars
|
||||
case number
|
||||
}
|
||||
|
||||
public let gift: TelegramCore.StarGift
|
||||
|
|
@ -2398,6 +2555,7 @@ public final class ProfileGiftsContext {
|
|||
public let prepaidUpgradeHash: String?
|
||||
public let upgradeSeparate: Bool
|
||||
public let dropOriginalDetailsStars: Int64?
|
||||
public let number: Int32?
|
||||
|
||||
fileprivate let _fromPeerId: EnginePeer.Id?
|
||||
|
||||
|
|
@ -2425,7 +2583,8 @@ public final class ProfileGiftsContext {
|
|||
collectionIds: [Int32]?,
|
||||
prepaidUpgradeHash: String?,
|
||||
upgradeSeparate: Bool,
|
||||
dropOriginalDetailsStars: Int64?
|
||||
dropOriginalDetailsStars: Int64?,
|
||||
number: Int32?
|
||||
) {
|
||||
self.gift = gift
|
||||
self.reference = reference
|
||||
|
|
@ -2448,6 +2607,7 @@ public final class ProfileGiftsContext {
|
|||
self.prepaidUpgradeHash = prepaidUpgradeHash
|
||||
self.upgradeSeparate = upgradeSeparate
|
||||
self.dropOriginalDetailsStars = dropOriginalDetailsStars
|
||||
self.number = number
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
|
|
@ -2480,6 +2640,7 @@ public final class ProfileGiftsContext {
|
|||
self.prepaidUpgradeHash = try container.decodeIfPresent(String.self, forKey: .prepaidUpgradeHash)
|
||||
self.upgradeSeparate = try container.decodeIfPresent(Bool.self, forKey: .upgradeSeparate) ?? false
|
||||
self.dropOriginalDetailsStars = try container.decodeIfPresent(Int64.self, forKey: .dropOriginalDetailsStars)
|
||||
self.number = try container.decodeIfPresent(Int32.self, forKey: .number)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
|
|
@ -2505,6 +2666,7 @@ public final class ProfileGiftsContext {
|
|||
try container.encodeIfPresent(self.prepaidUpgradeHash, forKey: .prepaidUpgradeHash)
|
||||
try container.encode(self.upgradeSeparate, forKey: .upgradeSeparate)
|
||||
try container.encodeIfPresent(self.dropOriginalDetailsStars, forKey: .dropOriginalDetailsStars)
|
||||
try container.encodeIfPresent(self.number, forKey: .number)
|
||||
}
|
||||
|
||||
public func withGift(_ gift: TelegramCore.StarGift) -> StarGift {
|
||||
|
|
@ -2528,7 +2690,8 @@ public final class ProfileGiftsContext {
|
|||
collectionIds: self.collectionIds,
|
||||
prepaidUpgradeHash: self.prepaidUpgradeHash,
|
||||
upgradeSeparate: self.upgradeSeparate,
|
||||
dropOriginalDetailsStars: self.dropOriginalDetailsStars
|
||||
dropOriginalDetailsStars: self.dropOriginalDetailsStars,
|
||||
number: self.number
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -2553,7 +2716,8 @@ public final class ProfileGiftsContext {
|
|||
collectionIds: self.collectionIds,
|
||||
prepaidUpgradeHash: self.prepaidUpgradeHash,
|
||||
upgradeSeparate: self.upgradeSeparate,
|
||||
dropOriginalDetailsStars: self.dropOriginalDetailsStars
|
||||
dropOriginalDetailsStars: self.dropOriginalDetailsStars,
|
||||
number: self.number
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -2578,7 +2742,8 @@ public final class ProfileGiftsContext {
|
|||
collectionIds: self.collectionIds,
|
||||
prepaidUpgradeHash: self.prepaidUpgradeHash,
|
||||
upgradeSeparate: self.upgradeSeparate,
|
||||
dropOriginalDetailsStars: self.dropOriginalDetailsStars
|
||||
dropOriginalDetailsStars: self.dropOriginalDetailsStars,
|
||||
number: self.number
|
||||
)
|
||||
}
|
||||
fileprivate func withFromPeer(_ fromPeer: EnginePeer?) -> StarGift {
|
||||
|
|
@ -2602,7 +2767,8 @@ public final class ProfileGiftsContext {
|
|||
collectionIds: self.collectionIds,
|
||||
prepaidUpgradeHash: self.prepaidUpgradeHash,
|
||||
upgradeSeparate: self.upgradeSeparate,
|
||||
dropOriginalDetailsStars: self.dropOriginalDetailsStars
|
||||
dropOriginalDetailsStars: self.dropOriginalDetailsStars,
|
||||
number: self.number
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -2627,7 +2793,8 @@ public final class ProfileGiftsContext {
|
|||
collectionIds: collectionIds,
|
||||
prepaidUpgradeHash: self.prepaidUpgradeHash,
|
||||
upgradeSeparate: self.upgradeSeparate,
|
||||
dropOriginalDetailsStars: self.dropOriginalDetailsStars
|
||||
dropOriginalDetailsStars: self.dropOriginalDetailsStars,
|
||||
number: self.number
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2845,7 +3012,7 @@ public final class ProfileGiftsContext {
|
|||
extension ProfileGiftsContext.State.StarGift {
|
||||
init?(apiSavedStarGift: Api.SavedStarGift, peerId: EnginePeer.Id, transaction: Transaction) {
|
||||
switch apiSavedStarGift {
|
||||
case let .savedStarGift(flags, fromId, date, apiGift, message, msgId, savedId, convertStars, upgradeStars, canExportDate, transferStars, canTransferAt, canResaleAt, collectionIds, prepaidUpgradeHash, dropOriginalDetailsStars):
|
||||
case let .savedStarGift(flags, fromId, date, apiGift, message, msgId, savedId, convertStars, upgradeStars, canExportDate, transferStars, canTransferAt, canResaleAt, collectionIds, prepaidUpgradeHash, dropOriginalDetailsStars, number):
|
||||
guard let gift = StarGift(apiStarGift: apiGift) else {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -2895,6 +3062,7 @@ extension ProfileGiftsContext.State.StarGift {
|
|||
self.prepaidUpgradeHash = prepaidUpgradeHash
|
||||
self.upgradeSeparate = (flags & (1 << 17)) != 0
|
||||
self.dropOriginalDetailsStars = dropOriginalDetailsStars
|
||||
self.number = number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2962,8 +3130,6 @@ func _internal_getUniqueStarGiftValueInfo(account: Account, slug: String) -> Sig
|
|||
if let result {
|
||||
switch result {
|
||||
case let .uniqueStarGiftValueInfo(flags, currency, value, initialSaleDate, initialSaleStars, initialSalePrice, lastSaleDate, lastSalePrice, floorPrice, averagePrice, listedCount, fragmentListedCount, fragmentListedUrl):
|
||||
let _ = listedCount
|
||||
let _ = fragmentListedCount
|
||||
return StarGift.UniqueGift.ValueInfo(
|
||||
isLastSaleOnFragment: flags & (1 << 1) != 0,
|
||||
valueIsAverage: flags & (1 << 6) != 0,
|
||||
|
|
@ -3623,3 +3789,65 @@ public final class ResaleGiftsContext {
|
|||
return state
|
||||
}
|
||||
}
|
||||
|
||||
func giftUpgradesId(giftId: Int64) -> ItemCacheEntryId {
|
||||
let cacheKey = ValueBoxKey(length: 8)
|
||||
cacheKey.setInt64(0, value: giftId)
|
||||
return ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedGiftUpgradesAttributes, key: cacheKey)
|
||||
}
|
||||
|
||||
final class CachedStartGiftUpgradeAttributes: Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case attributes
|
||||
}
|
||||
|
||||
var attributes: [StarGift.UniqueGift.Attribute]
|
||||
|
||||
init(attributes: [StarGift.UniqueGift.Attribute]) {
|
||||
self.attributes = attributes
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.attributes = try container.decode([StarGift.UniqueGift.Attribute].self, forKey: .attributes)
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(self.attributes, forKey: .attributes)
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_getStarGiftUpgradeAttributes(account: Account, giftId: Int64) -> Signal<[StarGift.UniqueGift.Attribute]?, NoError> {
|
||||
return account.postbox.transaction { transaction in
|
||||
if let cachedGifts = transaction.retrieveItemCacheEntry(id: giftUpgradesId(giftId: giftId))?.get(CachedStartGiftUpgradeAttributes.self) {
|
||||
return .single(cachedGifts.attributes)
|
||||
} else {
|
||||
return account.network.request(Api.functions.payments.getStarGiftUpgradeAttributes(giftId: giftId))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.payments.StarGiftUpgradeAttributes?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<[StarGift.UniqueGift.Attribute]?, NoError> in
|
||||
guard let result else {
|
||||
return .single(nil)
|
||||
}
|
||||
switch result {
|
||||
case let .starGiftUpgradeAttributes(apiAttributes):
|
||||
let attributes = apiAttributes.compactMap { StarGift.UniqueGift.Attribute(apiAttribute: $0) }
|
||||
return account.postbox.transaction { transaction in
|
||||
if !attributes.isEmpty {
|
||||
if let entry = CodableEntry(CachedStartGiftUpgradeAttributes(attributes: attributes)) {
|
||||
transaction.putItemCacheEntry(id: giftUpgradesId(giftId: giftId), entry: entry)
|
||||
}
|
||||
}
|
||||
return attributes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|> switchToLatest
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ private func _internal_getStarGiftAuctionState(postbox: Postbox, network: Networ
|
|||
}
|
||||
return postbox.transaction { transaction -> (gift: StarGift, state: GiftAuctionContext.State.AuctionState?, myState: GiftAuctionContext.State.MyState, timeout: Int32)? in
|
||||
switch result {
|
||||
case let .starGiftAuctionState(apiGift, state, userState, timeout, users):
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(users: users))
|
||||
case let .starGiftAuctionState(apiGift, state, userState, timeout, users, chats):
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(chats: chats, users: users))
|
||||
guard let gift = StarGift(apiStarGift: apiGift) else {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -54,9 +54,28 @@ public final class GiftAuctionContext {
|
|||
public var date: Int32
|
||||
}
|
||||
|
||||
public enum Round: Equatable {
|
||||
case generic(num: Int32, duration: Int32)
|
||||
case extendable(num: Int32, duration: Int32, extendTop: Int32, extendWindow: Int32)
|
||||
|
||||
public var num: Int32 {
|
||||
switch self {
|
||||
case let .generic(num, _), let .extendable(num, _, _, _):
|
||||
return num
|
||||
}
|
||||
}
|
||||
|
||||
public var duration: Int32 {
|
||||
switch self {
|
||||
case let .generic(_, duration), let .extendable(_, duration, _, _):
|
||||
return duration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum AuctionState: Equatable {
|
||||
case ongoing(version: Int32, startDate: Int32, endDate: Int32, minBidAmount: Int64, bidLevels: [BidLevel], topBidders: [EnginePeer], nextRoundDate: Int32, giftsLeft: Int32, currentRound: Int32, totalRounds: Int32)
|
||||
case finished(startDate: Int32, endDate: Int32, averagePrice: Int64)
|
||||
case ongoing(version: Int32, startDate: Int32, endDate: Int32, minBidAmount: Int64, bidLevels: [BidLevel], topBidders: [EnginePeer], nextRoundDate: Int32, giftsLeft: Int32, currentRound: Int32, totalRounds: Int32, rounds: [Round], lastGiftNumber: Int32)
|
||||
case finished(startDate: Int32, endDate: Int32, averagePrice: Int64, listedCount: Int32?, fragmentListedCount: Int32?, fragmentListedUrl: String?)
|
||||
}
|
||||
|
||||
public struct MyState: Equatable {
|
||||
|
|
@ -114,6 +133,15 @@ public final class GiftAuctionContext {
|
|||
}
|
||||
}
|
||||
|
||||
public var isUpcoming: Bool {
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
if case let .ongoing(_, startTime, _, _, _, _, _, _, _, _, _, _) = self.auctionState {
|
||||
return currentTime < startTime
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
public convenience init(account: Account, gift: StarGift) {
|
||||
self.init(account: account, gift: gift, initialAuctionState: nil, initialMyState: nil, initialTimeout: nil)
|
||||
}
|
||||
|
|
@ -136,7 +164,7 @@ public final class GiftAuctionContext {
|
|||
|
||||
private var currentVersion: Int32 {
|
||||
var currentVersion: Int32 = 0
|
||||
if case let .ongoing(version, _, _, _, _, _, _, _, _, _) = self.auctionState {
|
||||
if case let .ongoing(version, _, _, _, _, _, _, _, _, _, _, _) = self.auctionState {
|
||||
currentVersion = version
|
||||
}
|
||||
return currentVersion
|
||||
|
|
@ -154,7 +182,7 @@ public final class GiftAuctionContext {
|
|||
return
|
||||
}
|
||||
|
||||
if case let .ongoing(version, _, _, _, _, _, _, _, _, _) = auctionState, version < self.currentVersion {
|
||||
if case let .ongoing(version, _, _, _, _, _, _, _, _, _, _, _) = auctionState, version < self.currentVersion {
|
||||
} else if let auctionState {
|
||||
self.auctionState = auctionState
|
||||
}
|
||||
|
|
@ -163,7 +191,7 @@ public final class GiftAuctionContext {
|
|||
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
var effectiveTimeout = timeout
|
||||
if case let .ongoing(_, _, _, _, _, _, nextRoundDate, _, _, _) = auctionState {
|
||||
if case let .ongoing(_, _, _, _, _, _, nextRoundDate, _, _, _, _, _) = auctionState {
|
||||
let delta = nextRoundDate - currentTime
|
||||
if delta > 0 && delta < timeout {
|
||||
effectiveTimeout = delta
|
||||
|
|
@ -184,7 +212,7 @@ public final class GiftAuctionContext {
|
|||
}
|
||||
|
||||
func updateAuctionState(_ auctionState: GiftAuctionContext.State.AuctionState) {
|
||||
if case let .ongoing(version, _, _, _, _, _, _, _, _, _) = auctionState, version < self.currentVersion {
|
||||
if case let .ongoing(version, _, _, _, _, _, _, _, _, _, _, _) = auctionState, version < self.currentVersion {
|
||||
} else {
|
||||
self.auctionState = auctionState
|
||||
}
|
||||
|
|
@ -225,16 +253,45 @@ extension GiftAuctionContext.State.BidLevel {
|
|||
extension GiftAuctionContext.State.AuctionState {
|
||||
init?(apiAuctionState: Api.StarGiftAuctionState, peers: [PeerId: Peer]) {
|
||||
switch apiAuctionState {
|
||||
case let .starGiftAuctionState(version, startDate, endDate, minBidAmount, bidLevels, topBiddersPeerIds, nextRoundAt, giftsLeft, currentRound, totalRounds):
|
||||
case let .starGiftAuctionState(version, startDate, endDate, minBidAmount, bidLevels, topBiddersPeerIds, nextRoundAt, lastGiftNumber, giftsLeft, currentRound, totalRounds, apiRounds):
|
||||
var topBidders: [EnginePeer] = []
|
||||
for peerId in topBiddersPeerIds {
|
||||
if let peer = peers[PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(peerId))] {
|
||||
topBidders.append(EnginePeer(peer))
|
||||
}
|
||||
}
|
||||
self = .ongoing(version: version, startDate: startDate, endDate: endDate, minBidAmount: minBidAmount, bidLevels: bidLevels.map(GiftAuctionContext.State.BidLevel.init(apiBidLevel:)), topBidders: topBidders, nextRoundDate: nextRoundAt, giftsLeft: giftsLeft, currentRound: currentRound, totalRounds: totalRounds)
|
||||
case let .starGiftAuctionStateFinished(startDate, endDate, averagePrice):
|
||||
self = .finished(startDate: startDate, endDate: endDate, averagePrice: averagePrice)
|
||||
var rounds: [GiftAuctionContext.State.Round] = []
|
||||
for apiRound in apiRounds {
|
||||
switch apiRound {
|
||||
case let .starGiftAuctionRound(num, duration):
|
||||
rounds.append(.generic(num: num, duration: duration))
|
||||
case let .starGiftAuctionRoundExtendable(num, duration, extendTop, extendWindow):
|
||||
rounds.append(.extendable(num: num, duration: duration, extendTop: extendTop, extendWindow: extendWindow))
|
||||
}
|
||||
}
|
||||
self = .ongoing(
|
||||
version: version,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
minBidAmount: minBidAmount,
|
||||
bidLevels: bidLevels.map(GiftAuctionContext.State.BidLevel.init(apiBidLevel:)),
|
||||
topBidders: topBidders,
|
||||
nextRoundDate: nextRoundAt,
|
||||
giftsLeft: giftsLeft,
|
||||
currentRound: currentRound,
|
||||
totalRounds: totalRounds,
|
||||
rounds: rounds,
|
||||
lastGiftNumber: lastGiftNumber
|
||||
)
|
||||
case let .starGiftAuctionStateFinished(_, startDate, endDate, averagePrice, listedCount, fragmentListedCount, fragmentListedUrl):
|
||||
self = .finished(
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
averagePrice: averagePrice,
|
||||
listedCount: listedCount,
|
||||
fragmentListedCount: fragmentListedCount,
|
||||
fragmentListedUrl: fragmentListedUrl
|
||||
)
|
||||
case .starGiftAuctionStateNotModified:
|
||||
return nil
|
||||
}
|
||||
|
|
@ -242,16 +299,45 @@ extension GiftAuctionContext.State.AuctionState {
|
|||
|
||||
init?(apiAuctionState: Api.StarGiftAuctionState, transaction: Transaction) {
|
||||
switch apiAuctionState {
|
||||
case let .starGiftAuctionState(version, startDate, endDate, minBidAmount, bidLevels, topBiddersPeerIds, nextRoundAt, giftsLeft, currentRound, totalRounds):
|
||||
case let .starGiftAuctionState(version, startDate, endDate, minBidAmount, bidLevels, topBiddersPeerIds, nextRoundAt, lastGiftNumber, giftsLeft, currentRound, totalRounds, apiRounds):
|
||||
var topBidders: [EnginePeer] = []
|
||||
for peerId in topBiddersPeerIds {
|
||||
if let peer = transaction.getPeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(peerId))) {
|
||||
topBidders.append(EnginePeer(peer))
|
||||
}
|
||||
}
|
||||
self = .ongoing(version: version, startDate: startDate, endDate: endDate, minBidAmount: minBidAmount, bidLevels: bidLevels.map(GiftAuctionContext.State.BidLevel.init(apiBidLevel:)), topBidders: topBidders, nextRoundDate: nextRoundAt, giftsLeft: giftsLeft, currentRound: currentRound, totalRounds: totalRounds)
|
||||
case let .starGiftAuctionStateFinished(startDate, endDate, averagePrice):
|
||||
self = .finished(startDate: startDate, endDate: endDate, averagePrice: averagePrice)
|
||||
var rounds: [GiftAuctionContext.State.Round] = []
|
||||
for apiRound in apiRounds {
|
||||
switch apiRound {
|
||||
case let .starGiftAuctionRound(num, duration):
|
||||
rounds.append(.generic(num: num, duration: duration))
|
||||
case let .starGiftAuctionRoundExtendable(num, duration, extendTop, extendWindow):
|
||||
rounds.append(.extendable(num: num, duration: duration, extendTop: extendTop, extendWindow: extendWindow))
|
||||
}
|
||||
}
|
||||
self = .ongoing(
|
||||
version: version,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
minBidAmount: minBidAmount,
|
||||
bidLevels: bidLevels.map(GiftAuctionContext.State.BidLevel.init(apiBidLevel:)),
|
||||
topBidders: topBidders,
|
||||
nextRoundDate: nextRoundAt,
|
||||
giftsLeft: giftsLeft,
|
||||
currentRound: currentRound,
|
||||
totalRounds: totalRounds,
|
||||
rounds: rounds,
|
||||
lastGiftNumber: lastGiftNumber
|
||||
)
|
||||
case let .starGiftAuctionStateFinished(_, startDate, endDate, averagePrice, listedCount, fragmentListedCount, fragmentListedUrl):
|
||||
self = .finished(
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
averagePrice: averagePrice,
|
||||
listedCount: listedCount,
|
||||
fragmentListedCount: fragmentListedCount,
|
||||
fragmentListedUrl: fragmentListedUrl
|
||||
)
|
||||
case .starGiftAuctionStateNotModified:
|
||||
return nil
|
||||
}
|
||||
|
|
@ -281,6 +367,7 @@ public struct GiftAuctionAcquiredGift: Equatable {
|
|||
public let position: Int32
|
||||
public let text: String?
|
||||
public let entities: [MessageTextEntity]?
|
||||
public let number: Int32?
|
||||
}
|
||||
|
||||
func _internal_getGiftAuctionAcquiredGifts(account: Account, giftId: Int64) -> Signal<[GiftAuctionAcquiredGift], NoError> {
|
||||
|
|
@ -302,7 +389,7 @@ func _internal_getGiftAuctionAcquiredGifts(account: Account, giftId: Int64) -> S
|
|||
var mappedGifts: [GiftAuctionAcquiredGift] = []
|
||||
for gift in gifts {
|
||||
switch gift {
|
||||
case let .starGiftAuctionAcquiredGift(flags, peerId, date, bidAmount, round, pos, message):
|
||||
case let .starGiftAuctionAcquiredGift(flags, peerId, date, bidAmount, round, pos, message, number):
|
||||
if let peer = transaction.getPeer(peerId.peerId) {
|
||||
var text: String?
|
||||
var entities: [MessageTextEntity]?
|
||||
|
|
@ -321,7 +408,8 @@ func _internal_getGiftAuctionAcquiredGifts(account: Account, giftId: Int64) -> S
|
|||
round: round,
|
||||
position: pos,
|
||||
text: text,
|
||||
entities: entities
|
||||
entities: entities,
|
||||
number: number
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
@ -338,8 +426,8 @@ func _internal_getActiveGiftAuctions(account: Account, hash: Int64) -> Signal<[G
|
|||
|> mapToSignal { result in
|
||||
return account.postbox.transaction { transaction -> [GiftAuctionContext]? in
|
||||
switch result {
|
||||
case let .starGiftActiveAuctions(auctions, users):
|
||||
let parsedPeers = AccumulatedPeers(users: users)
|
||||
case let .starGiftActiveAuctions(auctions, users, chats):
|
||||
let parsedPeers = AccumulatedPeers(chats: chats, users: users)
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: parsedPeers)
|
||||
|
||||
var auctionContexts: [GiftAuctionContext] = []
|
||||
|
|
@ -493,7 +581,7 @@ public class GiftAuctionsManager {
|
|||
|
||||
public extension GiftAuctionContext.State {
|
||||
func getPlace(myBid: Int64?, myBidDate: Int32?) -> Int32? {
|
||||
guard case let .ongoing(_, _, _, _, bidLevels, _, _, _, _, _) = self.auctionState else {
|
||||
guard case let .ongoing(_, _, _, _, bidLevels, _, _, _, _, _, _, _) = self.auctionState else {
|
||||
return nil
|
||||
}
|
||||
guard let myBid = myBid ?? self.myState.bidAmount else {
|
||||
|
|
@ -550,18 +638,18 @@ public extension GiftAuctionContext.State {
|
|||
|
||||
var startDate: Int32 {
|
||||
switch self.auctionState {
|
||||
case let .ongoing(_, startDate, _, _, _, _, _, _, _, _):
|
||||
case let .ongoing(_, startDate, _, _, _, _, _, _, _, _, _, _):
|
||||
return startDate
|
||||
case let .finished(startDate, _, _):
|
||||
case let .finished(startDate, _, _, _, _, _):
|
||||
return startDate
|
||||
}
|
||||
}
|
||||
|
||||
var endDate: Int32 {
|
||||
switch self.auctionState {
|
||||
case let .ongoing(_, _, endDate, _, _, _, _, _, _, _):
|
||||
case let .ongoing(_, _, endDate, _, _, _, _, _, _, _, _, _):
|
||||
return endDate
|
||||
case let .finished(_, endDate, _):
|
||||
case let .finished(_, endDate, _, _, _, _):
|
||||
return endDate
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
import Foundation
|
||||
import Postbox
|
||||
import MtProtoKit
|
||||
import SwiftSignalKit
|
||||
import TelegramApi
|
||||
|
||||
public enum ResolveStarGiftOfferError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_resolveStarGiftOffer(account: Account, messageId: EngineMessage.Id, accept: Bool) -> Signal<Never, ResolveStarGiftOfferError> {
|
||||
var flags: Int32 = 0
|
||||
if !accept {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
return account.network.request(Api.functions.payments.resolveStarGiftOffer(flags: flags, offerMsgId: messageId.id))
|
||||
|> mapError { _ -> ResolveStarGiftOfferError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<Never, ResolveStarGiftOfferError> in
|
||||
account.stateManager.addUpdates(updates)
|
||||
return .complete()
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
|
||||
|
||||
public enum SendStarGiftOfferError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_sendStarGiftOffer(account: Account, peerId: EnginePeer.Id, slug: String, amount: CurrencyAmount, duration: Int32, allowPaidStars: Int64?) -> Signal<Never, SendStarGiftOfferError> {
|
||||
var flags: Int32 = 0
|
||||
if let _ = allowPaidStars {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
return account.postbox.transaction { transaction in
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> castError(SendStarGiftOfferError.self)
|
||||
|> mapToSignal { inputPeer -> Signal<Never, SendStarGiftOfferError> in
|
||||
guard let inputPeer else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
return account.network.request(Api.functions.payments.sendStarGiftOffer(flags: flags, peer: inputPeer, slug: slug, price: amount.apiAmount, duration: duration, randomId: Int64.random(in: .min ..< .max), allowPaidStars: allowPaidStars))
|
||||
|> mapError { _ -> SendStarGiftOfferError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<Never, SendStarGiftOfferError> in
|
||||
account.stateManager.addUpdates(updates)
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
|
|
@ -735,6 +735,9 @@ private extension StarsContext.State.Transaction {
|
|||
if (apiFlags & (1 << 28)) != 0 {
|
||||
flags.insert(.isStarGiftAuctionBid)
|
||||
}
|
||||
if (apiFlags & (1 << 29)) != 0 {
|
||||
flags.insert(.isStarGiftOffer)
|
||||
}
|
||||
|
||||
let media = extendedMedia.flatMap({ $0.compactMap { textMediaAndExpirationTimerFromApiMedia($0, PeerId(0)).media } }) ?? []
|
||||
|
||||
|
|
@ -793,6 +796,7 @@ public final class StarsContext {
|
|||
public static let isStarGiftDropOriginalDetails = Flags(rawValue: 1 << 12)
|
||||
public static let isStarGiftAuctionBid = Flags(rawValue: 1 << 13)
|
||||
public static let isLiveStreamPaidMessage = Flags(rawValue: 1 << 14)
|
||||
public static let isStarGiftOffer = Flags(rawValue: 1 << 15)
|
||||
}
|
||||
|
||||
public enum Peer: Equatable {
|
||||
|
|
@ -1640,7 +1644,7 @@ func _internal_sendStarsPaymentForm(account: Account, formId: Int64, source: Bot
|
|||
case .giftCode, .stars, .starsGift, .starsChatSubscription, .starGift, .starGiftUpgrade, .starGiftTransfer, .premiumGift, .starGiftResale, .starGiftPrepaidUpgrade, .starGiftDropOriginalDetails, .starGiftAuctionBid:
|
||||
receiptMessageId = nil
|
||||
}
|
||||
} else if case let .starGiftUnique(gift, _, _, savedToProfile, canExportDate, transferStars, _, _, peerId, _, savedId, _, canTransferDate, canResaleDate, dropOriginalDetailsStars, _) = action.action, case let .Id(messageId) = message.id {
|
||||
} else if case let .starGiftUnique(gift, _, _, savedToProfile, canExportDate, transferStars, _, _, peerId, _, savedId, _, canTransferDate, canResaleDate, dropOriginalDetailsStars, _, _) = action.action, case let .Id(messageId) = message.id {
|
||||
let reference: StarGiftReference
|
||||
if let peerId, let savedId {
|
||||
reference = .peer(peerId: peerId, id: savedId)
|
||||
|
|
@ -1667,7 +1671,8 @@ func _internal_sendStarsPaymentForm(account: Account, formId: Int64, source: Bot
|
|||
collectionIds: nil,
|
||||
prepaidUpgradeHash: nil,
|
||||
upgradeSeparate: false,
|
||||
dropOriginalDetailsStars: dropOriginalDetailsStars
|
||||
dropOriginalDetailsStars: dropOriginalDetailsStars,
|
||||
number: nil
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,6 +180,18 @@ public extension TelegramEngine {
|
|||
public func getStarsTransaction(reference: StarsTransactionReference) -> Signal<StarsContext.State.Transaction?, NoError> {
|
||||
return _internal_getStarsTransaction(accountPeerId: self.account.peerId, postbox: self.account.postbox, network: self.account.network, transactionReference: reference)
|
||||
}
|
||||
|
||||
public func resolveStarGiftOffer(messageId: EngineMessage.Id, accept: Bool) -> Signal<Never, ResolveStarGiftOfferError> {
|
||||
return _internal_resolveStarGiftOffer(account: self.account, messageId: messageId, accept: accept)
|
||||
}
|
||||
|
||||
public func sendStarGiftOffer(peerId: EnginePeer.Id, slug: String, amount: CurrencyAmount, duration: Int32, allowPaidStars: Int64?) -> Signal<Never, SendStarGiftOfferError> {
|
||||
return _internal_sendStarGiftOffer(account: self.account, peerId: peerId, slug: slug, amount: amount, duration: duration, allowPaidStars: allowPaidStars)
|
||||
}
|
||||
|
||||
public func getStarGiftUpgradeAttributes(giftId: Int64) -> Signal<[StarGift.UniqueGift.Attribute]?, NoError> {
|
||||
return _internal_getStarGiftUpgradeAttributes(account: self.account, giftId: giftId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1171,7 +1171,7 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
|||
attributedString = mutableString
|
||||
case .prizeStars:
|
||||
attributedString = NSAttributedString(string: strings.Notification_StarsPrize, font: titleFont, textColor: primaryTextColor)
|
||||
case let .starGift(gift, _, text, entities, _, _, _, _, _, upgradeStars, _, isPrepaidUpgrade, _, peerId, senderId, _, _, _, upgradeSeparate, isAuctionAcquired, _):
|
||||
case let .starGift(gift, _, text, entities, _, _, _, _, _, upgradeStars, _, isPrepaidUpgrade, _, peerId, senderId, _, _, _, upgradeSeparate, isAuctionAcquired, _, _):
|
||||
if !forAdditionalServiceMessage {
|
||||
if let text {
|
||||
let mutableAttributedString = NSMutableAttributedString(attributedString: stringWithAppliedEntities(text, entities: entities ?? [], baseColor: primaryTextColor, linkColor: primaryTextColor, baseFont: titleFont, linkFont: titleBoldFont, boldFont: titleBoldFont, italicFont: titleFont, boldItalicFont: titleBoldFont, fixedFont: titleFont, blockQuoteFont: titleFont, underlineLinks: false, message: message._asMessage()))
|
||||
|
|
@ -1262,7 +1262,7 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
|||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_Sent(authorName, starsPrice)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
}
|
||||
}
|
||||
case let .starGiftUnique(gift, isUpgrade, _, _, _, _, _, isPrepaidUpgrade, peerId, senderId, _, resaleStars, _, _, _, assigned):
|
||||
case let .starGiftUnique(gift, isUpgrade, _, _, _, _, _, isPrepaidUpgrade, peerId, senderId, _, resaleStars, _, _, _, assigned, fromOffer):
|
||||
if case let .unique(gift) = gift {
|
||||
if !forAdditionalServiceMessage && !"".isEmpty {
|
||||
attributedString = NSAttributedString(string: "\(gift.title) #\(presentationStringsFormattedNumber(gift.number, dateTimeFormat.groupingSeparator))", font: titleFont, textColor: primaryTextColor)
|
||||
|
|
@ -1290,7 +1290,33 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if message.id.peerId == accountPeerId && assigned {
|
||||
if fromOffer, let resaleStars {
|
||||
let starsString: String
|
||||
switch resaleStars.currency {
|
||||
case .stars:
|
||||
starsString = strings.Notification_StarsGiftOffer_Accepted_Stars(Int32(clamping: resaleStars.amount.value))
|
||||
case .ton:
|
||||
starsString = formatTonAmountText(resaleStars.amount.value, dateTimeFormat: dateTimeFormat) + " TON"
|
||||
}
|
||||
let giftTitle = "\(gift.title) #\(presentationStringsFormattedNumber(gift.number, dateTimeFormat.groupingSeparator))"
|
||||
var peerName = ""
|
||||
if let name = message.peers[message.id.peerId].flatMap(EnginePeer.init)?.compactDisplayTitle {
|
||||
peerName = name
|
||||
}
|
||||
if message.author?.id == accountPeerId {
|
||||
let peerIds: [(Int, EnginePeer.Id?)] = [(1, message.id.peerId)]
|
||||
var attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributes[0] = boldAttributes
|
||||
attributes[2] = boldAttributes
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGiftOffer_AcceptedYou(giftTitle, peerName, starsString)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
} else {
|
||||
let peerIds: [(Int, EnginePeer.Id?)] = [(0, message.author?.id)]
|
||||
var attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributes[1] = boldAttributes
|
||||
attributes[2] = boldAttributes
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGiftOffer_Accepted(peerName, giftTitle, starsString)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
}
|
||||
} else if message.id.peerId == accountPeerId && assigned {
|
||||
let attributes: [Int: MarkdownAttributeSet] = [0: boldAttributes]
|
||||
let giftTitle = "\(gift.title) #\(presentationStringsFormattedNumber(gift.number, dateTimeFormat.groupingSeparator))"
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_Assigned(giftTitle)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
|
|
@ -1616,6 +1642,103 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
|||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_Sent(authorName, price)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
}
|
||||
}
|
||||
case let .starGiftPurchaseOffer(gift, amount, _, _, _):
|
||||
let peerName = message.peers[message.id.peerId].flatMap { EnginePeer($0) }?.compactDisplayTitle ?? ""
|
||||
|
||||
let giftTitle: String
|
||||
if case let .unique(gift) = gift {
|
||||
giftTitle = "\(gift.title) #\(formatCollectibleNumber(gift.number, dateTimeFormat: dateTimeFormat))"
|
||||
} else {
|
||||
giftTitle = ""
|
||||
}
|
||||
|
||||
let peerIds: [(Int, EnginePeer.Id?)] = [(0, message.id.peerId)]
|
||||
var attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributes[1] = boldAttributes
|
||||
attributes[2] = boldAttributes
|
||||
|
||||
if message.author?.id == accountPeerId {
|
||||
let priceString: String
|
||||
switch amount.currency {
|
||||
case .stars:
|
||||
priceString = strings.Notification_StarsGiftOffer_OfferYou_Stars(Int32(clamping: amount.amount.value))
|
||||
case .ton:
|
||||
priceString = "\(amount.amount) TON"
|
||||
}
|
||||
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGiftOffer_OfferYou(peerName, priceString, giftTitle)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
} else {
|
||||
let priceString: String
|
||||
switch amount.currency {
|
||||
case .stars:
|
||||
priceString = strings.Notification_StarsGiftOffer_Offer_Stars(Int32(clamping: amount.amount.value))
|
||||
case .ton:
|
||||
priceString = "\(amount.amount) TON"
|
||||
}
|
||||
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGiftOffer_Offer(peerName, priceString, giftTitle)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
}
|
||||
case let .starGiftPurchaseOfferDeclined(gift, amount, hasExpired):
|
||||
let peerName = message.peers[message.id.peerId].flatMap { EnginePeer($0) }?.compactDisplayTitle ?? ""
|
||||
let peerIds: [(Int, EnginePeer.Id?)] = [(0, message.id.peerId)]
|
||||
|
||||
let giftTitle: String
|
||||
if case let .unique(gift) = gift {
|
||||
giftTitle = "\(gift.title) #\(formatCollectibleNumber(gift.number, dateTimeFormat: dateTimeFormat))"
|
||||
} else {
|
||||
giftTitle = ""
|
||||
}
|
||||
|
||||
if hasExpired {
|
||||
if message.author?.id == accountPeerId {
|
||||
let priceString: String
|
||||
switch amount.currency {
|
||||
case .stars:
|
||||
priceString = strings.Notification_StarsGiftOffer_ExpiredYou_Stars(Int32(clamping: amount.amount.value))
|
||||
case .ton:
|
||||
priceString = "\(amount.amount) TON"
|
||||
}
|
||||
|
||||
var attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributes[1] = boldAttributes
|
||||
attributes[2] = boldAttributes
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGiftOffer_ExpiredYou(peerName, giftTitle, priceString)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
} else {
|
||||
let priceString: String
|
||||
switch amount.currency {
|
||||
case .stars:
|
||||
priceString = strings.Notification_StarsGiftOffer_Expired_Stars(Int32(clamping: amount.amount.value))
|
||||
case .ton:
|
||||
priceString = "\(amount.amount) TON"
|
||||
}
|
||||
|
||||
let timeString = "[TODO]"
|
||||
|
||||
var attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributes[1] = boldAttributes
|
||||
attributes[2] = boldAttributes
|
||||
attributes[3] = boldAttributes
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGiftOffer_Expired(peerName, giftTitle, timeString, priceString)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
}
|
||||
} else {
|
||||
if message.author?.id == accountPeerId {
|
||||
let attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGiftOffer_RejectedYou(peerName)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
} else {
|
||||
let priceString: String
|
||||
switch amount.currency {
|
||||
case .stars:
|
||||
priceString = strings.Notification_StarsGiftOffer_Rejected_Stars(Int32(clamping: amount.amount.value))
|
||||
case .ton:
|
||||
priceString = "\(amount.amount) TON"
|
||||
}
|
||||
|
||||
var attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributes[1] = boldAttributes
|
||||
attributes[2] = boldAttributes
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGiftOffer_Rejected(peerName, giftTitle, priceString)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
}
|
||||
}
|
||||
case .unknown:
|
||||
attributedString = nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -402,6 +402,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/Chat/ChatMessageUnsupportedBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageGiftOfferBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageGiveawayBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatRecentActionsController",
|
||||
|
|
@ -497,6 +498,8 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/AttachmentFileController",
|
||||
"//submodules/TelegramUI/Components/Contacts/NewContactScreen",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatSendAsContextMenu",
|
||||
"//submodules/TelegramUI/Components/Settings/PasskeysScreen",
|
||||
"//submodules/TelegramUI/Components/Gifts/GiftDemoScreen",
|
||||
] + select({
|
||||
"@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets,
|
||||
"//build-system:ios_sim_arm64": [],
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ final class AdminUserActionsPeerComponent: Component {
|
|||
private weak var state: EmptyComponentState?
|
||||
|
||||
public var customUpdateIsHighlighted: ((Bool) -> Void)?
|
||||
public var enumerateSiblings: (((UIView) -> Void) -> Void)?
|
||||
public var separatorInset: CGFloat = 0.0
|
||||
|
||||
override init(frame: CGRect) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue