diff --git a/.bazelrc b/.bazelrc index 86b38a8f41..fc6d0486d1 100644 --- a/.bazelrc +++ b/.bazelrc @@ -19,7 +19,7 @@ build --per_file_copt="Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/.*\. build --per_file_copt="Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/.*\.mm$","@-std=c++17" build --per_file_copt="third-party/td/TdBinding/Sources/.*\.mm$","@-std=c++17" -build --swiftcopt=-whole-module-optimization +#build --swiftcopt=-whole-module-optimization build --per_file_copt=".*\.m$","@-fno-objc-msgsend-selector-stubs" build --per_file_copt=".*\.mm$","@-fno-objc-msgsend-selector-stubs" @@ -37,4 +37,3 @@ build --spawn_strategy=standalone build --strategy=SwiftCompile=standalone build --define RULES_SWIFT_BUILD_DUMMY_WORKER=1 -build --noenable_bzlmod diff --git a/MODULE.bazel b/MODULE.bazel index 00bb18361f..3f8e4a31c5 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,6 +1,64 @@ -############################################################################### -# Bazel now uses Bzlmod by default to manage external dependencies. -# Please consider migrating your external dependencies from WORKSPACE to MODULE.bazel. -# -# For more details, please check https://github.com/bazelbuild/bazel/issues/18958 -############################################################################### +http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") + +bazel_dep(name = "bazel_features", version = "1.29.0") +bazel_dep(name = "bazel_skylib", version = "1.7.1") +bazel_dep(name = "platforms", version = "0.0.11") + +bazel_dep(name = "rules_xcodeproj") +local_path_override( + module_name = "rules_xcodeproj", + path = "./build-system/bazel-rules/rules_xcodeproj", +) + +bazel_dep(name = "rules_apple", repo_name = "build_bazel_rules_apple") +local_path_override( + module_name = "rules_apple", + path = "./build-system/bazel-rules/rules_apple", +) + +bazel_dep(name = "rules_swift", repo_name = "build_bazel_rules_swift") +local_path_override( + module_name = "rules_swift", + path = "./build-system/bazel-rules/rules_swift", +) + +bazel_dep(name = "apple_support", repo_name = "build_bazel_apple_support") +local_path_override( + module_name = "apple_support", + path = "./build-system/bazel-rules/apple_support", +) + +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", +) + +http_file( + name = "meson_tar_gz", + urls = ["https://github.com/mesonbuild/meson/releases/download/1.6.0/meson-1.6.0.tar.gz"], + sha256 = "999b65f21c03541cf11365489c1fad22e2418bb0c3d50ca61139f2eec09d5496", +) + +http_file( + name = "ninja-mac_zip", + urls = ["https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-mac.zip"], + sha256 = "89a287444b5b3e98f88a945afa50ce937b8ffd1dcc59c555ad9b1baf855298c9", +) + +http_file( + name = "flatbuffers_zip", + urls = ["https://github.com/google/flatbuffers/archive/refs/tags/v24.12.23.zip"], + sha256 = "c5cd6a605ff20350c7faa19d8eeb599df6117ea4aabd16ac58a7eb5ba82df4e7", +) + +provisioning_profile_repository = use_extension("@build_bazel_rules_apple//apple:apple.bzl", "provisioning_profile_repository_extension") +#provisioning_profile_repository.setup( +# fallback_profiles = "//path/to/some:filegroup", # Profiles to use if one isn't found locally +#) + +bazel_dep(name = "build_configuration") +local_path_override( + module_name = "build_configuration", + path = "./build-input/configuration-repository", +) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 7266ea0556..dec3d9b9a2 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1,624 +1,527 @@ { - "lockFileVersion": 3, - "moduleFileHash": "0e3e315145ac7ee7a4e0ac825e1c5e03c068ec1254dd42c3caaecb27e921dc4d", - "flags": { - "cmdRegistries": [ - "https://bcr.bazel.build/" - ], - "cmdModuleOverrides": {}, - "allowedYankedVersions": [], - "envVarAllowedYankedVersions": "", - "ignoreDevDependency": false, - "directDependenciesMode": "WARNING", - "compatibilityMode": "ERROR" + "lockFileVersion": 18, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.29.0/MODULE.bazel": "fc2373c9825b71bcd06b60ef19b1715a42fa58edc4e39086375f47aa277e45ba", + "https://bcr.bazel.build/modules/bazel_features/1.29.0/source.json": "714dbd96075890f20f4f158ed9fa7fd1080bf6a6e0d5a89a05e2765e3ed74260", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953", + "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", + "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.11/source.json": "f7e188b79ebedebfe75e9e1d098b8845226c7992b307e28e1496f23112e8fc29", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2023-09-01/source.json": "e044ce89c2883cd957a2969a43e79f7752f9656f6b20050b62f90ede21ec6eb4", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/source.json": "4db99b3f55c90ab28d14552aa0632533e3e8e5e9aea0f5c24ac0014282c2a7c5", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", + "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "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.11.0/MODULE.bazel": "c3d280bc5ff1038dcb3bacb95d3f6b83da8dd27bba57820ec89ea4085da767ad", + "https://bcr.bazel.build/modules/rules_java/8.11.0/source.json": "302b52a39259a85aa06ca3addb9787864ca3e03b432a5f964ea68244397e7544", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", + "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/source.json": "6f5f5a5a4419ae4e37c35a5bb0a6ae657ed40b7abc5a5189111b47fcebe43197", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.27.1/MODULE.bazel": "65dc875cc1a06c30d5bbdba7ab021fd9e551a6579e408a3943a61303e2228a53", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", + "https://bcr.bazel.build/modules/rules_python/0.40.0/source.json": "939d4bd2e3110f27bfb360292986bb79fd8dcefb874358ccd6cdaa7bda029320", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/source.json": "7f27af3c28037d9701487c4744b5448d26537cc66cdef0d8df7ae85411f8de95", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", + "https://bcr.bazel.build/modules/stardoc/0.7.1/source.json": "b6500ffcd7b48cd72c29bb67bcac781e12701cc0d6d55d266a652583cfcdab01", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" }, - "localOverrideHashes": { - "bazel_tools": "922ea6752dc9105de5af957f7a99a6933c0a6a712d23df6aad16a9c399f7e787" - }, - "moduleDepGraph": { - "": { - "name": "", - "version": "", - "key": "", - "repoName": "", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [], - "extensionUsages": [], - "deps": { - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - } - }, - "bazel_tools@_": { - "name": "bazel_tools", - "version": "", - "key": "bazel_tools@_", - "repoName": "bazel_tools", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [ - "@local_config_cc_toolchains//:all", - "@local_config_sh//:local_sh_toolchain" - ], - "extensionUsages": [ - { - "extensionBzlFile": "@bazel_tools//tools/cpp:cc_configure.bzl", - "extensionName": "cc_configure_extension", - "usingModule": "bazel_tools@_", - "location": { - "file": "@@bazel_tools//:MODULE.bazel", - "line": 17, - "column": 29 + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@apple_support+//crosstool:setup.bzl%apple_cc_configure_extension": { + "general": { + "bzlTransitiveDigest": "Ync9nL0AbHC6ondeEY7fBjBjLxojTsiXcJh65ZDTRlA=", + "usagesDigest": "lfcV4HxPD+NLaRIT/v7BtSGFgE7c9xrWU7jDiwBAxzo=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "local_config_apple_cc_toolchains": { + "repoRuleId": "@@apple_support+//crosstool:setup.bzl%_apple_cc_autoconf_toolchains", + "attributes": {} }, - "imports": { - "local_config_cc": "local_config_cc", - "local_config_cc_toolchains": "local_config_cc_toolchains" - }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true + "local_config_apple_cc": { + "repoRuleId": "@@apple_support+//crosstool:setup.bzl%_apple_cc_autoconf", + "attributes": {} + } }, - { - "extensionBzlFile": "@bazel_tools//tools/osx:xcode_configure.bzl", - "extensionName": "xcode_configure_extension", - "usingModule": "bazel_tools@_", - "location": { - "file": "@@bazel_tools//:MODULE.bazel", - "line": 21, - "column": 32 + "recordedRepoMappingEntries": [ + [ + "apple_support+", + "bazel_tools", + "bazel_tools" + ], + [ + "bazel_tools", + "rules_cc", + "rules_cc+" + ] + ] + } + }, + "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { + "general": { + "bzlTransitiveDigest": "sFhcgPbDQehmbD1EOXzX4H1q/CD5df8zwG4kp4jbvr8=", + "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_github_jetbrains_kotlin_git": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository", + "attributes": { + "urls": [ + "https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip" + ], + "sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88" + } }, - "imports": { - "local_config_xcode": "local_config_xcode" + "com_github_jetbrains_kotlin": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository", + "attributes": { + "git_repository_name": "com_github_jetbrains_kotlin_git", + "compiler_version": "1.9.23" + } }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true + "com_github_google_ksp": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository", + "attributes": { + "urls": [ + "https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip" + ], + "sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d", + "strip_version": "1.9.23-1.0.20" + } + }, + "com_github_pinterest_ktlint": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985", + "urls": [ + "https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint" + ], + "executable": true + } + }, + "rules_android": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806", + "strip_prefix": "rules_android-0.1.1", + "urls": [ + "https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip" + ] + } + } }, - { - "extensionBzlFile": "@rules_java//java:extensions.bzl", - "extensionName": "toolchains", - "usingModule": "bazel_tools@_", - "location": { - "file": "@@bazel_tools//:MODULE.bazel", - "line": 24, - "column": 32 + "recordedRepoMappingEntries": [ + [ + "rules_kotlin+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_swift+//swift:extensions.bzl%non_module_deps": { + "general": { + "bzlTransitiveDigest": "CstlfOV6P4ALl6q8xx9u3M8jofl+G5yMT1+IKHo3264=", + "usagesDigest": "mbxc/w+QB6+HxN+/1OLr7IYf5Rrdluul+wdTTRMLmlE=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_github_apple_swift_protobuf": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-protobuf/archive/1.20.2.tar.gz" + ], + "sha256": "3fb50bd4d293337f202d917b6ada22f9548a0a0aed9d9a4d791e6fbd8a246ebb", + "strip_prefix": "swift-protobuf-1.20.2/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_protobuf/BUILD.overlay" + } }, - "imports": { - "local_jdk": "local_jdk", - "remote_java_tools": "remote_java_tools", - "remote_java_tools_linux": "remote_java_tools_linux", - "remote_java_tools_windows": "remote_java_tools_windows", - "remote_java_tools_darwin_x86_64": "remote_java_tools_darwin_x86_64", - "remote_java_tools_darwin_arm64": "remote_java_tools_darwin_arm64" + "com_github_grpc_grpc_swift": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/grpc/grpc-swift/archive/1.16.0.tar.gz" + ], + "sha256": "58b60431d0064969f9679411264b82e40a217ae6bd34e17096d92cc4e47556a5", + "strip_prefix": "grpc-swift-1.16.0/", + "build_file": "@@rules_swift+//third_party:com_github_grpc_grpc_swift/BUILD.overlay" + } }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true + "com_github_apple_swift_nio": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-nio/archive/2.42.0.tar.gz" + ], + "sha256": "e3304bc3fb53aea74a3e54bd005ede11f6dc357117d9b1db642d03aea87194a0", + "strip_prefix": "swift-nio-2.42.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio/BUILD.overlay" + } + }, + "com_github_apple_swift_nio_http2": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-nio-http2/archive/1.26.0.tar.gz" + ], + "sha256": "f0edfc9d6a7be1d587e5b403f2d04264bdfae59aac1d74f7d974a9022c6d2b25", + "strip_prefix": "swift-nio-http2-1.26.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_http2/BUILD.overlay" + } + }, + "com_github_apple_swift_nio_transport_services": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-nio-transport-services/archive/1.15.0.tar.gz" + ], + "sha256": "f3498dafa633751a52b9b7f741f7ac30c42bcbeb3b9edca6d447e0da8e693262", + "strip_prefix": "swift-nio-transport-services-1.15.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_transport_services/BUILD.overlay" + } + }, + "com_github_apple_swift_nio_extras": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-nio-extras/archive/1.4.0.tar.gz" + ], + "sha256": "4684b52951d9d9937bb3e8ccd6b5daedd777021ef2519ea2f18c4c922843b52b", + "strip_prefix": "swift-nio-extras-1.4.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_extras/BUILD.overlay" + } + }, + "com_github_apple_swift_log": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-log/archive/1.4.4.tar.gz" + ], + "sha256": "48fe66426c784c0c20031f15dc17faf9f4c9037c192bfac2f643f65cb2321ba0", + "strip_prefix": "swift-log-1.4.4/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_log/BUILD.overlay" + } + }, + "com_github_apple_swift_nio_ssl": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-nio-ssl/archive/2.23.0.tar.gz" + ], + "sha256": "4787c63f61dd04d99e498adc3d1a628193387e41efddf8de19b8db04544d016d", + "strip_prefix": "swift-nio-ssl-2.23.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_ssl/BUILD.overlay" + } + }, + "com_github_apple_swift_collections": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-collections/archive/1.0.4.tar.gz" + ], + "sha256": "d9e4c8a91c60fb9c92a04caccbb10ded42f4cb47b26a212bc6b39cc390a4b096", + "strip_prefix": "swift-collections-1.0.4/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_collections/BUILD.overlay" + } + }, + "com_github_apple_swift_atomics": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-atomics/archive/1.1.0.tar.gz" + ], + "sha256": "1bee7f469f7e8dc49f11cfa4da07182fbc79eab000ec2c17bfdce468c5d276fb", + "strip_prefix": "swift-atomics-1.1.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_atomics/BUILD.overlay" + } + }, + "build_bazel_rules_swift_index_import": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file": "@@rules_swift+//third_party:build_bazel_rules_swift_index_import/BUILD.overlay", + "canonical_id": "index-import-5.8", + "urls": [ + "https://github.com/MobileNativeFoundation/index-import/releases/download/5.8.0.1/index-import.tar.gz" + ], + "sha256": "28c1ffa39d99e74ed70623899b207b41f79214c498c603915aef55972a851a15" + } + }, + "build_bazel_rules_swift_local_config": { + "repoRuleId": "@@rules_swift+//swift/internal:swift_autoconfiguration.bzl%swift_autoconfiguration", + "attributes": {} + } }, - { - "extensionBzlFile": "@bazel_tools//tools/sh:sh_configure.bzl", - "extensionName": "sh_configure_extension", - "usingModule": "bazel_tools@_", - "location": { - "file": "@@bazel_tools//:MODULE.bazel", - "line": 35, - "column": 39 - }, - "imports": { - "local_config_sh": "local_config_sh" - }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true + "recordedRepoMappingEntries": [ + [ + "rules_swift+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_swift+", + "build_bazel_rules_swift", + "rules_swift+" + ] + ] + } + }, + "@@rules_xcodeproj+//xcodeproj:extensions.bzl%internal": { + "general": { + "bzlTransitiveDigest": "kC15ekAbrVsNpiIk+/b5EhXG5RINIYKGICYn8Z8YhqQ=", + "usagesDigest": "fvsnMonVwKDYnBfww4bXuYie3WU0d9VSqT2gePSdQco=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "rules_xcodeproj_generated": { + "repoRuleId": "@@rules_xcodeproj+//xcodeproj:repositories.bzl%generated_files_repo", + "attributes": {} + } }, - { - "extensionBzlFile": "@bazel_tools//tools/test:extensions.bzl", - "extensionName": "remote_coverage_tools_extension", - "usingModule": "bazel_tools@_", - "location": { - "file": "@@bazel_tools//:MODULE.bazel", - "line": 39, - "column": 48 + "recordedRepoMappingEntries": [ + [ + "rules_xcodeproj+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_xcodeproj+//xcodeproj:extensions.bzl%non_module_deps": { + "general": { + "bzlTransitiveDigest": "kC15ekAbrVsNpiIk+/b5EhXG5RINIYKGICYn8Z8YhqQ=", + "usagesDigest": "jzxYhnOC9BE0dJ0biFLfxWXi/+R19uAAZkJ0p9CY0JI=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "rules_xcodeproj_legacy_index_import": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "load(\"@bazel_skylib//rules:native_binary.bzl\", \"native_binary\")\n\nnative_binary(\n name = \"index_import\",\n src = \"index-import\",\n out = \"index-import\",\n visibility = [\"//visibility:public\"],\n)\n", + "canonical_id": "index-import-5.8.0.1", + "sha256": "28c1ffa39d99e74ed70623899b207b41f79214c498c603915aef55972a851a15", + "url": "https://github.com/MobileNativeFoundation/index-import/releases/download/5.8.0.1/index-import.tar.gz" + } }, - "imports": { - "remote_coverage_tools": "remote_coverage_tools" + "rules_xcodeproj_index_import": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "load(\"@bazel_skylib//rules:native_binary.bzl\", \"native_binary\")\n\nnative_binary(\n name = \"index_import\",\n src = \"index-import\",\n out = \"index-import\",\n visibility = [\"//visibility:public\"],\n)\n", + "canonical_id": "index-import-6.1.0", + "sha256": "54d0477526bba0dc1560189dfc4f02d90aea536e9cb329e911f32b2a564b66f1", + "url": "https://github.com/MobileNativeFoundation/index-import/releases/download/6.1.0/index-import.tar.gz" + } }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true + "com_github_apple_swift_argument_parser": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "load(\"@build_bazel_rules_swift//swift:swift.bzl\", \"swift_library\")\n\nswift_library(\n name = \"ArgumentParserToolInfo\",\n srcs = glob([\"Sources/ArgumentParserToolInfo/**/*.swift\"]),\n visibility = [\"//visibility:public\"],\n)\n\nswift_library(\n name = \"ArgumentParser\",\n srcs = glob([\"Sources/ArgumentParser/**/*.swift\"]),\n visibility = [\"//visibility:public\"],\n deps = [\":ArgumentParserToolInfo\"],\n)\n", + "sha256": "4a10bbef290a2167c5cc340b39f1f7ff6a8cf4e1b5433b68548bf5f1e542e908", + "strip_prefix": "swift-argument-parser-1.2.3", + "url": "https://github.com/apple/swift-argument-parser/archive/refs/tags/1.2.3.tar.gz" + } + }, + "com_github_kylef_pathkit": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "load(\"@build_bazel_rules_swift//swift:swift.bzl\", \"swift_library\")\n\nswift_library(\n name = \"PathKit\",\n srcs = glob([\"Sources/**/*.swift\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "fcda78cdf12c1c6430c67273333e060a9195951254230e524df77841a0235dae", + "strip_prefix": "PathKit-1.0.1", + "url": "https://github.com/kylef/PathKit/archive/refs/tags/1.0.1.tar.gz" + } + }, + "com_github_tadija_aexml": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "load(\"@build_bazel_rules_swift//swift:swift.bzl\", \"swift_library\")\n\nswift_library(\n name = \"AEXML\",\n srcs = glob([\"Sources/AEXML/**/*.swift\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "5a76c28e4fa9dcc1cbfb87a8518652628e990e522ecfbc98bdad17eabf4631d5", + "strip_prefix": "AEXML-4.6.1", + "url": "https://github.com/tadija/AEXML/archive/refs/tags/4.6.1.tar.gz" + } + }, + "com_github_michaeleisel_jjliso8601dateformatter": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "objc_library(\n name = \"JJLISO8601DateFormatter\",\n srcs = glob([\"Sources/JJLISO8601DateFormatter/**/*\"]),\n copts = [\n \"-Wno-incompatible-pointer-types\",\n \"-Wno-incompatible-pointer-types-discards-qualifiers\",\n \"-Wno-shorten-64-to-32\",\n \"-Wno-unreachable-code\",\n \"-Wno-unused-function\",\n \"-Wno-unused-variable\",\n ],\n includes = [\"Sources/JJLISO8601DateFormatter/include\"],\n hdrs = glob([\"Sources/JJLISO8601DateFormatter/include/*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "patches": [ + "@@rules_xcodeproj+//third_party/com_github_michaeleisel_jjliso8601dateformatter:include_fix.patch" + ], + "sha256": "6fe15f251f100f3df057c2802a50765387674fde9c922375683682b5ba37eef0", + "strip_prefix": "JJLISO8601DateFormatter-0.1.6", + "url": "https://github.com/michaeleisel/JJLISO8601DateFormatter/archive/refs/tags/0.1.6.tar.gz" + } + }, + "com_github_michaeleisel_zippyjsoncfamily": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "objc_library(\n name = \"ZippyJSONCFamily\",\n copts = [\n \"-std=c++17\",\n \"-Wno-unused-function\",\n \"-Wno-reorder-ctor\",\n \"-Wno-return-type-c-linkage\",\n \"-Wno-shorten-64-to-32\",\n \"-Wno-unused-variable\",\n ],\n srcs = glob([\"Sources/ZippyJSONCFamily/**/*\"]),\n includes = [\"Sources/ZippyJSONCFamily/include\"],\n hdrs = glob([\"Sources/ZippyJSONCFamily/include/*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "patches": [ + "@@rules_xcodeproj+//third_party/com_github_michaeleisel_zippyjsoncfamily:include_fix.patch" + ], + "sha256": "b215927ada8403e1b056d39450c6a7b59122eca4b0c7fc5beb5f0b5fea2acd72", + "strip_prefix": "ZippyJSONCFamily-1.2.9", + "url": "https://github.com/michaeleisel/ZippyJSONCFamily/archive/refs/tags/1.2.9.tar.gz" + } + }, + "com_github_michaeleisel_zippyjson": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "load(\"@build_bazel_rules_swift//swift:swift.bzl\", \"swift_library\")\n\nswift_library(\n name = \"ZippyJSON\",\n srcs = glob([\"Sources/ZippyJSON/**/*.swift\"]),\n deps = [\n \"@com_github_michaeleisel_jjliso8601dateformatter//:JJLISO8601DateFormatter\",\n \"@com_github_michaeleisel_zippyjsoncfamily//:ZippyJSONCFamily\",\n ],\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "4b256843c9c3686c527e76dde54f8d76b6201c1fd903c07dc2211ab1b250bd04", + "strip_prefix": "ZippyJSON-1.2.10", + "url": "https://github.com/michaeleisel/ZippyJSON/archive/refs/tags/1.2.10.tar.gz" + } + }, + "com_github_tuist_xcodeproj": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "load(\"@build_bazel_rules_swift//swift:swift.bzl\", \"swift_library\")\n\nswift_library(\n name = \"XcodeProj\",\n srcs = glob([\"Sources/XcodeProj/**/*.swift\"]),\n visibility = [\"//visibility:public\"],\n deps = [\n \"@com_github_tadija_aexml//:AEXML\",\n \"@com_github_kylef_pathkit//:PathKit\",\n ],\n)\n", + "sha256": "70a4504d5cfd30e1c1968df3929bf0c40cba91bdb2ef0e3143c0e72bbe1d8092", + "strip_prefix": "XcodeProj-8.9.0", + "url": "https://github.com/tuist/XcodeProj/archive/refs/tags/8.9.0.tar.gz" + } + }, + "com_github_apple_swift_collections": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "load(\"@build_bazel_rules_swift//swift:swift.bzl\", \"swift_library\")\n\nswift_library(\n name = \"Collections\",\n srcs = glob([\"Sources/Collections/**/*.swift\"]),\n deps = [\n \"@com_github_apple_swift_collections//:DequeModule\",\n ],\n visibility = [\"//visibility:public\"],\n)\n\nswift_library(\n name = \"DequeModule\",\n srcs = glob([\"Sources/DequeModule/**/*.swift\"]),\n visibility = [\"//visibility:public\"],\n)\n\nswift_library(\n name = \"OrderedCollections\",\n srcs = glob([\"Sources/OrderedCollections/**/*.swift\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "1a2ec8cc6c63c383a9dd4eb975bf83ce3bc7a2ac21a0289a50dae98a576327d6", + "strip_prefix": "swift-collections-4cab1c1c417855b90e9cfde40349a43aff99c536", + "url": "https://github.com/apple/swift-collections/archive/4cab1c1c417855b90e9cfde40349a43aff99c536.tar.gz" + } + } }, - { - "extensionBzlFile": "@bazel_tools//tools/android:android_extensions.bzl", - "extensionName": "remote_android_tools_extensions", - "usingModule": "bazel_tools@_", - "location": { - "file": "@@bazel_tools//:MODULE.bazel", - "line": 42, - "column": 42 - }, - "imports": { - "android_gmaven_r8": "android_gmaven_r8", - "android_tools": "android_tools" - }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true - } - ], - "deps": { - "rules_cc": "rules_cc@0.0.9", - "rules_java": "rules_java@7.1.0", - "rules_license": "rules_license@0.0.7", - "rules_proto": "rules_proto@4.0.0", - "rules_python": "rules_python@0.4.0", - "platforms": "platforms@0.0.7", - "com_google_protobuf": "protobuf@3.19.6", - "zlib": "zlib@1.3", - "build_bazel_apple_support": "apple_support@1.5.0", - "local_config_platform": "local_config_platform@_" - } - }, - "local_config_platform@_": { - "name": "local_config_platform", - "version": "", - "key": "local_config_platform@_", - "repoName": "local_config_platform", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [], - "extensionUsages": [], - "deps": { - "platforms": "platforms@0.0.7", - "bazel_tools": "bazel_tools@_" - } - }, - "rules_cc@0.0.9": { - "name": "rules_cc", - "version": "0.0.9", - "key": "rules_cc@0.0.9", - "repoName": "rules_cc", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [ - "@local_config_cc_toolchains//:all" - ], - "extensionUsages": [ - { - "extensionBzlFile": "@bazel_tools//tools/cpp:cc_configure.bzl", - "extensionName": "cc_configure_extension", - "usingModule": "rules_cc@0.0.9", - "location": { - "file": "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel", - "line": 9, - "column": 29 - }, - "imports": { - "local_config_cc_toolchains": "local_config_cc_toolchains" - }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true - } - ], - "deps": { - "platforms": "platforms@0.0.7", - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "name": "rules_cc~0.0.9", - "urls": [ - "https://github.com/bazelbuild/rules_cc/releases/download/0.0.9/rules_cc-0.0.9.tar.gz" - ], - "integrity": "sha256-IDeHW5pEVtzkp50RKorohbvEqtlo5lh9ym5k86CQDN8=", - "strip_prefix": "rules_cc-0.0.9", - "remote_patches": { - "https://bcr.bazel.build/modules/rules_cc/0.0.9/patches/module_dot_bazel_version.patch": "sha256-mM+qzOI0SgAdaJBlWOSMwMPKpaA9b7R37Hj/tp5bb4g=" - }, - "remote_patch_strip": 0 - } - } - }, - "rules_java@7.1.0": { - "name": "rules_java", - "version": "7.1.0", - "key": "rules_java@7.1.0", - "repoName": "rules_java", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [ - "//toolchains:all", - "@local_jdk//:runtime_toolchain_definition", - "@local_jdk//:bootstrap_runtime_toolchain_definition", - "@remotejdk11_linux_toolchain_config_repo//:all", - "@remotejdk11_linux_aarch64_toolchain_config_repo//:all", - "@remotejdk11_linux_ppc64le_toolchain_config_repo//:all", - "@remotejdk11_linux_s390x_toolchain_config_repo//:all", - "@remotejdk11_macos_toolchain_config_repo//:all", - "@remotejdk11_macos_aarch64_toolchain_config_repo//:all", - "@remotejdk11_win_toolchain_config_repo//:all", - "@remotejdk11_win_arm64_toolchain_config_repo//:all", - "@remotejdk17_linux_toolchain_config_repo//:all", - "@remotejdk17_linux_aarch64_toolchain_config_repo//:all", - "@remotejdk17_linux_ppc64le_toolchain_config_repo//:all", - "@remotejdk17_linux_s390x_toolchain_config_repo//:all", - "@remotejdk17_macos_toolchain_config_repo//:all", - "@remotejdk17_macos_aarch64_toolchain_config_repo//:all", - "@remotejdk17_win_toolchain_config_repo//:all", - "@remotejdk17_win_arm64_toolchain_config_repo//:all", - "@remotejdk21_linux_toolchain_config_repo//:all", - "@remotejdk21_linux_aarch64_toolchain_config_repo//:all", - "@remotejdk21_macos_toolchain_config_repo//:all", - "@remotejdk21_macos_aarch64_toolchain_config_repo//:all", - "@remotejdk21_win_toolchain_config_repo//:all" - ], - "extensionUsages": [ - { - "extensionBzlFile": "@rules_java//java:extensions.bzl", - "extensionName": "toolchains", - "usingModule": "rules_java@7.1.0", - "location": { - "file": "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel", - "line": 19, - "column": 27 - }, - "imports": { - "remote_java_tools": "remote_java_tools", - "remote_java_tools_linux": "remote_java_tools_linux", - "remote_java_tools_windows": "remote_java_tools_windows", - "remote_java_tools_darwin_x86_64": "remote_java_tools_darwin_x86_64", - "remote_java_tools_darwin_arm64": "remote_java_tools_darwin_arm64", - "local_jdk": "local_jdk", - "remotejdk11_linux_toolchain_config_repo": "remotejdk11_linux_toolchain_config_repo", - "remotejdk11_linux_aarch64_toolchain_config_repo": "remotejdk11_linux_aarch64_toolchain_config_repo", - "remotejdk11_linux_ppc64le_toolchain_config_repo": "remotejdk11_linux_ppc64le_toolchain_config_repo", - "remotejdk11_linux_s390x_toolchain_config_repo": "remotejdk11_linux_s390x_toolchain_config_repo", - "remotejdk11_macos_toolchain_config_repo": "remotejdk11_macos_toolchain_config_repo", - "remotejdk11_macos_aarch64_toolchain_config_repo": "remotejdk11_macos_aarch64_toolchain_config_repo", - "remotejdk11_win_toolchain_config_repo": "remotejdk11_win_toolchain_config_repo", - "remotejdk11_win_arm64_toolchain_config_repo": "remotejdk11_win_arm64_toolchain_config_repo", - "remotejdk17_linux_toolchain_config_repo": "remotejdk17_linux_toolchain_config_repo", - "remotejdk17_linux_aarch64_toolchain_config_repo": "remotejdk17_linux_aarch64_toolchain_config_repo", - "remotejdk17_linux_ppc64le_toolchain_config_repo": "remotejdk17_linux_ppc64le_toolchain_config_repo", - "remotejdk17_linux_s390x_toolchain_config_repo": "remotejdk17_linux_s390x_toolchain_config_repo", - "remotejdk17_macos_toolchain_config_repo": "remotejdk17_macos_toolchain_config_repo", - "remotejdk17_macos_aarch64_toolchain_config_repo": "remotejdk17_macos_aarch64_toolchain_config_repo", - "remotejdk17_win_toolchain_config_repo": "remotejdk17_win_toolchain_config_repo", - "remotejdk17_win_arm64_toolchain_config_repo": "remotejdk17_win_arm64_toolchain_config_repo", - "remotejdk21_linux_toolchain_config_repo": "remotejdk21_linux_toolchain_config_repo", - "remotejdk21_linux_aarch64_toolchain_config_repo": "remotejdk21_linux_aarch64_toolchain_config_repo", - "remotejdk21_macos_toolchain_config_repo": "remotejdk21_macos_toolchain_config_repo", - "remotejdk21_macos_aarch64_toolchain_config_repo": "remotejdk21_macos_aarch64_toolchain_config_repo", - "remotejdk21_win_toolchain_config_repo": "remotejdk21_win_toolchain_config_repo" - }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true - } - ], - "deps": { - "platforms": "platforms@0.0.7", - "rules_cc": "rules_cc@0.0.9", - "bazel_skylib": "bazel_skylib@1.3.0", - "rules_proto": "rules_proto@4.0.0", - "rules_license": "rules_license@0.0.7", - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "name": "rules_java~7.1.0", - "urls": [ - "https://github.com/bazelbuild/rules_java/releases/download/7.1.0/rules_java-7.1.0.tar.gz" - ], - "integrity": "sha256-o3pOX2OrgnFuXdau75iO2EYcegC46TYnImKJn1h81OE=", - "strip_prefix": "", - "remote_patches": {}, - "remote_patch_strip": 0 - } - } - }, - "rules_license@0.0.7": { - "name": "rules_license", - "version": "0.0.7", - "key": "rules_license@0.0.7", - "repoName": "rules_license", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [], - "extensionUsages": [], - "deps": { - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "name": "rules_license~0.0.7", - "urls": [ - "https://github.com/bazelbuild/rules_license/releases/download/0.0.7/rules_license-0.0.7.tar.gz" - ], - "integrity": "sha256-RTHezLkTY5ww5cdRKgVNXYdWmNrrddjPkPKEN1/nw2A=", - "strip_prefix": "", - "remote_patches": {}, - "remote_patch_strip": 0 - } - } - }, - "rules_proto@4.0.0": { - "name": "rules_proto", - "version": "4.0.0", - "key": "rules_proto@4.0.0", - "repoName": "rules_proto", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [], - "extensionUsages": [], - "deps": { - "bazel_skylib": "bazel_skylib@1.3.0", - "rules_cc": "rules_cc@0.0.9", - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "name": "rules_proto~4.0.0", - "urls": [ - "https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.zip" - ], - "integrity": "sha256-Lr5z6xyuRA19pNtRYMGjKaynwQpck4H/lwYyVjyhoq4=", - "strip_prefix": "rules_proto-4.0.0", - "remote_patches": { - "https://bcr.bazel.build/modules/rules_proto/4.0.0/patches/module_dot_bazel.patch": "sha256-MclJO7tIAM2ElDAmscNId9pKTpOuDGHgVlW/9VBOIp0=" - }, - "remote_patch_strip": 0 - } - } - }, - "rules_python@0.4.0": { - "name": "rules_python", - "version": "0.4.0", - "key": "rules_python@0.4.0", - "repoName": "rules_python", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [ - "@bazel_tools//tools/python:autodetecting_toolchain" - ], - "extensionUsages": [ - { - "extensionBzlFile": "@rules_python//bzlmod:extensions.bzl", - "extensionName": "pip_install", - "usingModule": "rules_python@0.4.0", - "location": { - "file": "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel", - "line": 7, - "column": 28 - }, - "imports": { - "pypi__click": "pypi__click", - "pypi__pip": "pypi__pip", - "pypi__pip_tools": "pypi__pip_tools", - "pypi__pkginfo": "pypi__pkginfo", - "pypi__setuptools": "pypi__setuptools", - "pypi__wheel": "pypi__wheel" - }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true - } - ], - "deps": { - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "name": "rules_python~0.4.0", - "urls": [ - "https://github.com/bazelbuild/rules_python/releases/download/0.4.0/rules_python-0.4.0.tar.gz" - ], - "integrity": "sha256-lUqom0kb5KCDMEosuDgBnIuMNyCnq7nEy4GseiQjDOo=", - "strip_prefix": "", - "remote_patches": { - "https://bcr.bazel.build/modules/rules_python/0.4.0/patches/propagate_pip_install_dependencies.patch": "sha256-v7S/dem/mixg63MF4KoRGDA4KEol9ab/tIVp+6Xq0D0=", - "https://bcr.bazel.build/modules/rules_python/0.4.0/patches/module_dot_bazel.patch": "sha256-kG4VIfWxQazzTuh50mvsx6pmyoRVA4lfH5rkto/Oq+Y=" - }, - "remote_patch_strip": 1 - } - } - }, - "platforms@0.0.7": { - "name": "platforms", - "version": "0.0.7", - "key": "platforms@0.0.7", - "repoName": "platforms", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [], - "extensionUsages": [], - "deps": { - "rules_license": "rules_license@0.0.7", - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "name": "platforms", - "urls": [ - "https://github.com/bazelbuild/platforms/releases/download/0.0.7/platforms-0.0.7.tar.gz" - ], - "integrity": "sha256-OlYcmee9vpFzqmU/1Xn+hJ8djWc5V4CrR3Cx84FDHVE=", - "strip_prefix": "", - "remote_patches": {}, - "remote_patch_strip": 0 - } - } - }, - "protobuf@3.19.6": { - "name": "protobuf", - "version": "3.19.6", - "key": "protobuf@3.19.6", - "repoName": "protobuf", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [], - "extensionUsages": [], - "deps": { - "bazel_skylib": "bazel_skylib@1.3.0", - "zlib": "zlib@1.3", - "rules_python": "rules_python@0.4.0", - "rules_cc": "rules_cc@0.0.9", - "rules_proto": "rules_proto@4.0.0", - "rules_java": "rules_java@7.1.0", - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "name": "protobuf~3.19.6", - "urls": [ - "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v3.19.6.zip" - ], - "integrity": "sha256-OH4sVZuyx8G8N5jE5s/wFTgaebJ1hpavy/johzC0c4k=", - "strip_prefix": "protobuf-3.19.6", - "remote_patches": { - "https://bcr.bazel.build/modules/protobuf/3.19.6/patches/relative_repo_names.patch": "sha256-w/5gw/zGv8NFId+669hcdw1Uus2lxgYpulATHIwIByI=", - "https://bcr.bazel.build/modules/protobuf/3.19.6/patches/remove_dependency_on_rules_jvm_external.patch": "sha256-THUTnVgEBmjA0W7fKzIyZOVG58DnW9HQTkr4D2zKUUc=", - "https://bcr.bazel.build/modules/protobuf/3.19.6/patches/add_module_dot_bazel_for_examples.patch": "sha256-s/b1gi3baK3LsXefI2rQilhmkb2R5jVJdnT6zEcdfHY=", - "https://bcr.bazel.build/modules/protobuf/3.19.6/patches/module_dot_bazel.patch": "sha256-S0DEni8zgx7rHscW3z/rCEubQnYec0XhNet640cw0h4=" - }, - "remote_patch_strip": 1 - } - } - }, - "zlib@1.3": { - "name": "zlib", - "version": "1.3", - "key": "zlib@1.3", - "repoName": "zlib", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [], - "extensionUsages": [], - "deps": { - "platforms": "platforms@0.0.7", - "rules_cc": "rules_cc@0.0.9", - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "name": "zlib~1.3", - "urls": [ - "https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.gz" - ], - "integrity": "sha256-/wukwpIBPbwnUws6geH5qBPNOd4Byl4Pi/NVcC76WT4=", - "strip_prefix": "zlib-1.3", - "remote_patches": { - "https://bcr.bazel.build/modules/zlib/1.3/patches/add_build_file.patch": "sha256-Ei+FYaaOo7A3jTKunMEodTI0Uw5NXQyZEcboMC8JskY=", - "https://bcr.bazel.build/modules/zlib/1.3/patches/module_dot_bazel.patch": "sha256-fPWLM+2xaF/kuy+kZc1YTfW6hNjrkG400Ho7gckuyJk=" - }, - "remote_patch_strip": 0 - } - } - }, - "apple_support@1.5.0": { - "name": "apple_support", - "version": "1.5.0", - "key": "apple_support@1.5.0", - "repoName": "build_bazel_apple_support", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [ - "@local_config_apple_cc_toolchains//:all" - ], - "extensionUsages": [ - { - "extensionBzlFile": "@build_bazel_apple_support//crosstool:setup.bzl", - "extensionName": "apple_cc_configure_extension", - "usingModule": "apple_support@1.5.0", - "location": { - "file": "https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel", - "line": 17, - "column": 35 - }, - "imports": { - "local_config_apple_cc": "local_config_apple_cc", - "local_config_apple_cc_toolchains": "local_config_apple_cc_toolchains" - }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true - } - ], - "deps": { - "bazel_skylib": "bazel_skylib@1.3.0", - "platforms": "platforms@0.0.7", - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "name": "apple_support~1.5.0", - "urls": [ - "https://github.com/bazelbuild/apple_support/releases/download/1.5.0/apple_support.1.5.0.tar.gz" - ], - "integrity": "sha256-miM41vja0yRPgj8txghKA+TQ+7J8qJLclw5okNW0gYQ=", - "strip_prefix": "", - "remote_patches": {}, - "remote_patch_strip": 0 - } - } - }, - "bazel_skylib@1.3.0": { - "name": "bazel_skylib", - "version": "1.3.0", - "key": "bazel_skylib@1.3.0", - "repoName": "bazel_skylib", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [ - "//toolchains/unittest:cmd_toolchain", - "//toolchains/unittest:bash_toolchain" - ], - "extensionUsages": [], - "deps": { - "platforms": "platforms@0.0.7", - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "name": "bazel_skylib~1.3.0", - "urls": [ - "https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz" - ], - "integrity": "sha256-dNVE2W9KW7Yw1GXKi7z+Ix41lOWq5X4e2/F6brPKJQY=", - "strip_prefix": "", - "remote_patches": {}, - "remote_patch_strip": 0 - } + "recordedRepoMappingEntries": [ + [ + "rules_xcodeproj+", + "bazel_tools", + "bazel_tools" + ] + ] } } - }, - "moduleExtensions": {} + } } diff --git a/Telegram/BUILD b/Telegram/BUILD index f2f2f00f06..c40fa37fe1 100644 --- a/Telegram/BUILD +++ b/Telegram/BUILD @@ -16,11 +16,6 @@ load("@build_bazel_rules_apple//apple:resources.bzl", "swift_intent_library", ) -load("@build_bazel_rules_apple//apple:watchos.bzl", - "watchos_application", - "watchos_extension", -) - load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library", ) @@ -48,7 +43,6 @@ load( "telegram_team_id", "telegram_enable_icloud", "telegram_enable_siri", - "telegram_enable_watch", ) load("@build_bazel_rules_apple//apple:resources.bzl", @@ -145,7 +139,6 @@ genrule( ) minimum_os_version = "12.0" -minimum_watchos_version="9.0" notificationServiceExtensionVersion = "v1" @@ -259,13 +252,6 @@ filegroup( ], ) -filegroup( - name = "WatchAppStringResources", - srcs = glob([ - "Telegram-iOS/*.lproj/Localizable.strings", - ], exclude = ["Telegram-iOS/*.lproj/**/.*"]), -) - filegroup( name = "AppIntentVocabularyResources", srcs = glob([ @@ -301,13 +287,6 @@ filegroup( ], exclude = ["Telegram-iOS/DefaultAppIcon.xcassets/**/.*"]), ) -filegroup( - name = "BlackAppIcon", - srcs = glob([ - "Telegram-iOS/BlackIcon.xcassets/**/*", - ], exclude = ["Telegram-iOS/BlackIcon.xcassets/**/.*"]), -) - filegroup( name = "DefaultIcon", srcs = glob([ @@ -315,13 +294,6 @@ filegroup( ]), ) -filegroup( - name = "AdditionalIcons", - srcs = glob([ - "Telegram-iOS/*.png", - ]), -) - alternate_icon_folders = [ "BlackIcon", "BlackClassicIcon", @@ -568,62 +540,6 @@ plist_fragment( ]) ) -filegroup( - name = "TelegramWatchExtensionResources", - srcs = glob([ - "Watch/Extension/Resources/**/*", - ], exclude = ["Watch/Extension/Resources/**/.*"]), -) - -filegroup( - name = "TelegramWatchAppResources", - srcs = glob([ - "Watch/Extension/Resources/**/*.png", - ], exclude = ["Watch/Extension/Resources/**/.*"]), -) - -filegroup( - name = "TelegramWatchAppAssets", - srcs = glob([ - "Watch/App/Assets.xcassets/**/*", - ], exclude = ["Watch/App/Assets.xcassets/**/.*"]), -) - -filegroup( - name = "TelegramWatchAppInterface", - srcs = glob([ - "Watch/App/Base.lproj/Interface.storyboard", - ]), -) - -objc_library( - name = "TelegramWatchLib", - srcs = glob([ - "Watch/Extension/**/*.m", - "Watch/SSignalKit/**/*.m", - "Watch/Bridge/**/*.m", - "Watch/WatchCommonWatch/**/*.m", - "Watch/Extension/**/*.h", - "Watch/SSignalKit/**/*.h", - "Watch/Bridge/**/*.h", - "Watch/WatchCommonWatch/**/*.h", - ]), - copts = [ - "-DTARGET_OS_WATCH=1", - "-ITelegram/Watch", - "-ITelegram/Watch/Extension", - "-ITelegram/Watch/Bridge", - ], - sdk_frameworks = [ - "WatchKit", - "WatchConnectivity", - "ClockKit", - "UserNotifications", - "CoreLocation", - "CoreGraphics", - ], -) - plist_fragment( name = "VersionInfoPlist", extension = "plist", @@ -656,162 +572,6 @@ plist_fragment( """ ) -plist_fragment( - name = "WatchExtensionNSExtensionInfoPlist", - extension = "plist", - template = - """ - NSExtension - - NSExtensionAttributes - - WKAppBundleIdentifier - {telegram_bundle_id}.watchkitapp - - NSExtensionPointIdentifier - com.apple.watchkit - - """.format( - telegram_bundle_id = telegram_bundle_id, - ) -) - -plist_fragment( - name = "WatchAppCompanionInfoPlist", - extension = "plist", - template = - """ - WKCompanionAppBundleIdentifier - {telegram_bundle_id} - """.format( - telegram_bundle_id = telegram_bundle_id, - ) -) - -plist_fragment( - name = "WatchExtensionInfoPlist", - extension = "plist", - template = - """ - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - {telegram_bundle_id}.watchkitapp.watchkitextension - CFBundleName - Telegram - CFBundlePackageType - XPC! - WKExtensionDelegateClassName - TGExtensionDelegate - """.format( - telegram_bundle_id = telegram_bundle_id, - ) -) - -plist_fragment( - name = "WatchAppInfoPlist", - extension = "plist", - template = - """ - CFBundleDevelopmentRegion - en - CFBundleIdentifier - {telegram_bundle_id}.watchkitapp - CFBundleName - Telegram - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - - WKWatchKitApp - - CFBundlePackageType - APPL - """.format( - telegram_bundle_id = telegram_bundle_id, - ) -) - -watchos_extension( - name = "TelegramWatchExtension", - bundle_id = "{telegram_bundle_id}.watchkitapp.watchkitextension".format( - telegram_bundle_id = telegram_bundle_id, - ), - bundle_name = "TelegramWatchExtension", - infoplists = [ - ":WatchExtensionInfoPlist", - ":VersionInfoPlist", - ":BuildNumberInfoPlist", - ":AppNameInfoPlist", - ":WatchExtensionNSExtensionInfoPlist", - ], - minimum_os_version = minimum_watchos_version, - provisioning_profile = select({ - ":disableProvisioningProfilesSetting": None, - "//conditions:default": "@build_configuration//provisioning:WatchExtension.mobileprovision", - }), - resources = [ - ":TelegramWatchExtensionResources", - ], - strings = [ - ":WatchAppStringResources", - ], - deps = [ - ":TelegramWatchLib", - ], -) - - -genrule( - name = "StripWatchosStubBinary", - cmd_bash = -""" - echo 'lipo -remove armv7k -remove arm64 -remove arm64e $$1/TelegramWatch.app/_WatchKitStub/WK -output $$1/TelegramWatch.app/_WatchKitStub/WK' > $(location StripWatchosStubBinary.sh) - echo '' >> $(location StripWatchosStubBinary.sh) -""", - outs = [ - "StripWatchosStubBinary.sh", - ], - executable = True, - visibility = [ - "//visibility:public", - ] -) - -watchos_application( - name = "TelegramWatchApp", - bundle_id = "{telegram_bundle_id}.watchkitapp".format( - telegram_bundle_id = telegram_bundle_id, - ), - bundle_name = "TelegramWatch", - extension = ":TelegramWatchExtension", - infoplists = [ - ":WatchAppInfoPlist", - ":VersionInfoPlist", - ":BuildNumberInfoPlist", - ":AppNameInfoPlist", - ":WatchAppCompanionInfoPlist", - ], - minimum_os_version = minimum_watchos_version, - provisioning_profile = select({ - ":disableProvisioningProfilesSetting": None, - "//conditions:default": "@build_configuration//provisioning:WatchApp.mobileprovision", - }), - ipa_post_processor = ":StripWatchosStubBinary", - resources = [ - ":TelegramWatchAppResources", - ":TelegramWatchAppAssets", - ], - storyboards = [ - ":TelegramWatchAppInterface", - ], - strings = [ - ], -) - plist_fragment( name = "MtProtoKitInfoPlist", extension = "plist", @@ -1942,11 +1702,9 @@ ios_application( alternate_icons = [ ":{}".format(name) for name in alternate_icon_folders ], - #ipa_post_processor = ":AddAlternateIcons", resources = [ ":LaunchScreen", ":DefaultAppIcon", - #":AdditionalIcons", ], frameworks = [ ":MtProtoKitFramework", @@ -1969,10 +1727,6 @@ ios_application( ":BroadcastUploadExtension", ], }), - watch_application = select({ - ":disableExtensionsSetting": None, - "//conditions:default": None#":TelegramWatchApp", - }) if telegram_enable_watch else None, deps = [ ":Main", ":Lib", @@ -2090,53 +1844,3 @@ ios_application( "//third-party/libvpx:vpx", ], ) - -swift_library( - name = "TelegramCoreBuildTestLib", - module_name = "TelegramCoreBuildTestLib", - srcs = glob([ - "Tests/TelegramCoreBuildTest/**/*.swift", - ]), - copts = [ - "-warnings-as-errors", - ], - data = [ - ":WidgetAssets", - ], - deps = [ - "//submodules/BuildConfig:BuildConfig", - "//submodules/WidgetItems:WidgetItems_iOS14", - "//submodules/WidgetItemsUtils:WidgetItemsUtils", - "//submodules/AppLockState:AppLockState", - "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", - "//submodules/Postbox:Postbox", - "//submodules/TelegramCore:TelegramCore", - "//submodules/OpenSSLEncryptionProvider:OpenSSLEncryptionProvider", - "//Telegram:GeneratedSources", - ], -) - -ios_application( - name = "TelegramCoreBuildTest", - bundle_id = "{telegram_bundle_id}".format( - telegram_bundle_id = telegram_bundle_id, - ), - families = ["iphone", "ipad"], - minimum_os_version = minimum_os_version, - provisioning_profile = select({ - ":disableProvisioningProfilesSetting": None, - "//conditions:default": "@build_configuration//provisioning:Telegram.mobileprovision", - }), - entitlements = ":TelegramEntitlements.entitlements", - infoplists = [ - ":TelegramInfoPlist", - ":BuildNumberInfoPlist", - ":VersionInfoPlist", - ":RequiredDeviceCapabilitiesPlist", - ":UrlTypesInfoPlist", - ], - frameworks = [ - ":TelegramCoreFramework", - ], - deps = [":TelegramCoreBuildTestLib"], -) diff --git a/build-system/Make/Make.py b/build-system/Make/Make.py index 67cbb89c3e..03251a5967 100644 --- a/build-system/Make/Make.py +++ b/build-system/Make/Make.py @@ -90,7 +90,9 @@ class BazelCommandLine: # 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), + #'--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 = [ @@ -106,7 +108,7 @@ class BazelCommandLine: # 1. resolves issues with the linker caused by the swift-objc mixing. # 2. makes the resulting binaries significantly smaller (up to 9% for this project). #'--swiftcopt=-num-threads', '--swiftcopt=1', - '--swiftcopt=-num-threads', '--swiftcopt=1', + #'--@build_bazel_rules_swift//swift:copt="-num-threads 0"', # Strip unsused code. '--features=dead_strip', @@ -197,8 +199,7 @@ class BazelCommandLine: # Require DSYM files as build output. '--output_groups=+dsyms', - '--swiftcopt=-num-threads', - '--swiftcopt=0', + #'--@build_bazel_rules_swift//swift:copt="-num-threads 0"', ] + self.common_release_args else: raise Exception('Unknown configuration {}'.format(configuration)) diff --git a/submodules/AccountContext/Sources/ChatController.swift b/submodules/AccountContext/Sources/ChatController.swift index 5931ae17b1..4cab8932e6 100644 --- a/submodules/AccountContext/Sources/ChatController.swift +++ b/submodules/AccountContext/Sources/ChatController.swift @@ -1166,7 +1166,6 @@ public enum ChatCustomContentsKind: Equatable { case quickReplyMessageInput(shortcut: String, shortcutType: ChatQuickReplyShortcutType) case businessLinkSetup(link: TelegramBusinessChatLinks.Link) case hashTagSearch(publicPosts: Bool) - case postSuggestions(price: StarsAmount) } public protocol ChatCustomContentsProtocol: AnyObject { diff --git a/submodules/AnimationCompression/BUILD b/submodules/AnimationCompression/BUILD index 55b637ec06..812408ebf6 100644 --- a/submodules/AnimationCompression/BUILD +++ b/submodules/AnimationCompression/BUILD @@ -69,7 +69,7 @@ objc_library( "DctHuffman/Sources/**/*.m", "DctHuffman/Sources/**/*.mm", "DctHuffman/Sources/**/*.h", - ]), + ], allow_empty=True), copts = [], hdrs = glob([ "DctHuffman/PublicHeaders/**/*.h", diff --git a/submodules/AppBundle/BUILD b/submodules/AppBundle/BUILD index 92d153bd64..3c935d1e30 100644 --- a/submodules/AppBundle/BUILD +++ b/submodules/AppBundle/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/AsyncDisplayKit/BUILD b/submodules/AsyncDisplayKit/BUILD index c7b86e3485..856b29e81d 100644 --- a/submodules/AsyncDisplayKit/BUILD +++ b/submodules/AsyncDisplayKit/BUILD @@ -4,7 +4,7 @@ public_headers = glob([ private_headers = glob([ "Source/*.h", -]) +], allow_empty=True) objc_library( name = "AsyncDisplayKit", @@ -13,7 +13,7 @@ objc_library( srcs = glob([ "Source/**/*.m", "Source/**/*.mm", - ]) + private_headers, + ], allow_empty=True) + private_headers, copts = [ "-Werror", ], diff --git a/submodules/AsyncDisplayKit/Source/ASDisplayNode+Layout.mm b/submodules/AsyncDisplayKit/Source/ASDisplayNode+Layout.mm index 32934a599c..8842b56324 100644 --- a/submodules/AsyncDisplayKit/Source/ASDisplayNode+Layout.mm +++ b/submodules/AsyncDisplayKit/Source/ASDisplayNode+Layout.mm @@ -909,7 +909,10 @@ ASLayoutElementStyleExtensibilityForwarding MutexLocker l(__instanceLock__); NSArray *sublayouts = _calculatedDisplayNodeLayout.layout.sublayouts; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvla-cxx-extension" unowned ASLayout *cSublayouts[sublayouts.count]; +#pragma clang diagnostic pop [sublayouts getObjects:cSublayouts range:NSMakeRange(0, AS_ARRAY_SIZE(cSublayouts))]; // Fast-path if we are in the correct state (likely). @@ -927,7 +930,10 @@ ASLayoutElementStyleExtensibilityForwarding } } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvla-cxx-extension" NSArray *layoutNodes = ASArrayByFlatMapping(sublayouts, ASLayout *layout, (ASDisplayNode *)layout.layoutElement); +#pragma clang diagnostic pop NSIndexSet *insertions, *deletions; [_subnodes asdk_diffWithArray:layoutNodes insertions:&insertions deletions:&deletions]; if (insertions.count > 0) { diff --git a/submodules/AsyncDisplayKit/Source/ASExperimentalFeatures.mm b/submodules/AsyncDisplayKit/Source/ASExperimentalFeatures.mm index 653db2c370..7b49efdeb6 100644 --- a/submodules/AsyncDisplayKit/Source/ASExperimentalFeatures.mm +++ b/submodules/AsyncDisplayKit/Source/ASExperimentalFeatures.mm @@ -31,9 +31,15 @@ NSArray *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags // Go through all names, testing each bit. NSUInteger i = 0; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvla-cxx-extension" + return ASArrayByFlatMapping(allNames, NSString *name, ({ (flags & (1 << i++)) ? name : nil; })); + +#pragma clang diagnostic pop } // O(N^2) but with counts this small, it's probably faster diff --git a/submodules/AsyncDisplayKit/Source/ASInternalHelpers.mm b/submodules/AsyncDisplayKit/Source/ASInternalHelpers.mm index a9926ccca4..c0f06b2f02 100644 --- a/submodules/AsyncDisplayKit/Source/ASInternalHelpers.mm +++ b/submodules/AsyncDisplayKit/Source/ASInternalHelpers.mm @@ -140,7 +140,10 @@ Class _Nullable ASGetClassFromType(const char * _Nullable type) // Copy type[2..(end-1)]. So @"UIImage" -> UIImage size_t resultLength = typeLength - 3; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvla-cxx-extension" char className[resultLength + 1]; +#pragma clang diagnostic pop strncpy(className, type + 2, resultLength); className[resultLength] = '\0'; return objc_getClass(className); diff --git a/submodules/AsyncDisplayKit/Source/ASLayout.mm b/submodules/AsyncDisplayKit/Source/ASLayout.mm index 6a6a96f24c..03ce0c111a 100644 --- a/submodules/AsyncDisplayKit/Source/ASLayout.mm +++ b/submodules/AsyncDisplayKit/Source/ASLayout.mm @@ -235,7 +235,10 @@ static std::atomic_bool static_retainsSublayoutLayoutElements = ATOMIC_VAR_INIT( } } else if (sublayoutsCount > 0) { // Fast-reverse-enumerate the sublayouts array by copying it into a C-array and push_front'ing each into the queue. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvla-cxx-extension" unowned ASLayout *rawSublayouts[sublayoutsCount]; +#pragma clang diagnostic pop [layout->_sublayouts getObjects:rawSublayouts range:NSMakeRange(0, sublayoutsCount)]; for (NSInteger i = sublayoutsCount - 1; i >= 0; i--) { queue.push_front({rawSublayouts[i], absolutePosition + rawSublayouts[i].position}); diff --git a/submodules/AsyncDisplayKit/Source/ASLayoutSpec.mm b/submodules/AsyncDisplayKit/Source/ASLayoutSpec.mm index 6123e4d734..dacb5b256a 100644 --- a/submodules/AsyncDisplayKit/Source/ASLayoutSpec.mm +++ b/submodules/AsyncDisplayKit/Source/ASLayoutSpec.mm @@ -159,7 +159,10 @@ ASLayoutElementStyleExtensibilityForwarding const auto result = [NSMutableArray array]; if (NSArray *children = self.children) { // Use tiny descriptions because these trees can get nested very deep. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvla-cxx-extension" const auto tinyDescriptions = ASArrayByFlatMapping(children, id object, ASObjectDescriptionMakeTiny(object)); +#pragma clang diagnostic pop [result addObject:@{ @"children": tinyDescriptions }]; } return result; @@ -290,7 +293,10 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__) { NSArray *children = self.children; const auto count = children.count; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvla-cxx-extension" ASLayout *rawSublayouts[count]; +#pragma clang diagnostic pop int i = 0; CGSize size = constrainedSize.min; diff --git a/submodules/AsyncDisplayKit/Source/ASMainThreadDeallocation.mm b/submodules/AsyncDisplayKit/Source/ASMainThreadDeallocation.mm index 4b16c932d2..68e4a709dd 100644 --- a/submodules/AsyncDisplayKit/Source/ASMainThreadDeallocation.mm +++ b/submodules/AsyncDisplayKit/Source/ASMainThreadDeallocation.mm @@ -31,7 +31,11 @@ // Will be unused if assertions are disabled. __unused int scanResult = sscanf(ivarsObj.objCType, "[%u^{objc_ivar}]", &count); ASDisplayNodeAssert(scanResult == 1, @"Unexpected type in NSValue: %s", ivarsObj.objCType); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvla-cxx-extension" Ivar ivars[count]; +#pragma clang diagnostic pop [ivarsObj getValue:ivars]; for (Ivar ivar : ivars) { diff --git a/submodules/BroadcastUploadHelpers/BUILD b/submodules/BroadcastUploadHelpers/BUILD index 276b7c9756..fb80ca4833 100644 --- a/submodules/BroadcastUploadHelpers/BUILD +++ b/submodules/BroadcastUploadHelpers/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/BrowserUI/Sources/BrowserBookmarksScreen.swift b/submodules/BrowserUI/Sources/BrowserBookmarksScreen.swift index d694b93de4..7bb140e7a8 100644 --- a/submodules/BrowserUI/Sources/BrowserBookmarksScreen.swift +++ b/submodules/BrowserUI/Sources/BrowserBookmarksScreen.swift @@ -175,6 +175,7 @@ public final class BrowserBookmarksScreen: ViewController { }, forceUpdateWarpContents: { }, playShakeAnimation: { }, displayQuickShare: { _, _ ,_ in + }, updateChatLocationThread: { _ in }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil)) diff --git a/submodules/BrowserUI/Sources/BrowserWebContent.swift b/submodules/BrowserUI/Sources/BrowserWebContent.swift index 3ffa7a7d6a..0f6923e00b 100644 --- a/submodules/BrowserUI/Sources/BrowserWebContent.swift +++ b/submodules/BrowserUI/Sources/BrowserWebContent.swift @@ -33,6 +33,15 @@ private final class TonSchemeHandler: NSObject, WKURLSchemeHandler { init(proxyServerHost: String, sourceTask: any WKURLSchemeTask) { self.sourceTask = sourceTask + final class BoxedSourceTask: @unchecked Sendable { + let value: any WKURLSchemeTask + + init(value: any WKURLSchemeTask) { + self.value = value + } + } + let sourceTaskReference = BoxedSourceTask(value: sourceTask) + let requestUrl = sourceTask.request.url var mappedHost: String = "" @@ -57,7 +66,7 @@ private final class TonSchemeHandler: NSObject, WKURLSchemeHandler { } if let error { - sourceTask.didFailWithError(error) + sourceTaskReference.value.didFailWithError(error) } else { if let response { if let response = response as? HTTPURLResponse, let requestUrl { @@ -67,18 +76,18 @@ private final class TonSchemeHandler: NSObject, WKURLSchemeHandler { httpVersion: "HTTP/1.1", headerFields: response.allHeaderFields as? [String: String] ?? [:] ) { - sourceTask.didReceive(updatedResponse) + sourceTaskReference.value.didReceive(updatedResponse) } else { - sourceTask.didReceive(response) + sourceTaskReference.value.didReceive(response) } } else { - sourceTask.didReceive(response) + sourceTaskReference.value.didReceive(response) } } if let data { - sourceTask.didReceive(data) + sourceTaskReference.value.didReceive(data) } - sourceTask.didFinish() + sourceTaskReference.value.didFinish() } }) self.urlSessionTask?.resume() diff --git a/submodules/BuildConfigExtra/BUILD b/submodules/BuildConfigExtra/BUILD index fb403a5b73..850eca77fc 100644 --- a/submodules/BuildConfigExtra/BUILD +++ b/submodules/BuildConfigExtra/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), copts = [ "-Werror", ], diff --git a/submodules/ChatListSearchItemHeader/Sources/ChatListSearchItemHeader.swift b/submodules/ChatListSearchItemHeader/Sources/ChatListSearchItemHeader.swift index 463f70fe57..71b378f3b3 100644 --- a/submodules/ChatListSearchItemHeader/Sources/ChatListSearchItemHeader.swift +++ b/submodules/ChatListSearchItemHeader/Sources/ChatListSearchItemHeader.swift @@ -204,6 +204,7 @@ private enum ChatListSearchItemHeaderId: Hashable { public final class ChatListSearchItemHeader: ListViewItemHeader { public let id: ListViewItemNode.HeaderId + public let stackingId: ListViewItemNode.HeaderId? = nil public let type: ChatListSearchItemHeaderType public let stickDirection: ListViewItemHeaderStickDirection = .top public let stickOverInsets: Bool = true @@ -287,7 +288,7 @@ public final class ChatListSearchItemHeaderNode: ListViewItemHeaderNode { } } - override public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) { + override public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { self.validLayout = (size, leftInset, rightInset) self.sectionHeaderNode.frame = CGRect(origin: CGPoint(), size: size) self.sectionHeaderNode.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset) diff --git a/submodules/ContactListUI/Sources/ContactListNameIndexHeader.swift b/submodules/ContactListUI/Sources/ContactListNameIndexHeader.swift index 2d263ec274..9fd3a49dcf 100644 --- a/submodules/ContactListUI/Sources/ContactListNameIndexHeader.swift +++ b/submodules/ContactListUI/Sources/ContactListNameIndexHeader.swift @@ -6,6 +6,7 @@ import ListSectionHeaderNode final class ContactListNameIndexHeader: Equatable, ListViewItemHeader { let id: ListViewItemNode.HeaderId + let stackingId: ListViewItemNode.HeaderId? = nil let theme: PresentationTheme let letter: unichar let stickDirection: ListViewItemHeaderStickDirection = .top @@ -66,7 +67,7 @@ final class ContactListNameIndexHeaderNode: ListViewItemHeaderNode { self.sectionHeaderNode.updateTheme(theme: theme) } - override func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) { + override func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { self.sectionHeaderNode.frame = CGRect(origin: CGPoint(), size: size) self.sectionHeaderNode.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset) } diff --git a/submodules/Crc32/BUILD b/submodules/Crc32/BUILD index caaf3812e4..6d662a3b13 100644 --- a/submodules/Crc32/BUILD +++ b/submodules/Crc32/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty = True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/Display/Source/CAAnimationUtils.swift b/submodules/Display/Source/CAAnimationUtils.swift index 952098bdee..73cc4f6e26 100644 --- a/submodules/Display/Source/CAAnimationUtils.swift +++ b/submodules/Display/Source/CAAnimationUtils.swift @@ -453,6 +453,14 @@ public extension CALayer { self.animate(from: from as NSNumber, to: to as NSNumber, keyPath: "bounds.origin.y", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: duration, mediaTimingFunction: mediaTimingFunction, additive: true) } + func animateBoundsOriginAdditive(from: CGPoint, to: CGPoint, duration: Double, mediaTimingFunction: CAMediaTimingFunction) { + self.animate(from: NSValue(cgPoint: from), to: NSValue(cgPoint: to), keyPath: "bounds.origin", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: duration, mediaTimingFunction: mediaTimingFunction, additive: true) + } + + func animateBoundsOriginAdditive(from: CGPoint, to: CGPoint, duration: Double, timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue, mediaTimingFunction: CAMediaTimingFunction? = nil) { + self.animate(from: NSValue(cgPoint: from), to: NSValue(cgPoint: to), keyPath: "bounds.origin", timingFunction: timingFunction, duration: duration, mediaTimingFunction: mediaTimingFunction, additive: true) + } + func animateShapeLineWidth(from: CGFloat, to: CGFloat, duration: Double, delay: Double = 0.0, timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, additive: Bool = false, completion: ((Bool) -> Void)? = nil) { self.animate(from: NSNumber(value: Float(from)), to: NSNumber(value: Float(to)), keyPath: "lineWidth", timingFunction: timingFunction, duration: duration, delay: delay, mediaTimingFunction: mediaTimingFunction, removeOnCompletion: removeOnCompletion, additive: additive, completion: completion) } diff --git a/submodules/Display/Source/ContainedViewLayoutTransition.swift b/submodules/Display/Source/ContainedViewLayoutTransition.swift index 6b49b01437..e72348ad07 100644 --- a/submodules/Display/Source/ContainedViewLayoutTransition.swift +++ b/submodules/Display/Source/ContainedViewLayoutTransition.swift @@ -651,6 +651,15 @@ public extension ContainedViewLayoutTransition { } } + func animateOffsetAdditive(node: ASDisplayNode, offset: CGPoint) { + switch self { + case .immediate: + break + case let .animated(duration, curve): + node.layer.animateBoundsOriginAdditive(from: offset, to: CGPoint(), duration: duration, timingFunction: curve.timingFunction, mediaTimingFunction: curve.mediaTimingFunction) + } + } + func animateHorizontalOffsetAdditive(node: ASDisplayNode, offset: CGFloat, completion: (() -> Void)? = nil) { switch self { case .immediate: diff --git a/submodules/Display/Source/ListView.swift b/submodules/Display/Source/ListView.swift index 6484cab49b..5cae045448 100644 --- a/submodules/Display/Source/ListView.swift +++ b/submodules/Display/Source/ListView.swift @@ -9,6 +9,11 @@ private let insertionAnimationDuration: Double = 0.4 private struct VisibleHeaderNodeId: Hashable { var id: ListViewItemNode.HeaderId var affinity: Int + + init(id: ListViewItemNode.HeaderId, affinity: Int) { + self.id = id + self.affinity = affinity + } } private final class ListViewBackingLayer: CALayer { @@ -1740,18 +1745,30 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } } - private func nodeForItem(synchronous: Bool, synchronousLoads: Bool, item: ListViewItem, previousNode: QueueLocalObject?, index: Int, previousItem: ListViewItem?, nextItem: ListViewItem?, params: ListViewItemLayoutParams, updateAnimationIsAnimated: Bool, updateAnimationIsCrossfade: Bool, completion: @escaping (QueueLocalObject, ListViewItemNodeLayout, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + private func nodeForItem(synchronous: Bool, synchronousLoads: Bool, item: ListViewItem, previousNode: QueueLocalObject?, index: Int, previousItem: ListViewItem?, nextItem: ListViewItem?, params: ListViewItemLayoutParams, updateAnimationIsAnimated: Bool, updateAnimationIsCrossfade: Bool, customAnimationTransition: ControlledTransition?, completion: @escaping (QueueLocalObject, ListViewItemNodeLayout, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { if let previousNode = previousNode { var controlledTransition: ControlledTransition? let updateAnimation: ListViewItemUpdateAnimation - if updateAnimationIsCrossfade { - updateAnimation = .Crossfade - } else if updateAnimationIsAnimated { - let transition = ControlledTransition(duration: insertionAnimationDuration * UIView.animationDurationFactor(), curve: .spring, interactive: true) - controlledTransition = transition - updateAnimation = .System(duration: insertionAnimationDuration * UIView.animationDurationFactor(), transition: transition) + if let customAnimationTransition { + controlledTransition = customAnimationTransition + var duration: Double = insertionAnimationDuration + switch customAnimationTransition.legacyAnimator.transition { + case .immediate: + duration = 0.0 + case let .animated(durationValue, _): + duration = durationValue + } + updateAnimation = .System(duration: duration * UIView.animationDurationFactor(), transition: customAnimationTransition) } else { - updateAnimation = .None + if updateAnimationIsCrossfade { + updateAnimation = .Crossfade + } else if updateAnimationIsAnimated { + let transition = ControlledTransition(duration: insertionAnimationDuration * UIView.animationDurationFactor(), curve: .spring, interactive: true) + controlledTransition = transition + updateAnimation = .System(duration: insertionAnimationDuration * UIView.animationDurationFactor(), transition: transition) + } else { + updateAnimation = .None + } } if let controlledTransition = controlledTransition { @@ -1846,7 +1863,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel self.transactionQueue.addTransaction({ [weak self] transactionCompletion in if let strongSelf = self { strongSelf.transactionOffset = 0.0 - strongSelf.deleteAndInsertItemsTransaction(deleteIndices: deleteIndices, insertIndicesAndItems: insertIndicesAndItems, updateIndicesAndItems: updateIndicesAndItems, options: options, scrollToItem: scrollToItem, additionalScrollDistance: additionalScrollDistance, updateSizeAndInsets: updateSizeAndInsets, stationaryItemRange: stationaryItemRange, updateOpaqueState: updateOpaqueState, completion: { [weak strongSelf] in + strongSelf.deleteAndInsertItemsTransaction(deleteIndices: deleteIndices, insertIndicesAndItems: insertIndicesAndItems, updateIndicesAndItems: updateIndicesAndItems, options: options, scrollToItem: scrollToItem, additionalScrollDistance: additionalScrollDistance, updateSizeAndInsets: updateSizeAndInsets, stationaryItemRange: stationaryItemRange, updateOpaqueState: updateOpaqueState, customAnimationTransition: updateSizeAndInsets?.customAnimationTransition, completion: { [weak strongSelf] in completion(strongSelf?.immediateDisplayedItemRange() ?? ListViewDisplayedItemRange(loadedRange: nil, visibleRange: nil)) transactionCompletion() @@ -1855,7 +1872,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel }) } - private func deleteAndInsertItemsTransaction(deleteIndices: [ListViewDeleteItem], insertIndicesAndItems: [ListViewInsertItem], updateIndicesAndItems: [ListViewUpdateItem], options: ListViewDeleteAndInsertOptions, scrollToItem: ListViewScrollToItem?, additionalScrollDistance: CGFloat, updateSizeAndInsets: ListViewUpdateSizeAndInsets?, stationaryItemRange: (Int, Int)?, updateOpaqueState: Any?, completion: @escaping () -> Void) { + private func deleteAndInsertItemsTransaction(deleteIndices: [ListViewDeleteItem], insertIndicesAndItems: [ListViewInsertItem], updateIndicesAndItems: [ListViewUpdateItem], options: ListViewDeleteAndInsertOptions, scrollToItem: ListViewScrollToItem?, additionalScrollDistance: CGFloat, updateSizeAndInsets: ListViewUpdateSizeAndInsets?, stationaryItemRange: (Int, Int)?, updateOpaqueState: Any?, customAnimationTransition: ControlledTransition?, completion: @escaping () -> Void) { if deleteIndices.isEmpty && insertIndicesAndItems.isEmpty && updateIndicesAndItems.isEmpty && scrollToItem == nil { if let updateSizeAndInsets = updateSizeAndInsets, (self.items.count == 0 || (updateSizeAndInsets.size == self.visibleSize && updateSizeAndInsets.insets == self.insets && !options.contains(.ForceUpdate))) { self.visibleSize = updateSizeAndInsets.size @@ -2096,7 +2113,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel print("deleteAndInsertItemsTransaction prepare \((CACurrentMediaTime() - startTime) * 1000.0) ms") } - self.fillMissingNodes(synchronous: options.contains(.Synchronous), synchronousLoads: options.contains(.PreferSynchronousResourceLoading), animated: animated, inputAnimatedInsertIndices: animated ? insertedIndexSet : Set(), insertDirectionHints: insertDirectionHints, inputState: state, inputPreviousNodes: previousNodes, inputOperations: operations, inputCompletion: { updatedState, operations in + self.fillMissingNodes(synchronous: options.contains(.Synchronous), synchronousLoads: options.contains(.PreferSynchronousResourceLoading), animated: animated, customAnimationTransition: updateSizeAndInsets?.customAnimationTransition, inputAnimatedInsertIndices: animated ? insertedIndexSet : Set(), insertDirectionHints: insertDirectionHints, inputState: state, inputPreviousNodes: previousNodes, inputOperations: operations, inputCompletion: { updatedState, operations in if self.debugInfo { print("fillMissingNodes completion \((CACurrentMediaTime() - startTime) * 1000.0) ms") @@ -2119,8 +2136,8 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel updateIndices.subtract(explicitelyUpdateIndices) - self.updateNodes(synchronous: options.contains(.Synchronous), synchronousLoads: options.contains(.PreferSynchronousResourceLoading), crossfade: options.contains(.AnimateCrossfade), animated: animated, updateIndicesAndItems: updateIndicesAndItems, inputState: updatedState, previousNodes: previousNodes, inputOperations: operations, completion: { updatedState, operations in - self.updateAdjacent(synchronous: options.contains(.Synchronous), animated: animated, state: updatedState, updateAdjacentItemsIndices: updateIndices, operations: operations, completion: { state, operations in + self.updateNodes(synchronous: options.contains(.Synchronous), synchronousLoads: options.contains(.PreferSynchronousResourceLoading), crossfade: options.contains(.AnimateCrossfade), customAnimationTransition: customAnimationTransition, animated: animated, updateIndicesAndItems: updateIndicesAndItems, inputState: updatedState, previousNodes: previousNodes, inputOperations: operations, completion: { updatedState, operations in + self.updateAdjacent(synchronous: options.contains(.Synchronous), animated: animated, customAnimationTransition: customAnimationTransition, state: updatedState, updateAdjacentItemsIndices: updateIndices, operations: operations, completion: { state, operations in var updatedState = state var updatedOperations = operations updatedState.removeInvisibleNodes(&updatedOperations) @@ -2154,7 +2171,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel let beginReplay = { [weak self] in if let strongSelf = self { - strongSelf.replayOperations(animated: animated, animateAlpha: options.contains(.AnimateAlpha), animateCrossfade: options.contains(.AnimateCrossfade), animateFullTransition: options.contains(.AnimateFullTransition), synchronous: options.contains(.Synchronous), synchronousLoads: options.contains(.PreferSynchronousResourceLoading), animateTopItemVerticalOrigin: options.contains(.AnimateTopItemPosition), operations: updatedOperations, requestItemInsertionAnimationsIndices: options.contains(.RequestItemInsertionAnimations) ? insertedIndexSet : Set(), scrollToItem: scrollToItem, additionalScrollDistance: additionalScrollDistance, updateSizeAndInsets: updateSizeAndInsets, stationaryItemIndex: stationaryItemIndex, updateOpaqueState: updateOpaqueState, forceInvertOffsetDirection: options.contains(.InvertOffsetDirection), completion: { + strongSelf.replayOperations(animated: animated, animateAlpha: options.contains(.AnimateAlpha), animateCrossfade: options.contains(.AnimateCrossfade), animateFullTransition: options.contains(.AnimateFullTransition), customAnimationTransition: updateSizeAndInsets?.customAnimationTransition, synchronous: options.contains(.Synchronous), synchronousLoads: options.contains(.PreferSynchronousResourceLoading), animateTopItemVerticalOrigin: options.contains(.AnimateTopItemPosition), operations: updatedOperations, requestItemInsertionAnimationsIndices: options.contains(.RequestItemInsertionAnimations) ? insertedIndexSet : Set(), scrollToItem: scrollToItem, additionalScrollDistance: additionalScrollDistance, updateSizeAndInsets: updateSizeAndInsets, stationaryItemIndex: stationaryItemIndex, updateOpaqueState: updateOpaqueState, forceInvertOffsetDirection: options.contains(.InvertOffsetDirection), completion: { if options.contains(.PreferSynchronousDrawing) { self?.recursivelyEnsureDisplaySynchronously(true) } @@ -2199,7 +2216,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } } - private func updateAdjacent(synchronous: Bool, animated: Bool, state: ListViewState, updateAdjacentItemsIndices: Set, operations: [ListViewStateOperation], completion: @escaping (ListViewState, [ListViewStateOperation]) -> Void) { + private func updateAdjacent(synchronous: Bool, animated: Bool, customAnimationTransition: ControlledTransition?, state: ListViewState, updateAdjacentItemsIndices: Set, operations: [ListViewStateOperation], completion: @escaping (ListViewState, [ListViewStateOperation]) -> Void) { if updateAdjacentItemsIndices.isEmpty { completion(state, operations) } else { @@ -2217,12 +2234,24 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel continueWithoutNode = false var controlledTransition: ControlledTransition? let updateAnimation: ListViewItemUpdateAnimation - if animated { - let transition = ControlledTransition(duration: insertionAnimationDuration * UIView.animationDurationFactor(), curve: .spring, interactive: true) - controlledTransition = transition - updateAnimation = .System(duration: insertionAnimationDuration * UIView.animationDurationFactor(), transition: transition) + if let customAnimationTransition { + controlledTransition = customAnimationTransition + var duration: Double = insertionAnimationDuration + switch customAnimationTransition.legacyAnimator.transition { + case .immediate: + duration = 0.0 + case let .animated(durationValue, _): + duration = durationValue + } + updateAnimation = .System(duration: duration * UIView.animationDurationFactor(), transition: customAnimationTransition) } else { - updateAnimation = .None + if animated { + let transition = ControlledTransition(duration: insertionAnimationDuration * UIView.animationDurationFactor(), curve: .spring, interactive: true) + controlledTransition = transition + updateAnimation = .System(duration: insertionAnimationDuration * UIView.animationDurationFactor(), transition: transition) + } else { + updateAnimation = .None + } } if let controlledTransition = controlledTransition { @@ -2264,7 +2293,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } } - self.updateAdjacent(synchronous: synchronous, animated: animated, state: updatedState, updateAdjacentItemsIndices: updatedUpdateAdjacentItemsIndices, operations: updatedOperations, completion: completion) + self.updateAdjacent(synchronous: synchronous, animated: animated, customAnimationTransition: customAnimationTransition, state: updatedState, updateAdjacentItemsIndices: updatedUpdateAdjacentItemsIndices, operations: updatedOperations, completion: completion) }) } break @@ -2273,12 +2302,12 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } if continueWithoutNode { - updateAdjacent(synchronous: synchronous, animated: animated, state: state, updateAdjacentItemsIndices: updatedUpdateAdjacentItemsIndices, operations: operations, completion: completion) + updateAdjacent(synchronous: synchronous, animated: animated, customAnimationTransition: customAnimationTransition, state: state, updateAdjacentItemsIndices: updatedUpdateAdjacentItemsIndices, operations: operations, completion: completion) } } } - private func fillMissingNodes(synchronous: Bool, synchronousLoads: Bool, animated: Bool, inputAnimatedInsertIndices: Set, insertDirectionHints: [Int: ListViewItemOperationDirectionHint], inputState: ListViewState, inputPreviousNodes: [Int: QueueLocalObject], inputOperations: [ListViewStateOperation], inputCompletion: @escaping (ListViewState, [ListViewStateOperation]) -> Void) { + private func fillMissingNodes(synchronous: Bool, synchronousLoads: Bool, animated: Bool, customAnimationTransition: ControlledTransition?, inputAnimatedInsertIndices: Set, insertDirectionHints: [Int: ListViewItemOperationDirectionHint], inputState: ListViewState, inputPreviousNodes: [Int: QueueLocalObject], inputOperations: [ListViewStateOperation], inputCompletion: @escaping (ListViewState, [ListViewStateOperation]) -> Void) { let animatedInsertIndices = inputAnimatedInsertIndices var state = inputState let previousNodes = inputPreviousNodes @@ -2312,7 +2341,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel let index = insertionItemIndexAndDirection.0 let threadId = pthread_self() var tailRecurse = false - self.nodeForItem(synchronous: synchronous, synchronousLoads: synchronousLoads, item: self.items[index], previousNode: previousNodes[index], index: index, previousItem: index == 0 ? nil : self.items[index - 1], nextItem: self.items.count == index + 1 ? nil : self.items[index + 1], params: ListViewItemLayoutParams(width: state.visibleSize.width, leftInset: state.insets.left, rightInset: state.insets.right, availableHeight: state.visibleSize.height - state.insets.top - state.insets.bottom), updateAnimationIsAnimated: animated, updateAnimationIsCrossfade: false, completion: { (node, layout, apply) in + self.nodeForItem(synchronous: synchronous, synchronousLoads: synchronousLoads, item: self.items[index], previousNode: previousNodes[index], index: index, previousItem: index == 0 ? nil : self.items[index - 1], nextItem: self.items.count == index + 1 ? nil : self.items[index + 1], params: ListViewItemLayoutParams(width: state.visibleSize.width, leftInset: state.insets.left, rightInset: state.insets.right, availableHeight: state.visibleSize.height - state.insets.top - state.insets.bottom), updateAnimationIsAnimated: animated, updateAnimationIsCrossfade: false, customAnimationTransition: customAnimationTransition, completion: { (node, layout, apply) in if pthread_equal(pthread_self(), threadId) != 0 && !tailRecurse { tailRecurse = true state.insertNode(index, node: node, layout: layout, apply: apply, offsetDirection: insertionItemIndexAndDirection.1, animated: animated && animatedInsertIndices.contains(index), operations: &operations, itemCount: self.items.count) @@ -2320,7 +2349,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel var updatedState = state var updatedOperations = operations updatedState.insertNode(index, node: node, layout: layout, apply: apply, offsetDirection: insertionItemIndexAndDirection.1, animated: animated && animatedInsertIndices.contains(index), operations: &updatedOperations, itemCount: self.items.count) - self.fillMissingNodes(synchronous: synchronous, synchronousLoads: synchronousLoads, animated: animated, inputAnimatedInsertIndices: animatedInsertIndices, insertDirectionHints: insertDirectionHints, inputState: updatedState, inputPreviousNodes: previousNodes, inputOperations: updatedOperations, inputCompletion: completion) + self.fillMissingNodes(synchronous: synchronous, synchronousLoads: synchronousLoads, animated: animated, customAnimationTransition: customAnimationTransition, inputAnimatedInsertIndices: animatedInsertIndices, insertDirectionHints: insertDirectionHints, inputState: updatedState, inputPreviousNodes: previousNodes, inputOperations: updatedOperations, inputCompletion: completion) } }) if !tailRecurse { @@ -2335,7 +2364,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } } - private func updateNodes(synchronous: Bool, synchronousLoads: Bool, crossfade: Bool, animated: Bool, updateIndicesAndItems: [ListViewUpdateItem], inputState: ListViewState, previousNodes: [Int: QueueLocalObject], inputOperations: [ListViewStateOperation], completion: @escaping (ListViewState, [ListViewStateOperation]) -> Void) { + private func updateNodes(synchronous: Bool, synchronousLoads: Bool, crossfade: Bool, customAnimationTransition: ControlledTransition?, animated: Bool, updateIndicesAndItems: [ListViewUpdateItem], inputState: ListViewState, previousNodes: [Int: QueueLocalObject], inputOperations: [ListViewStateOperation], completion: @escaping (ListViewState, [ListViewStateOperation]) -> Void) { var state = inputState var operations = inputOperations var updateIndicesAndItems = updateIndicesAndItems @@ -2347,11 +2376,11 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } else { let updateItem = updateIndicesAndItems[0] if let previousNode = previousNodes[updateItem.index] { - self.nodeForItem(synchronous: synchronous, synchronousLoads: synchronousLoads, item: updateItem.item, previousNode: previousNode, index: updateItem.index, previousItem: updateItem.index == 0 ? nil : self.items[updateItem.index - 1], nextItem: updateItem.index == (self.items.count - 1) ? nil : self.items[updateItem.index + 1], params: ListViewItemLayoutParams(width: state.visibleSize.width, leftInset: state.insets.left, rightInset: state.insets.right, availableHeight: state.visibleSize.height - state.insets.top - state.insets.bottom), updateAnimationIsAnimated: animated, updateAnimationIsCrossfade: crossfade, completion: { _, layout, apply in + self.nodeForItem(synchronous: synchronous, synchronousLoads: synchronousLoads, item: updateItem.item, previousNode: previousNode, index: updateItem.index, previousItem: updateItem.index == 0 ? nil : self.items[updateItem.index - 1], nextItem: updateItem.index == (self.items.count - 1) ? nil : self.items[updateItem.index + 1], params: ListViewItemLayoutParams(width: state.visibleSize.width, leftInset: state.insets.left, rightInset: state.insets.right, availableHeight: state.visibleSize.height - state.insets.top - state.insets.bottom), updateAnimationIsAnimated: animated, updateAnimationIsCrossfade: crossfade, customAnimationTransition: customAnimationTransition, completion: { _, layout, apply in state.updateNodeAtItemIndex(updateItem.index, layout: layout, direction: updateItem.directionHint, isAnimated: animated, apply: apply, operations: &operations) updateIndicesAndItems.remove(at: 0) - self.updateNodes(synchronous: synchronous, synchronousLoads: synchronousLoads, crossfade: crossfade, animated: animated, updateIndicesAndItems: updateIndicesAndItems, inputState: state, previousNodes: previousNodes, inputOperations: operations, completion: completion) + self.updateNodes(synchronous: synchronous, synchronousLoads: synchronousLoads, crossfade: crossfade, customAnimationTransition: customAnimationTransition, animated: animated, updateIndicesAndItems: updateIndicesAndItems, inputState: state, previousNodes: previousNodes, inputOperations: operations, completion: completion) }) break } else { @@ -2621,7 +2650,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } } - private func replayOperations(animated: Bool, animateAlpha: Bool, animateCrossfade: Bool, animateFullTransition: Bool, synchronous: Bool, synchronousLoads: Bool, animateTopItemVerticalOrigin: Bool, operations: [ListViewStateOperation], requestItemInsertionAnimationsIndices: Set, scrollToItem originalScrollToItem: ListViewScrollToItem?, additionalScrollDistance: CGFloat, updateSizeAndInsets: ListViewUpdateSizeAndInsets?, stationaryItemIndex: Int?, updateOpaqueState: Any?, forceInvertOffsetDirection: Bool = false, completion: () -> Void) { + private func replayOperations(animated: Bool, animateAlpha: Bool, animateCrossfade: Bool, animateFullTransition: Bool, customAnimationTransition: ControlledTransition?, synchronous: Bool, synchronousLoads: Bool, animateTopItemVerticalOrigin: Bool, operations: [ListViewStateOperation], requestItemInsertionAnimationsIndices: Set, scrollToItem originalScrollToItem: ListViewScrollToItem?, additionalScrollDistance: CGFloat, updateSizeAndInsets: ListViewUpdateSizeAndInsets?, stationaryItemIndex: Int?, updateOpaqueState: Any?, forceInvertOffsetDirection: Bool = false, completion: () -> Void) { var scrollToItem: ListViewScrollToItem? var isExperimentalSnapToScrollToItem = false if let originalScrollToItem = originalScrollToItem { @@ -2896,7 +2925,24 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel var offsetRanges = OffsetRanges() - if animated { + if let customAnimationTransition { + node.apparentHeight = updatedApparentHeight + + let apparentHeightDelta = updatedApparentHeight - previousApparentHeight + if apparentHeightDelta != 0.0 { + var apparentFrame = node.apparentFrame + apparentFrame.origin.y += offsetRanges.offsetForIndex(index) + if apparentFrame.maxY < self.insets.top { + offsetRanges.offset(IndexRange(first: 0, last: index), offset: -apparentHeightDelta) + } else { + offsetRanges.offset(IndexRange(first: index + 1, last: Int.max), offset: apparentHeightDelta) + } + } + + if previousApparentHeight != updatedApparentHeight { + customAnimationTransition.legacyAnimator.transition.animateOffsetAdditive(node: node, offset: previousApparentHeight - updatedApparentHeight) + } + } else if animated { if updatedInsets != previousInsets { node.insets = previousInsets node.addInsetsAnimationToValue(updatedInsets, duration: insertionAnimationDuration * UIView.animationDurationFactor(), beginAt: timestamp) @@ -2966,7 +3012,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel if offset != 0.0 { var frame = itemNode.frame frame.origin.y += offset - itemNode.updateFrame(frame, within: self.visibleSize) + itemNode.updateFrame(frame, within: self.visibleSize, transition: customAnimationTransition) } index += 1 @@ -3129,7 +3175,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel self.visibleSize = updateSizeAndInsets.size for itemNode in self.itemNodes { - itemNode.updateFrame(itemNode.frame.offsetBy(dx: 0.0, dy: offsetFix), within: self.visibleSize) + itemNode.updateFrame(itemNode.frame.offsetBy(dx: 0.0, dy: offsetFix), within: self.visibleSize, transition: customAnimationTransition) } let (snappedTopInset, snapToBoundsOffset) = self.snapToBounds(snapTopItem: scrollToItem != nil && scrollToItem?.directionHint != .Down, stackFromBottom: self.stackFromBottom, updateSizeAndInsets: updateSizeAndInsets, isExperimentalSnapToScrollToItem: isExperimentalSnapToScrollToItem, insetDeltaOffsetFix: insetDeltaOffsetFix) @@ -3830,23 +3876,84 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel func addHeader(id: VisibleHeaderNodeId, upperBound: CGFloat, upperIndex: Int, upperBoundEdge: CGFloat, lowerBound: CGFloat, lowerIndex: Int, item: ListViewItemHeader, hasValidNodes: Bool) { let itemHeaderHeight: CGFloat = item.height - let headerFrame: CGRect - let stickLocationDistanceFactor: CGFloat - let stickLocationDistance: CGFloat + var insertItemBelowOtherHeaders = false + var offsetByHeaderNodeId: ListViewItemNode.HeaderId? + var didOffsetByHeaderNode = false + + var headerFrame: CGRect + let naturalY: CGFloat + var stickLocationDistanceFactor: CGFloat = 0.0 + var stickLocationDistance: CGFloat switch item.stickDirection { case .top: + naturalY = lowerBound headerFrame = CGRect(origin: CGPoint(x: 0.0, y: min(max(upperDisplayBound, upperBound), lowerBound - itemHeaderHeight)), size: CGSize(width: self.visibleSize.width, height: itemHeaderHeight)) stickLocationDistance = headerFrame.minY - upperBound stickLocationDistanceFactor = max(0.0, min(1.0, stickLocationDistance / itemHeaderHeight)) case .topEdge: + naturalY = lowerBound headerFrame = CGRect(origin: CGPoint(x: 0.0, y: min(max(upperDisplayBound, upperBoundEdge - itemHeaderHeight), lowerBound - itemHeaderHeight)), size: CGSize(width: self.visibleSize.width, height: itemHeaderHeight)) stickLocationDistance = headerFrame.minY - upperBoundEdge + itemHeaderHeight stickLocationDistanceFactor = max(0.0, min(1.0, stickLocationDistance / itemHeaderHeight)) case .bottom: + naturalY = lowerBound headerFrame = CGRect(origin: CGPoint(x: 0.0, y: max(upperBound, min(lowerBound, lowerDisplayBound) - itemHeaderHeight)), size: CGSize(width: self.visibleSize.width, height: itemHeaderHeight)) stickLocationDistance = lowerBound - headerFrame.maxY stickLocationDistanceFactor = max(0.0, min(1.0, stickLocationDistance / itemHeaderHeight)) + + if let stackingId = item.stackingId { + insertItemBelowOtherHeaders = true + + var naturalOverlapLowerBound: CGFloat = naturalY + do { + for (otherId, otherNode) in self.itemHeaderNodes { + if otherId.id.space == stackingId.space { + if !visibleHeaderNodes.contains(otherId) { + continue + } + if let otherNaturalOriginY = otherNode.naturalOriginY, otherNaturalOriginY == naturalY { + naturalOverlapLowerBound = otherNaturalOriginY - 7.0 - 20.0 + break + } + } + } + } + + for _ in 0 ..< 2 { + var mostOverlap: (CGRect, CGFloat, ListViewItemHeaderNode)? + for (otherId, otherNode) in self.itemHeaderNodes { + if otherId.id.space == stackingId.space { + if !visibleHeaderNodes.contains(otherId) { + continue + } + if headerFrame.intersects(otherNode.frame) { + let intersectionHeight = headerFrame.intersection(otherNode.frame).height + if intersectionHeight > 0.0 { + if let (currentOverlapFrame, _, _) = mostOverlap { + if headerFrame.minY < currentOverlapFrame.minY { + mostOverlap = (otherNode.frame, intersectionHeight, otherNode) + } + } else { + mostOverlap = (otherNode.frame, intersectionHeight, otherNode) + } + } + } + } + } + if let (mostOverlap, _, otherNode) = mostOverlap { + let originalY = headerFrame.origin.y + headerFrame.origin.y = min(headerFrame.origin.y, mostOverlap.minY - 7.0 - 20.0) + headerFrame.origin.y = max(upperBound, headerFrame.origin.y) + offsetByHeaderNodeId = otherNode.item?.id + didOffsetByHeaderNode = originalY != headerFrame.origin.y + } + } + + stickLocationDistance = naturalOverlapLowerBound - headerFrame.maxY + stickLocationDistanceFactor = max(0.0, min(1.0, stickLocationDistance / itemHeaderHeight)) + } } + visibleHeaderNodes.append(id) let initialHeaderNodeAlpha = self.itemHeaderNodesAlpha @@ -3855,26 +3962,36 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel headerNode = current switch transition.0 { case .immediate: + let previousFrame = headerNode.frame headerNode.updateFrame(headerFrame, within: self.visibleSize) + if headerNode.offsetByHeaderNodeId != nil && offsetByHeaderNodeId != nil && headerNode.offsetByHeaderNodeId != offsetByHeaderNodeId { + let _ = didOffsetByHeaderNode + if !previousFrame.isEmpty { + ContainedViewLayoutTransition.animated(duration: 0.35, curve: .spring).animatePositionAdditive(node: headerNode, offset: CGPoint(x: 0.0, y: previousFrame.minY - headerFrame.minY)) + } + } case let .animated(duration, curve): let previousFrame = headerNode.frame headerNode.updateFrame(headerFrame, within: self.visibleSize) - var offset = headerFrame.minY - previousFrame.minY + transition.2 + var offsetY = headerFrame.minY - previousFrame.minY + transition.2 + var offsetX: CGFloat = 0.0 if headerNode.isRotated { - offset = -offset + offsetY = -offsetY + offsetX = headerFrame.width - previousFrame.width } + let offset = CGPoint(x: offsetX, y: offsetY) switch curve { case .linear: - headerNode.layer.animateBoundsOriginYAdditive(from: offset, to: 0.0, duration: duration, mediaTimingFunction: CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)) + headerNode.layer.animateBoundsOriginAdditive(from: offset, to: CGPoint(), duration: duration, mediaTimingFunction: CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)) case .spring, .customSpring: transition.0.animateOffsetAdditive(node: headerNode, offset: offset) case let .custom(p1, p2, p3, p4): - headerNode.layer.animateBoundsOriginYAdditive(from: offset, to: 0.0, duration: duration, mediaTimingFunction: CAMediaTimingFunction(controlPoints: p1, p2, p3, p4)) + headerNode.layer.animateBoundsOriginAdditive(from: offset, to: CGPoint(), duration: duration, mediaTimingFunction: CAMediaTimingFunction(controlPoints: p1, p2, p3, p4)) case .easeInOut: if transition.1 { - headerNode.layer.animateBoundsOriginYAdditive(from: offset, to: 0.0, duration: duration, mediaTimingFunction: ContainedViewLayoutTransitionCurve.slide.mediaTimingFunction) + headerNode.layer.animateBoundsOriginAdditive(from: offset, to: CGPoint(), duration: duration, mediaTimingFunction: ContainedViewLayoutTransitionCurve.slide.mediaTimingFunction) } else { - headerNode.layer.animateBoundsOriginYAdditive(from: offset, to: 0.0, duration: duration, mediaTimingFunction: CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)) + headerNode.layer.animateBoundsOriginAdditive(from: offset, to: CGPoint(), duration: duration, mediaTimingFunction: CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)) } } } @@ -3883,7 +4000,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel item.updateNode(headerNode, previous: nil, next: nil) headerNode.item = item } - headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset) + headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset, transition: animateInsertion ? .immediate : transition.0) headerNode.updateInternalStickLocationDistanceFactor(stickLocationDistanceFactor, animated: true) headerNode.internalStickLocationDistance = stickLocationDistance if !hasValidNodes && !headerNode.alpha.isZero { @@ -3896,7 +4013,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel headerNode.animateAdded(duration: 0.2) } } - headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, transition: transition.0) + headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, distance: stickLocationDistance, transition: transition.0) } else { headerNode = item.node(synchronousLoad: synchronousLoad) headerNode.alpha = initialHeaderNodeAlpha @@ -3906,10 +4023,28 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel } headerNode.updateFlashingOnScrolling(flashing, animated: false) headerNode.frame = headerFrame - headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset) + headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset, transition: animateInsertion ? .immediate : transition.0) headerNode.updateInternalStickLocationDistanceFactor(stickLocationDistanceFactor, animated: false) self.itemHeaderNodes[id] = headerNode - if let verticalScrollIndicator = self.verticalScrollIndicator { + if insertItemBelowOtherHeaders { + var lowestHeaderNode: ASDisplayNode? + var lowestHeaderNodeIndex: Int? + for (_, headerNode) in self.itemHeaderNodes { + if let index = self.view.subviews.firstIndex(of: headerNode.view) { + if lowestHeaderNodeIndex == nil || index < lowestHeaderNodeIndex! { + lowestHeaderNodeIndex = index + lowestHeaderNode = headerNode + } + } + } + if let lowestHeaderNode { + self.insertSubnode(headerNode, belowSubnode: lowestHeaderNode) + } else if let verticalScrollIndicator = self.verticalScrollIndicator { + self.insertSubnode(headerNode, belowSubnode: verticalScrollIndicator) + } else { + self.addSubnode(headerNode) + } + } else if let verticalScrollIndicator = self.verticalScrollIndicator { self.insertSubnode(headerNode, belowSubnode: verticalScrollIndicator) } else { self.addSubnode(headerNode) @@ -3918,8 +4053,10 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel headerNode.alpha = initialHeaderNodeAlpha headerNode.animateAdded(duration: 0.2) } - headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, transition: .immediate) + headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, distance: stickLocationDistance, transition: .immediate) } + headerNode.offsetByHeaderNodeId = offsetByHeaderNodeId + headerNode.naturalOriginY = naturalY var maxIntersectionHeight: (CGFloat, Int)? for i in upperIndex ... lowerIndex { let itemNode = self.itemNodes[i] @@ -3964,53 +4101,65 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel var previousHeaderBySpace: [AnyHashable: (id: VisibleHeaderNodeId, upperBound: CGFloat, upperBoundIndex: Int, upperBoundEdge: CGFloat, lowerBound: CGFloat, lowerBoundIndex: Int, item: ListViewItemHeader, hasValidNodes: Bool)] = [:] - for i in 0 ..< self.itemNodes.count { - let itemNode = self.itemNodes[i] - let itemFrame = itemNode.apparentFrame - let itemTopInset = itemNode.insets.top - var validItemHeaderSpaces: [AnyHashable] = [] - if let itemHeaders = itemNode.headers() { - for itemHeader in itemHeaders { - guard let affinity = itemNode.headerSpaceAffinities[itemHeader.id] else { - assertionFailure() - continue - } - - let headerId = VisibleHeaderNodeId(id: itemHeader.id, affinity: affinity) - - validItemHeaderSpaces.append(itemHeader.id.space) - - let itemMaxY: CGFloat - if itemHeader.stickOverInsets { - itemMaxY = itemFrame.maxY - } else { - itemMaxY = itemFrame.maxY - (self.rotated ? itemNode.insets.top : itemNode.insets.bottom) - } - - if let (previousHeaderId, previousUpperBound, previousUpperIndex, previousUpperBoundEdge, previousLowerBound, previousLowerIndex, previousHeaderItem, hasValidNodes) = previousHeaderBySpace[itemHeader.id.space] { - if previousHeaderId == headerId { - previousHeaderBySpace[itemHeader.id.space] = (previousHeaderId, previousUpperBound, previousUpperIndex, previousUpperBoundEdge, itemMaxY, i, previousHeaderItem, hasValidNodes || itemNode.index != nil) + for phase in 0 ..< 2 { + for i in 0 ..< self.itemNodes.count { + let itemNode = self.itemNodes[i] + let itemFrame = itemNode.apparentFrame + let itemTopInset = itemNode.insets.top + var validItemHeaderSpaces: [AnyHashable] = [] + if let itemHeaders = itemNode.headers() { + outerItemHeaders: for itemHeader in itemHeaders { + if phase == 0 { + if itemHeader.stackingId != nil { + continue outerItemHeaders + } + } else { + if itemHeader.stackingId == nil { + continue outerItemHeaders + } + } + + guard let affinity = itemNode.headerSpaceAffinities[itemHeader.id] else { + assertionFailure() + continue + } + + let headerId = VisibleHeaderNodeId(id: itemHeader.id, affinity: affinity) + + validItemHeaderSpaces.append(itemHeader.id.space) + + var itemMaxY: CGFloat + if itemHeader.stickOverInsets { + itemMaxY = itemFrame.maxY + } else { + itemMaxY = itemFrame.maxY - (self.rotated ? itemNode.insets.top : itemNode.insets.bottom) + } + + if let (previousHeaderId, previousUpperBound, previousUpperIndex, previousUpperBoundEdge, previousLowerBound, previousLowerIndex, previousHeaderItem, hasValidNodes) = previousHeaderBySpace[itemHeader.id.space] { + if previousHeaderId == headerId { + previousHeaderBySpace[itemHeader.id.space] = (previousHeaderId, previousUpperBound, previousUpperIndex, previousUpperBoundEdge, itemMaxY, i, previousHeaderItem, hasValidNodes || itemNode.index != nil) + } else { + addHeader(id: previousHeaderId, upperBound: previousUpperBound, upperIndex: previousUpperIndex, upperBoundEdge: previousUpperBoundEdge, lowerBound: previousLowerBound, lowerIndex: previousLowerIndex, item: previousHeaderItem, hasValidNodes: hasValidNodes) + + previousHeaderBySpace[itemHeader.id.space] = (headerId, itemFrame.minY, i, itemFrame.minY + itemTopInset, itemMaxY, i, itemHeader, itemNode.index != nil) + } } else { - addHeader(id: previousHeaderId, upperBound: previousUpperBound, upperIndex: previousUpperIndex, upperBoundEdge: previousUpperBoundEdge, lowerBound: previousLowerBound, lowerIndex: previousLowerIndex, item: previousHeaderItem, hasValidNodes: hasValidNodes) - previousHeaderBySpace[itemHeader.id.space] = (headerId, itemFrame.minY, i, itemFrame.minY + itemTopInset, itemMaxY, i, itemHeader, itemNode.index != nil) } - } else { - previousHeaderBySpace[itemHeader.id.space] = (headerId, itemFrame.minY, i, itemFrame.minY + itemTopInset, itemMaxY, i, itemHeader, itemNode.index != nil) } } - } - - for (space, previousHeader) in previousHeaderBySpace { - if validItemHeaderSpaces.contains(space) { - continue + + for (space, previousHeader) in previousHeaderBySpace { + if validItemHeaderSpaces.contains(space) { + continue + } + + let (previousHeaderId, previousUpperBound, previousUpperIndex, previousUpperBoundEdge, previousLowerBound, previousLowerIndex, previousHeaderItem, hasValidNodes) = previousHeader + + addHeader(id: previousHeaderId, upperBound: previousUpperBound, upperIndex: previousUpperIndex, upperBoundEdge: previousUpperBoundEdge, lowerBound: previousLowerBound, lowerIndex: previousLowerIndex, item: previousHeaderItem, hasValidNodes: hasValidNodes) + + previousHeaderBySpace.removeValue(forKey: space) } - - let (previousHeaderId, previousUpperBound, previousUpperIndex, previousUpperBoundEdge, previousLowerBound, previousLowerIndex, previousHeaderItem, hasValidNodes) = previousHeader - - addHeader(id: previousHeaderId, upperBound: previousUpperBound, upperIndex: previousUpperIndex, upperBoundEdge: previousUpperBoundEdge, lowerBound: previousLowerBound, lowerIndex: previousLowerIndex, item: previousHeaderItem, hasValidNodes: hasValidNodes) - - previousHeaderBySpace.removeValue(forKey: space) } } @@ -4368,15 +4517,15 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel let state = self.currentState() let begin: () -> Void = { - self.fillMissingNodes(synchronous: synchronous, synchronousLoads: false, animated: false, inputAnimatedInsertIndices: [], insertDirectionHints: [:], inputState: state, inputPreviousNodes: [:], inputOperations: []) { state, operations in + self.fillMissingNodes(synchronous: synchronous, synchronousLoads: false, animated: false, customAnimationTransition: nil, inputAnimatedInsertIndices: [], insertDirectionHints: [:], inputState: state, inputPreviousNodes: [:], inputOperations: []) { state, operations in var updatedState = state var updatedOperations = operations updatedState.removeInvisibleNodes(&updatedOperations) if synchronous { - self.replayOperations(animated: false, animateAlpha: false, animateCrossfade: false, animateFullTransition: false, synchronous: false, synchronousLoads: false, animateTopItemVerticalOrigin: false, operations: updatedOperations, requestItemInsertionAnimationsIndices: Set(), scrollToItem: nil, additionalScrollDistance: 0.0, updateSizeAndInsets: nil, stationaryItemIndex: nil, updateOpaqueState: nil, completion: completion) + self.replayOperations(animated: false, animateAlpha: false, animateCrossfade: false, animateFullTransition: false, customAnimationTransition: nil, synchronous: false, synchronousLoads: false, animateTopItemVerticalOrigin: false, operations: updatedOperations, requestItemInsertionAnimationsIndices: Set(), scrollToItem: nil, additionalScrollDistance: 0.0, updateSizeAndInsets: nil, stationaryItemIndex: nil, updateOpaqueState: nil, completion: completion) } else { self.dispatchOnVSync { - self.replayOperations(animated: false, animateAlpha: false, animateCrossfade: false, animateFullTransition: false, synchronous: false, synchronousLoads: false, animateTopItemVerticalOrigin: false, operations: updatedOperations, requestItemInsertionAnimationsIndices: Set(), scrollToItem: nil, additionalScrollDistance: 0.0, updateSizeAndInsets: nil, stationaryItemIndex: nil, updateOpaqueState: nil, completion: completion) + self.replayOperations(animated: false, animateAlpha: false, animateCrossfade: false, animateFullTransition: false, customAnimationTransition: nil, synchronous: false, synchronousLoads: false, animateTopItemVerticalOrigin: false, operations: updatedOperations, requestItemInsertionAnimationsIndices: Set(), scrollToItem: nil, additionalScrollDistance: 0.0, updateSizeAndInsets: nil, stationaryItemIndex: nil, updateOpaqueState: nil, completion: completion) } } } diff --git a/submodules/Display/Source/ListViewIntermediateState.swift b/submodules/Display/Source/ListViewIntermediateState.swift index 0d5c6d9ba0..e80b3c1185 100644 --- a/submodules/Display/Source/ListViewIntermediateState.swift +++ b/submodules/Display/Source/ListViewIntermediateState.swift @@ -141,8 +141,9 @@ public struct ListViewUpdateSizeAndInsets { public var duration: Double public var curve: ListViewAnimationCurve public var ensureTopInsetForOverlayHighlightedItems: CGFloat? + public var customAnimationTransition: ControlledTransition? - public init(size: CGSize, insets: UIEdgeInsets, headerInsets: UIEdgeInsets? = nil, scrollIndicatorInsets: UIEdgeInsets? = nil, duration: Double, curve: ListViewAnimationCurve, ensureTopInsetForOverlayHighlightedItems: CGFloat? = nil) { + public init(size: CGSize, insets: UIEdgeInsets, headerInsets: UIEdgeInsets? = nil, scrollIndicatorInsets: UIEdgeInsets? = nil, duration: Double, curve: ListViewAnimationCurve, ensureTopInsetForOverlayHighlightedItems: CGFloat? = nil, customAnimationTransition: ControlledTransition? = nil) { self.size = size self.insets = insets self.headerInsets = headerInsets @@ -150,6 +151,7 @@ public struct ListViewUpdateSizeAndInsets { self.duration = duration self.curve = curve self.ensureTopInsetForOverlayHighlightedItems = ensureTopInsetForOverlayHighlightedItems + self.customAnimationTransition = customAnimationTransition } } diff --git a/submodules/Display/Source/ListViewItemHeader.swift b/submodules/Display/Source/ListViewItemHeader.swift index 8842efc8a2..98a43c73b0 100644 --- a/submodules/Display/Source/ListViewItemHeader.swift +++ b/submodules/Display/Source/ListViewItemHeader.swift @@ -10,6 +10,7 @@ public enum ListViewItemHeaderStickDirection { public protocol ListViewItemHeader: AnyObject { var id: ListViewItemNode.HeaderId { get } + var stackingId: ListViewItemNode.HeaderId? { get } var stickDirection: ListViewItemHeaderStickDirection { get } var height: CGFloat { get } var stickOverInsets: Bool { get } @@ -29,6 +30,9 @@ open class ListViewItemHeaderNode: ASDisplayNode { private var isFlashingOnScrolling = false weak var attachedToItemNode: ListViewItemNode? + var offsetByHeaderNodeId: ListViewItemNode.HeaderId? + var naturalOriginY: CGFloat? + public var item: ListViewItemHeader? func updateInternalStickLocationDistanceFactor(_ factor: CGFloat, animated: Bool) { @@ -61,7 +65,7 @@ open class ListViewItemHeaderNode: ASDisplayNode { self.isLayerBacked = layerBacked } - open func updateStickDistanceFactor(_ factor: CGFloat, transition: ContainedViewLayoutTransition) { + open func updateStickDistanceFactor(_ factor: CGFloat, distance: CGFloat, transition: ContainedViewLayoutTransition) { } final func addScrollingOffset(_ scrollingOffset: CGFloat) { @@ -128,7 +132,7 @@ open class ListViewItemHeaderNode: ASDisplayNode { private var cachedLayout: (CGSize, CGFloat, CGFloat)? - public func updateLayoutInternal(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) { + public func updateLayoutInternal(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { var update = false if let cachedLayout = self.cachedLayout { if cachedLayout.0 != size || cachedLayout.1 != leftInset || cachedLayout.2 != rightInset { @@ -139,11 +143,11 @@ open class ListViewItemHeaderNode: ASDisplayNode { } if update { self.cachedLayout = (size, leftInset, rightInset) - self.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset) + self.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset, transition: transition) } } - open func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) { + open func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { } open func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) { diff --git a/submodules/Display/Source/ListViewItemNode.swift b/submodules/Display/Source/ListViewItemNode.swift index 2d44033cb2..7c3ff8eee7 100644 --- a/submodules/Display/Source/ListViewItemNode.swift +++ b/submodules/Display/Source/ListViewItemNode.swift @@ -629,9 +629,16 @@ open class ListViewItemNode: ASDisplayNode, AccessibilityFocusableNode { (self.supernode as? ListView)?.ensureItemNodeVisible(self, animated: false, overflow: 22.0, allowIntersection: true) } - public func updateFrame(_ frame: CGRect, within containerSize: CGSize, updateFrame: Bool = true) { + public func updateFrame(_ frame: CGRect, within containerSize: CGSize, updateFrame: Bool = true, transition: ControlledTransition? = nil) { if updateFrame { - self.frame = frame + if let transition { + let previousFrame = self.frame + self.frame = frame + + transition.legacyAnimator.transition.animatePositionAdditive(layer: self.layer, offset: CGPoint(x: previousFrame.minX - frame.minX, y: previousFrame.minY - frame.minY)) + } else { + self.frame = frame + } } if frame.maxY < 0.0 || frame.minY > containerSize.height { } else { diff --git a/submodules/EncryptionKeyVisualization/Impl/BUILD b/submodules/EncryptionKeyVisualization/Impl/BUILD index c4c7874874..b4cd316031 100644 --- a/submodules/EncryptionKeyVisualization/Impl/BUILD +++ b/submodules/EncryptionKeyVisualization/Impl/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/EncryptionProvider/BUILD b/submodules/EncryptionProvider/BUILD index 7b876fc0d7..380a5eb390 100644 --- a/submodules/EncryptionProvider/BUILD +++ b/submodules/EncryptionProvider/BUILD @@ -3,9 +3,7 @@ objc_library( name = "EncryptionProvider", enable_modules = True, module_name = "EncryptionProvider", - srcs = glob([ - "Sources/**/*.m", - ]), + srcs = [], hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/FFMpegBinding/BUILD b/submodules/FFMpegBinding/BUILD index 912e66ded1..70b8dbb350 100644 --- a/submodules/FFMpegBinding/BUILD +++ b/submodules/FFMpegBinding/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "Public/**/*.h", ]), diff --git a/submodules/GalleryUI/Sources/GalleryController.swift b/submodules/GalleryUI/Sources/GalleryController.swift index aec776a3b8..e161b6d5b5 100644 --- a/submodules/GalleryUI/Sources/GalleryController.swift +++ b/submodules/GalleryUI/Sources/GalleryController.swift @@ -792,8 +792,8 @@ public class GalleryController: ViewController, StandalonePresentableController, let syncResult = Atomic<(Bool, (() -> Void)?)>(value: (false, nil)) self.disposable.set(combineLatest( messageView, - self.context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration]), - translateToLanguage + self.context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration]) |> take(1), + translateToLanguage |> take(1) ).start(next: { [weak self] view, preferencesView, translateToLanguage in let f: () -> Void = { if let strongSelf = self { diff --git a/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift b/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift index 0723c7d3a2..499100d72b 100644 --- a/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift +++ b/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift @@ -2045,6 +2045,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo public final class ItemListPeerItemHeader: ListViewItemHeader { public let id: ListViewItemNode.HeaderId + public let stackingId: ListViewItemNode.HeaderId? = nil public let context: AccountContext public let text: NSAttributedString public let additionalText: String @@ -2201,11 +2202,11 @@ public final class ItemListPeerItemHeaderNode: ListViewItemHeaderNode, ItemListH self.actionTextNode.attributedText = NSAttributedString(string: actionTitle ?? "", font: titleFont, textColor: action == nil ? theme.list.sectionHeaderTextColor : theme.list.itemAccentColor) self.actionButton.isUserInteractionEnabled = self.action != nil if let (size, leftInset, rightInset) = self.validLayout { - self.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset) + self.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset, transition: .immediate) } } - override public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) { + override public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { self.validLayout = (size, leftInset, rightInset) self.backgroundNode.frame = CGRect(origin: CGPoint(), size: size) self.snappedBackgroundNode.frame = CGRect(origin: CGPoint(), size: size) @@ -2229,7 +2230,7 @@ public final class ItemListPeerItemHeaderNode: ListViewItemHeaderNode, ItemListH self.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: true) } - override public func updateStickDistanceFactor(_ factor: CGFloat, transition: ContainedViewLayoutTransition) { + override public func updateStickDistanceFactor(_ factor: CGFloat, distance: CGFloat, transition: ContainedViewLayoutTransition) { if self.stickDistanceFactor == factor { return } diff --git a/submodules/ListMessageItem/Sources/ListMessageDateHeader.swift b/submodules/ListMessageItem/Sources/ListMessageDateHeader.swift index a6763f51d6..40cd573723 100644 --- a/submodules/ListMessageItem/Sources/ListMessageDateHeader.swift +++ b/submodules/ListMessageItem/Sources/ListMessageDateHeader.swift @@ -42,6 +42,7 @@ final class ListMessageDateHeader: ListViewItemHeader { private let year: Int32 let id: ListViewItemNode.HeaderId + let stackingId: ListViewItemNode.HeaderId? = nil let theme: PresentationTheme let strings: PresentationStrings let fontSize: PresentationFontSize @@ -117,7 +118,7 @@ public final class ListMessageDateHeaderNode: ListViewItemHeaderNode { self.setNeedsLayout() } - override public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) { + override public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { let headerFrame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: size.width, height: size.height + UIScreenPixel)) self.headerNode.frame = headerFrame self.headerNode.updateLayout(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset) diff --git a/submodules/LottieCpp/BUILD b/submodules/LottieCpp/BUILD index 67dc182542..686f35669a 100644 --- a/submodules/LottieCpp/BUILD +++ b/submodules/LottieCpp/BUILD @@ -17,7 +17,7 @@ objc_library( "lottiecpp/PlatformSpecific/Darwin/Sources/**/*.c", "lottiecpp/PlatformSpecific/Darwin/Sources/**/*.cpp", "lottiecpp/PlatformSpecific/Darwin/Sources/**/*.hpp", - ]), + ], allow_empty=True), copts = [ "-Werror", "-I{}/lottiecpp/Sources".format(package_name()), @@ -44,7 +44,7 @@ cc_library( hdrs = glob([ "lottiecpp/PublicHeaders/**/*.h", "lottiecpp/PlatformSpecific/Darwin/PublicHeaders/**/*.h", - ]), + ], allow_empty=True), includes = [ "PublicHeaders", ], diff --git a/submodules/MimeTypes/BUILD b/submodules/MimeTypes/BUILD index cdaaa20685..e4c7fb3d6a 100644 --- a/submodules/MimeTypes/BUILD +++ b/submodules/MimeTypes/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/*.m", "Sources/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/MonotonicTime/BUILD b/submodules/MonotonicTime/BUILD index 545b0a7b88..075c8066c9 100644 --- a/submodules/MonotonicTime/BUILD +++ b/submodules/MonotonicTime/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/*.m", "Sources/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/MozjpegBinding/BUILD b/submodules/MozjpegBinding/BUILD index db74cf5040..01efb01634 100644 --- a/submodules/MozjpegBinding/BUILD +++ b/submodules/MozjpegBinding/BUILD @@ -7,7 +7,7 @@ objc_library( "Sources/**/*.m", "Sources/**/*.mm", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "Public/**/*.h", ]), diff --git a/submodules/OpenSSLEncryptionProvider/BUILD b/submodules/OpenSSLEncryptionProvider/BUILD index 648b6de676..cd745b149e 100644 --- a/submodules/OpenSSLEncryptionProvider/BUILD +++ b/submodules/OpenSSLEncryptionProvider/BUILD @@ -5,7 +5,6 @@ objc_library( module_name = "OpenSSLEncryptionProvider", srcs = glob([ "Sources/**/*.m", - "Sources/**/*.h", ]), hdrs = glob([ "PublicHeaders/**/*.h", diff --git a/submodules/PKCS/BUILD b/submodules/PKCS/BUILD index 6334f1cc4c..a781fe2224 100644 --- a/submodules/PKCS/BUILD +++ b/submodules/PKCS/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/Postbox/Sources/MessageHistoryTable.swift b/submodules/Postbox/Sources/MessageHistoryTable.swift index 7d4bf2899e..7c097a125d 100644 --- a/submodules/Postbox/Sources/MessageHistoryTable.swift +++ b/submodules/Postbox/Sources/MessageHistoryTable.swift @@ -2782,6 +2782,10 @@ final class MessageHistoryTable: Table { associatedThreadInfo = self.seedConfiguration.decodeMessageThreadInfo(data.data) } + if let threadId = message.threadId, let possibleThreadPeer = peerTable.get(PeerId(threadId)) { + peers[possibleThreadPeer.id] = possibleThreadPeer + } + return Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: message.timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, customTags: message.customTags, forwardInfo: forwardInfo, author: author, text: message.text, attributes: parsedAttributes, media: parsedMedia, peers: peers, associatedMessages: associatedMessages, associatedMessageIds: associatedMessageIds, associatedMedia: associatedMedia, associatedThreadInfo: associatedThreadInfo, associatedStories: associatedStories) } diff --git a/submodules/Postbox/Sources/MessageHistoryViewState.swift b/submodules/Postbox/Sources/MessageHistoryViewState.swift index 1449e611ea..02a4cf1532 100644 --- a/submodules/Postbox/Sources/MessageHistoryViewState.swift +++ b/submodules/Postbox/Sources/MessageHistoryViewState.swift @@ -969,7 +969,7 @@ struct OrderedHistoryViewEntries { } } - #if DEBUG && TARGET_OS_IOS + #if DEBUG && os(iOS) for entry in self.lowerOrAtAnchor { assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace)) } @@ -1008,7 +1008,7 @@ struct OrderedHistoryViewEntries { } } - #if DEBUG && TARGET_OS_IOS + #if DEBUG && os(iOS) for entry in self.lowerOrAtAnchor { assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace)) } @@ -1047,7 +1047,7 @@ struct OrderedHistoryViewEntries { } } - #if DEBUG && TARGET_OS_IOS + #if DEBUG && os(iOS) for entry in self.lowerOrAtAnchor { assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace)) } @@ -1073,7 +1073,7 @@ struct OrderedHistoryViewEntries { } } - #if DEBUG && TARGET_OS_IOS + #if DEBUG && os(iOS) for entry in self.lowerOrAtAnchor { assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace)) } @@ -1099,7 +1099,7 @@ struct OrderedHistoryViewEntries { } } - #if DEBUG && TARGET_OS_IOS + #if DEBUG && os(iOS) for entry in self.lowerOrAtAnchor { assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace)) } @@ -1125,7 +1125,7 @@ struct OrderedHistoryViewEntries { self.lowerOrAtAnchor.remove(at: index) - #if DEBUG && TARGET_OS_IOS + #if DEBUG && os(iOS) for entry in self.lowerOrAtAnchor { assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace)) } @@ -1151,7 +1151,7 @@ struct OrderedHistoryViewEntries { self.higherThanAnchor.remove(at: index) - #if DEBUG && TARGET_OS_IOS + #if DEBUG && os(iOS) for entry in self.lowerOrAtAnchor { assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace)) } @@ -1207,7 +1207,7 @@ struct OrderedHistoryViewEntries { self.higherThanAnchor.sort(by: { $0.index.id.id < $1.index.id.id }) } - #if DEBUG && TARGET_OS_IOS + #if DEBUG && os(iOS) for entry in self.lowerOrAtAnchor { assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace)) } diff --git a/submodules/RaiseToListen/Impl/BUILD b/submodules/RaiseToListen/Impl/BUILD index 0ecababba4..8bdcffdd65 100644 --- a/submodules/RaiseToListen/Impl/BUILD +++ b/submodules/RaiseToListen/Impl/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift b/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift index b3a847c5dd..ff0d42bcf8 100644 --- a/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift +++ b/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift @@ -253,7 +253,7 @@ private final class BubbleSettingsControllerNode: ASDisplayNode, ASScrollViewDel } transition.updateFrame(node: dateHeaderNode, frame: CGRect(origin: CGPoint(x: 0.0, y: bottomOffset), size: CGSize(width: layout.size.width, height: headerItem.height))) - dateHeaderNode.updateLayout(size: self.messagesContainerNode.frame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right) + dateHeaderNode.updateLayout(size: self.messagesContainerNode.frame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: .immediate) } func updatePresentationThemeSettings(_ presentationThemeSettings: PresentationThemeSettings) { diff --git a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift index da00b80f4f..4258e68693 100644 --- a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift +++ b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift @@ -321,10 +321,10 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, ASScrollView let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) - let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil)) + let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil)) let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) - let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil)) + let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil)) let peer6: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let timestamp = self.referenceTimestamp @@ -524,7 +524,7 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, ASScrollView } transition.updateFrame(node: dateHeaderNode, frame: CGRect(origin: CGPoint(x: 0.0, y: bottomOffset), size: CGSize(width: layout.size.width, height: headerItem.height))) - dateHeaderNode.updateLayout(size: self.messagesContainerNode.frame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right) + dateHeaderNode.updateLayout(size: self.messagesContainerNode.frame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: .immediate) } func updatePresentationThemeSettings(_ presentationThemeSettings: PresentationThemeSettings) { diff --git a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift index 94b8743d41..5431653217 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift @@ -470,10 +470,10 @@ final class ThemePreviewControllerNode: ASDisplayNode, ASScrollViewDelegate { let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) - let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil)) + let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil)) let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) - let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil)) + let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil)) let peer6: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let peer7: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(6)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_7_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) @@ -696,7 +696,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, ASScrollViewDelegate { } transition.updateFrame(node: dateHeaderNode, frame: CGRect(origin: CGPoint(x: 0.0, y: bottomOffset), size: CGSize(width: layout.size.width, height: headerItem.height))) - dateHeaderNode.updateLayout(size: self.messagesContainerNode.frame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right) + dateHeaderNode.updateLayout(size: self.messagesContainerNode.frame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: .immediate) } func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { diff --git a/submodules/ShareItems/Impl/BUILD b/submodules/ShareItems/Impl/BUILD index 95a6289dab..21b141321f 100644 --- a/submodules/ShareItems/Impl/BUILD +++ b/submodules/ShareItems/Impl/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift index 26b078703c..60777f05e1 100644 --- a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift +++ b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift @@ -388,7 +388,7 @@ class StatsOverviewItemNode: ListViewItemNode { insets = itemListNeighborsGroupedInsets(neighbors, params) } - var twoColumnLayout = true + var twoColumnLayout = "".isEmpty // Silence the warning var useMinLeftColumnWidth = false var topLeftItemLayoutAndApply: (CGSize, () -> ValueItemNode)? diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 5aa75afbe9..e6d624d75c 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -200,7 +200,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-531931925] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsMentions($0) } dict[-566281095] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsRecent($0) } dict[106343499] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsSearch($0) } - dict[1954681982] = { return Api.Chat.parse_channel($0) } + dict[-26717355] = { return Api.Chat.parse_channel($0) } dict[399807445] = { return Api.Chat.parse_channelForbidden($0) } dict[1103884886] = { return Api.Chat.parse_chat($0) } dict[693512293] = { return Api.Chat.parse_chatEmpty($0) } @@ -208,7 +208,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1605510357] = { return Api.ChatAdminRights.parse_chatAdminRights($0) } dict[-219353309] = { return Api.ChatAdminWithInvites.parse_chatAdminWithInvites($0) } dict[-1626209256] = { return Api.ChatBannedRights.parse_chatBannedRights($0) } - dict[2143550156] = { return Api.ChatFull.parse_channelFull($0) } + dict[1389789291] = { return Api.ChatFull.parse_channelFull($0) } dict[640893467] = { return Api.ChatFull.parse_chatFull($0) } dict[1553807106] = { return Api.ChatInvite.parse_chatInvite($0) } dict[1516793212] = { return Api.ChatInvite.parse_chatInviteAlready($0) } diff --git a/submodules/TelegramApi/Sources/Api38.swift b/submodules/TelegramApi/Sources/Api38.swift index 8459b8722e..89e642222c 100644 --- a/submodules/TelegramApi/Sources/Api38.swift +++ b/submodules/TelegramApi/Sources/Api38.swift @@ -5640,9 +5640,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?, scheduleDate: Int32?, sendAs: Api.InputPeer?, quickReplyShortcut: Api.InputQuickReplyShortcut?, videoTimestamp: Int32?, allowPaidStars: Int64?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func forwardMessages(flags: Int32, fromPeer: Api.InputPeer, id: [Int32], randomId: [Int64], toPeer: Api.InputPeer, topMsgId: Int32?, replyTo: Api.InputReplyTo?, scheduleDate: Int32?, sendAs: Api.InputPeer?, quickReplyShortcut: Api.InputQuickReplyShortcut?, videoTimestamp: Int32?, allowPaidStars: Int64?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(-1147165579) + buffer.appendInt32(955259020) serializeInt32(flags, buffer: buffer, boxed: false) fromPeer.serialize(buffer, true) buffer.appendInt32(481674261) @@ -5657,12 +5657,13 @@ public extension Api.functions.messages { } toPeer.serialize(buffer, true) if Int(flags) & Int(1 << 9) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 22) != 0 {replyTo!.serialize(buffer, true)} if Int(flags) & Int(1 << 10) != 0 {serializeInt32(scheduleDate!, 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 << 20) != 0 {serializeInt32(videoTimestamp!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 21) != 0 {serializeInt64(allowPaidStars!, buffer: buffer, boxed: false)} - 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)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs)), ("quickReplyShortcut", String(describing: quickReplyShortcut)), ("videoTimestamp", String(describing: videoTimestamp)), ("allowPaidStars", String(describing: allowPaidStars))]), 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)), ("sendAs", String(describing: sendAs)), ("quickReplyShortcut", String(describing: quickReplyShortcut)), ("videoTimestamp", String(describing: videoTimestamp)), ("allowPaidStars", String(describing: allowPaidStars))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in let reader = BufferReader(buffer) var result: Api.Updates? if let signature = reader.readInt32() { diff --git a/submodules/TelegramApi/Sources/Api4.swift b/submodules/TelegramApi/Sources/Api4.swift index 91700d5673..17aff5d9cc 100644 --- a/submodules/TelegramApi/Sources/Api4.swift +++ b/submodules/TelegramApi/Sources/Api4.swift @@ -534,7 +534,7 @@ public extension Api { } public extension Api { indirect enum Chat: TypeConstructorDescription { - case channel(flags: Int32, flags2: Int32, id: Int64, accessHash: Int64?, title: String, username: String?, photo: Api.ChatPhoto, date: Int32, restrictionReason: [Api.RestrictionReason]?, adminRights: Api.ChatAdminRights?, bannedRights: Api.ChatBannedRights?, defaultBannedRights: Api.ChatBannedRights?, participantsCount: Int32?, usernames: [Api.Username]?, storiesMaxId: Int32?, color: Api.PeerColor?, profileColor: Api.PeerColor?, emojiStatus: Api.EmojiStatus?, level: Int32?, subscriptionUntilDate: Int32?, botVerificationIcon: Int64?, sendPaidMessagesStars: Int64?) + case channel(flags: Int32, flags2: Int32, id: Int64, accessHash: Int64?, title: String, username: String?, photo: Api.ChatPhoto, date: Int32, restrictionReason: [Api.RestrictionReason]?, adminRights: Api.ChatAdminRights?, bannedRights: Api.ChatBannedRights?, defaultBannedRights: Api.ChatBannedRights?, participantsCount: Int32?, usernames: [Api.Username]?, storiesMaxId: Int32?, color: Api.PeerColor?, profileColor: Api.PeerColor?, emojiStatus: Api.EmojiStatus?, level: Int32?, subscriptionUntilDate: Int32?, botVerificationIcon: Int64?, sendPaidMessagesStars: Int64?, linkedMonoforumId: Int64?) case channelForbidden(flags: Int32, id: Int64, accessHash: Int64, title: String, untilDate: Int32?) case chat(flags: Int32, id: Int64, title: String, photo: Api.ChatPhoto, participantsCount: Int32, date: Int32, version: Int32, migratedTo: Api.InputChannel?, adminRights: Api.ChatAdminRights?, defaultBannedRights: Api.ChatBannedRights?) case chatEmpty(id: Int64) @@ -542,9 +542,9 @@ public extension Api { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .channel(let flags, let flags2, let id, let accessHash, let title, let username, let photo, let date, let restrictionReason, let adminRights, let bannedRights, let defaultBannedRights, let participantsCount, let usernames, let storiesMaxId, let color, let profileColor, let emojiStatus, let level, let subscriptionUntilDate, let botVerificationIcon, let sendPaidMessagesStars): + case .channel(let flags, let flags2, let id, let accessHash, let title, let username, let photo, let date, let restrictionReason, let adminRights, let bannedRights, let defaultBannedRights, let participantsCount, let usernames, let storiesMaxId, let color, let profileColor, let emojiStatus, let level, let subscriptionUntilDate, let botVerificationIcon, let sendPaidMessagesStars, let linkedMonoforumId): if boxed { - buffer.appendInt32(1954681982) + buffer.appendInt32(-26717355) } serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags2, buffer: buffer, boxed: false) @@ -576,6 +576,7 @@ public extension Api { if Int(flags2) & Int(1 << 11) != 0 {serializeInt32(subscriptionUntilDate!, buffer: buffer, boxed: false)} if Int(flags2) & Int(1 << 13) != 0 {serializeInt64(botVerificationIcon!, buffer: buffer, boxed: false)} if Int(flags2) & Int(1 << 14) != 0 {serializeInt64(sendPaidMessagesStars!, buffer: buffer, boxed: false)} + if Int(flags2) & Int(1 << 18) != 0 {serializeInt64(linkedMonoforumId!, buffer: buffer, boxed: false)} break case .channelForbidden(let flags, let id, let accessHash, let title, let untilDate): if boxed { @@ -620,8 +621,8 @@ public extension Api { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .channel(let flags, let flags2, let id, let accessHash, let title, let username, let photo, let date, let restrictionReason, let adminRights, let bannedRights, let defaultBannedRights, let participantsCount, let usernames, let storiesMaxId, let color, let profileColor, let emojiStatus, let level, let subscriptionUntilDate, let botVerificationIcon, let sendPaidMessagesStars): - return ("channel", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("accessHash", accessHash as Any), ("title", title as Any), ("username", username as Any), ("photo", photo as Any), ("date", date as Any), ("restrictionReason", restrictionReason as Any), ("adminRights", adminRights as Any), ("bannedRights", bannedRights as Any), ("defaultBannedRights", defaultBannedRights as Any), ("participantsCount", participantsCount as Any), ("usernames", usernames as Any), ("storiesMaxId", storiesMaxId as Any), ("color", color as Any), ("profileColor", profileColor as Any), ("emojiStatus", emojiStatus as Any), ("level", level as Any), ("subscriptionUntilDate", subscriptionUntilDate as Any), ("botVerificationIcon", botVerificationIcon as Any), ("sendPaidMessagesStars", sendPaidMessagesStars as Any)]) + case .channel(let flags, let flags2, let id, let accessHash, let title, let username, let photo, let date, let restrictionReason, let adminRights, let bannedRights, let defaultBannedRights, let participantsCount, let usernames, let storiesMaxId, let color, let profileColor, let emojiStatus, let level, let subscriptionUntilDate, let botVerificationIcon, let sendPaidMessagesStars, let linkedMonoforumId): + return ("channel", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("accessHash", accessHash as Any), ("title", title as Any), ("username", username as Any), ("photo", photo as Any), ("date", date as Any), ("restrictionReason", restrictionReason as Any), ("adminRights", adminRights as Any), ("bannedRights", bannedRights as Any), ("defaultBannedRights", defaultBannedRights as Any), ("participantsCount", participantsCount as Any), ("usernames", usernames as Any), ("storiesMaxId", storiesMaxId as Any), ("color", color as Any), ("profileColor", profileColor as Any), ("emojiStatus", emojiStatus as Any), ("level", level as Any), ("subscriptionUntilDate", subscriptionUntilDate as Any), ("botVerificationIcon", botVerificationIcon as Any), ("sendPaidMessagesStars", sendPaidMessagesStars as Any), ("linkedMonoforumId", linkedMonoforumId as Any)]) case .channelForbidden(let flags, let id, let accessHash, let title, let untilDate): return ("channelForbidden", [("flags", flags as Any), ("id", id as Any), ("accessHash", accessHash as Any), ("title", title as Any), ("untilDate", untilDate as Any)]) case .chat(let flags, let id, let title, let photo, let participantsCount, let date, let version, let migratedTo, let adminRights, let defaultBannedRights): @@ -696,6 +697,8 @@ public extension Api { if Int(_2!) & Int(1 << 13) != 0 {_21 = reader.readInt64() } var _22: Int64? if Int(_2!) & Int(1 << 14) != 0 {_22 = reader.readInt64() } + var _23: Int64? + if Int(_2!) & Int(1 << 18) != 0 {_23 = reader.readInt64() } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil @@ -718,8 +721,9 @@ public extension Api { let _c20 = (Int(_2!) & Int(1 << 11) == 0) || _20 != nil let _c21 = (Int(_2!) & Int(1 << 13) == 0) || _21 != nil let _c22 = (Int(_2!) & Int(1 << 14) == 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.Chat.channel(flags: _1!, flags2: _2!, id: _3!, accessHash: _4, title: _5!, username: _6, photo: _7!, date: _8!, restrictionReason: _9, adminRights: _10, bannedRights: _11, defaultBannedRights: _12, participantsCount: _13, usernames: _14, storiesMaxId: _15, color: _16, profileColor: _17, emojiStatus: _18, level: _19, subscriptionUntilDate: _20, botVerificationIcon: _21, sendPaidMessagesStars: _22) + let _c23 = (Int(_2!) & Int(1 << 18) == 0) || _23 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 { + return Api.Chat.channel(flags: _1!, flags2: _2!, id: _3!, accessHash: _4, title: _5!, username: _6, photo: _7!, date: _8!, restrictionReason: _9, adminRights: _10, bannedRights: _11, defaultBannedRights: _12, participantsCount: _13, usernames: _14, storiesMaxId: _15, color: _16, profileColor: _17, emojiStatus: _18, level: _19, subscriptionUntilDate: _20, botVerificationIcon: _21, sendPaidMessagesStars: _22, linkedMonoforumId: _23) } else { return nil @@ -944,14 +948,14 @@ public extension Api { } public extension Api { enum ChatFull: TypeConstructorDescription { - case channelFull(flags: Int32, flags2: Int32, id: Int64, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo], migratedFromChatId: Int64?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int64?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?, ttlPeriod: Int32?, pendingSuggestions: [String]?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, defaultSendAs: Api.Peer?, availableReactions: Api.ChatReactions?, reactionsLimit: Int32?, stories: Api.PeerStories?, wallpaper: Api.WallPaper?, boostsApplied: Int32?, boostsUnrestrict: Int32?, emojiset: Api.StickerSet?, botVerification: Api.BotVerification?, stargiftsCount: Int32?, linkedMonoforumId: Int64?) + case channelFull(flags: Int32, flags2: Int32, id: Int64, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo], migratedFromChatId: Int64?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int64?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?, ttlPeriod: Int32?, pendingSuggestions: [String]?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, defaultSendAs: Api.Peer?, availableReactions: Api.ChatReactions?, reactionsLimit: Int32?, stories: Api.PeerStories?, wallpaper: Api.WallPaper?, boostsApplied: Int32?, boostsUnrestrict: Int32?, emojiset: Api.StickerSet?, botVerification: Api.BotVerification?, stargiftsCount: Int32?) case chatFull(flags: Int32, id: Int64, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?, call: Api.InputGroupCall?, ttlPeriod: Int32?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, availableReactions: Api.ChatReactions?, reactionsLimit: Int32?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .channelFull(let flags, let flags2, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttlPeriod, let pendingSuggestions, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let defaultSendAs, let availableReactions, let reactionsLimit, let stories, let wallpaper, let boostsApplied, let boostsUnrestrict, let emojiset, let botVerification, let stargiftsCount, let linkedMonoforumId): + case .channelFull(let flags, let flags2, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttlPeriod, let pendingSuggestions, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let defaultSendAs, let availableReactions, let reactionsLimit, let stories, let wallpaper, let boostsApplied, let boostsUnrestrict, let emojiset, let botVerification, let stargiftsCount): if boxed { - buffer.appendInt32(2143550156) + buffer.appendInt32(1389789291) } serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags2, buffer: buffer, boxed: false) @@ -1010,7 +1014,6 @@ public extension Api { if Int(flags2) & Int(1 << 10) != 0 {emojiset!.serialize(buffer, true)} if Int(flags2) & Int(1 << 17) != 0 {botVerification!.serialize(buffer, true)} if Int(flags2) & Int(1 << 18) != 0 {serializeInt32(stargiftsCount!, buffer: buffer, boxed: false)} - if Int(flags2) & Int(1 << 21) != 0 {serializeInt64(linkedMonoforumId!, buffer: buffer, boxed: false)} break case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttlPeriod, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let availableReactions, let reactionsLimit): if boxed { @@ -1048,8 +1051,8 @@ public extension Api { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .channelFull(let flags, let flags2, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttlPeriod, let pendingSuggestions, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let defaultSendAs, let availableReactions, let reactionsLimit, let stories, let wallpaper, let boostsApplied, let boostsUnrestrict, let emojiset, let botVerification, let stargiftsCount, let linkedMonoforumId): - return ("channelFull", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("about", about as Any), ("participantsCount", participantsCount as Any), ("adminsCount", adminsCount as Any), ("kickedCount", kickedCount as Any), ("bannedCount", bannedCount as Any), ("onlineCount", onlineCount as Any), ("readInboxMaxId", readInboxMaxId as Any), ("readOutboxMaxId", readOutboxMaxId as Any), ("unreadCount", unreadCount as Any), ("chatPhoto", chatPhoto as Any), ("notifySettings", notifySettings as Any), ("exportedInvite", exportedInvite as Any), ("botInfo", botInfo as Any), ("migratedFromChatId", migratedFromChatId as Any), ("migratedFromMaxId", migratedFromMaxId as Any), ("pinnedMsgId", pinnedMsgId as Any), ("stickerset", stickerset as Any), ("availableMinId", availableMinId as Any), ("folderId", folderId as Any), ("linkedChatId", linkedChatId as Any), ("location", location as Any), ("slowmodeSeconds", slowmodeSeconds as Any), ("slowmodeNextSendDate", slowmodeNextSendDate as Any), ("statsDc", statsDc as Any), ("pts", pts as Any), ("call", call as Any), ("ttlPeriod", ttlPeriod as Any), ("pendingSuggestions", pendingSuggestions as Any), ("groupcallDefaultJoinAs", groupcallDefaultJoinAs as Any), ("themeEmoticon", themeEmoticon as Any), ("requestsPending", requestsPending as Any), ("recentRequesters", recentRequesters as Any), ("defaultSendAs", defaultSendAs as Any), ("availableReactions", availableReactions as Any), ("reactionsLimit", reactionsLimit as Any), ("stories", stories as Any), ("wallpaper", wallpaper as Any), ("boostsApplied", boostsApplied as Any), ("boostsUnrestrict", boostsUnrestrict as Any), ("emojiset", emojiset as Any), ("botVerification", botVerification as Any), ("stargiftsCount", stargiftsCount as Any), ("linkedMonoforumId", linkedMonoforumId as Any)]) + case .channelFull(let flags, let flags2, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttlPeriod, let pendingSuggestions, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let defaultSendAs, let availableReactions, let reactionsLimit, let stories, let wallpaper, let boostsApplied, let boostsUnrestrict, let emojiset, let botVerification, let stargiftsCount): + return ("channelFull", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("about", about as Any), ("participantsCount", participantsCount as Any), ("adminsCount", adminsCount as Any), ("kickedCount", kickedCount as Any), ("bannedCount", bannedCount as Any), ("onlineCount", onlineCount as Any), ("readInboxMaxId", readInboxMaxId as Any), ("readOutboxMaxId", readOutboxMaxId as Any), ("unreadCount", unreadCount as Any), ("chatPhoto", chatPhoto as Any), ("notifySettings", notifySettings as Any), ("exportedInvite", exportedInvite as Any), ("botInfo", botInfo as Any), ("migratedFromChatId", migratedFromChatId as Any), ("migratedFromMaxId", migratedFromMaxId as Any), ("pinnedMsgId", pinnedMsgId as Any), ("stickerset", stickerset as Any), ("availableMinId", availableMinId as Any), ("folderId", folderId as Any), ("linkedChatId", linkedChatId as Any), ("location", location as Any), ("slowmodeSeconds", slowmodeSeconds as Any), ("slowmodeNextSendDate", slowmodeNextSendDate as Any), ("statsDc", statsDc as Any), ("pts", pts as Any), ("call", call as Any), ("ttlPeriod", ttlPeriod as Any), ("pendingSuggestions", pendingSuggestions as Any), ("groupcallDefaultJoinAs", groupcallDefaultJoinAs as Any), ("themeEmoticon", themeEmoticon as Any), ("requestsPending", requestsPending as Any), ("recentRequesters", recentRequesters as Any), ("defaultSendAs", defaultSendAs as Any), ("availableReactions", availableReactions as Any), ("reactionsLimit", reactionsLimit as Any), ("stories", stories as Any), ("wallpaper", wallpaper as Any), ("boostsApplied", boostsApplied as Any), ("boostsUnrestrict", boostsUnrestrict as Any), ("emojiset", emojiset as Any), ("botVerification", botVerification as Any), ("stargiftsCount", stargiftsCount as Any)]) case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttlPeriod, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let availableReactions, let reactionsLimit): return ("chatFull", [("flags", flags as Any), ("id", id as Any), ("about", about as Any), ("participants", participants as Any), ("chatPhoto", chatPhoto as Any), ("notifySettings", notifySettings as Any), ("exportedInvite", exportedInvite as Any), ("botInfo", botInfo as Any), ("pinnedMsgId", pinnedMsgId as Any), ("folderId", folderId as Any), ("call", call as Any), ("ttlPeriod", ttlPeriod as Any), ("groupcallDefaultJoinAs", groupcallDefaultJoinAs as Any), ("themeEmoticon", themeEmoticon as Any), ("requestsPending", requestsPending as Any), ("recentRequesters", recentRequesters as Any), ("availableReactions", availableReactions as Any), ("reactionsLimit", reactionsLimit as Any)]) } @@ -1178,8 +1181,6 @@ public extension Api { } } var _45: Int32? if Int(_2!) & Int(1 << 18) != 0 {_45 = reader.readInt32() } - var _46: Int64? - if Int(_2!) & Int(1 << 21) != 0 {_46 = reader.readInt64() } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil @@ -1225,9 +1226,8 @@ public extension Api { let _c43 = (Int(_2!) & Int(1 << 10) == 0) || _43 != nil let _c44 = (Int(_2!) & Int(1 << 17) == 0) || _44 != nil let _c45 = (Int(_2!) & Int(1 << 18) == 0) || _45 != nil - let _c46 = (Int(_2!) & Int(1 << 21) == 0) || _46 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 && _c34 && _c35 && _c36 && _c37 && _c38 && _c39 && _c40 && _c41 && _c42 && _c43 && _c44 && _c45 && _c46 { - return Api.ChatFull.channelFull(flags: _1!, flags2: _2!, id: _3!, about: _4!, participantsCount: _5, adminsCount: _6, kickedCount: _7, bannedCount: _8, onlineCount: _9, readInboxMaxId: _10!, readOutboxMaxId: _11!, unreadCount: _12!, chatPhoto: _13!, notifySettings: _14!, exportedInvite: _15, botInfo: _16!, migratedFromChatId: _17, migratedFromMaxId: _18, pinnedMsgId: _19, stickerset: _20, availableMinId: _21, folderId: _22, linkedChatId: _23, location: _24, slowmodeSeconds: _25, slowmodeNextSendDate: _26, statsDc: _27, pts: _28!, call: _29, ttlPeriod: _30, pendingSuggestions: _31, groupcallDefaultJoinAs: _32, themeEmoticon: _33, requestsPending: _34, recentRequesters: _35, defaultSendAs: _36, availableReactions: _37, reactionsLimit: _38, stories: _39, wallpaper: _40, boostsApplied: _41, boostsUnrestrict: _42, emojiset: _43, botVerification: _44, stargiftsCount: _45, linkedMonoforumId: _46) + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 && _c34 && _c35 && _c36 && _c37 && _c38 && _c39 && _c40 && _c41 && _c42 && _c43 && _c44 && _c45 { + return Api.ChatFull.channelFull(flags: _1!, flags2: _2!, id: _3!, about: _4!, participantsCount: _5, adminsCount: _6, kickedCount: _7, bannedCount: _8, onlineCount: _9, readInboxMaxId: _10!, readOutboxMaxId: _11!, unreadCount: _12!, chatPhoto: _13!, notifySettings: _14!, exportedInvite: _15, botInfo: _16!, migratedFromChatId: _17, migratedFromMaxId: _18, pinnedMsgId: _19, stickerset: _20, availableMinId: _21, folderId: _22, linkedChatId: _23, location: _24, slowmodeSeconds: _25, slowmodeNextSendDate: _26, statsDc: _27, pts: _28!, call: _29, ttlPeriod: _30, pendingSuggestions: _31, groupcallDefaultJoinAs: _32, themeEmoticon: _33, requestsPending: _34, recentRequesters: _35, defaultSendAs: _36, availableReactions: _37, reactionsLimit: _38, stories: _39, wallpaper: _40, boostsApplied: _41, boostsUnrestrict: _42, emojiset: _43, botVerification: _44, stargiftsCount: _45) } else { return nil diff --git a/submodules/TelegramCore/FlatSerialization/Models/TelegramChannel.fbs b/submodules/TelegramCore/FlatSerialization/Models/TelegramChannel.fbs index 0cef240e6f..8440b863e9 100644 --- a/submodules/TelegramCore/FlatSerialization/Models/TelegramChannel.fbs +++ b/submodules/TelegramCore/FlatSerialization/Models/TelegramChannel.fbs @@ -55,6 +55,7 @@ table TelegramChannel { subscriptionUntilDate:int32 (id: 22); verificationIconFileId:int64 (id: 23); sendPaidMessageStars:StarsAmount (id: 24); + linkedMonoforumId:PeerId (id: 25); } root_type TelegramChannel; diff --git a/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift b/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift index 65bfb08098..bc4b6190ed 100644 --- a/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift +++ b/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift @@ -494,7 +494,7 @@ struct AccountMutableState { for chat in chats { switch chat { - case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _): + case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _): if let participantsCount = participantsCount { self.addOperation(.UpdateCachedPeerData(chat.peerId, { current in var previous: CachedChannelData diff --git a/submodules/TelegramCore/Sources/Account/AccountManager.swift b/submodules/TelegramCore/Sources/Account/AccountManager.swift index 180790f157..ef367cdca9 100644 --- a/submodules/TelegramCore/Sources/Account/AccountManager.swift +++ b/submodules/TelegramCore/Sources/Account/AccountManager.swift @@ -228,7 +228,6 @@ private var declaredEncodables: Void = { declareEncodable(DerivedDataMessageAttribute.self, f: { DerivedDataMessageAttribute(decoder: $0) }) declareEncodable(TelegramApplicationIcons.self, f: { TelegramApplicationIcons(decoder: $0) }) declareEncodable(OutgoingQuickReplyMessageAttribute.self, f: { OutgoingQuickReplyMessageAttribute(decoder: $0) }) - declareEncodable(OutgoingSuggestedPostMessageAttribute.self, f: { OutgoingSuggestedPostMessageAttribute(decoder: $0) }) declareEncodable(EffectMessageAttribute.self, f: { EffectMessageAttribute(decoder: $0) }) declareEncodable(FactCheckMessageAttribute.self, f: { FactCheckMessageAttribute(decoder: $0) }) declareEncodable(TelegramMediaPaidContent.self, f: { TelegramMediaPaidContent(decoder: $0) }) diff --git a/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift b/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift index 9a914f0f08..ab6fa6b98b 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift @@ -61,7 +61,7 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? { return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)), title: "", photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0) case let .chatForbidden(id, title): return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)), title: title, photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0) - case let .channel(flags, flags2, id, accessHash, title, username, photo, date, restrictionReason, adminRights, bannedRights, defaultBannedRights, _, usernames, _, color, profileColor, emojiStatus, boostLevel, subscriptionUntilDate, verificationIconFileId, sendPaidMessageStars): + case let .channel(flags, flags2, id, accessHash, title, username, photo, date, restrictionReason, adminRights, bannedRights, defaultBannedRights, _, usernames, _, color, profileColor, emojiStatus, boostLevel, subscriptionUntilDate, verificationIconFileId, sendPaidMessageStars, linkedMonoforumId): let isMin = (flags & (1 << 12)) != 0 let participationStatus: TelegramChannelParticipationStatus @@ -185,7 +185,7 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? { } } - return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: date, version: 0, participationStatus: participationStatus, info: info, flags: channelFlags, restrictionInfo: restrictionInfo, adminRights: adminRights.flatMap(TelegramChatAdminRights.init), bannedRights: bannedRights.flatMap(TelegramChatBannedRights.init), defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColorIndex.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId, profileColor: profileColorIndex.flatMap { PeerNameColor(rawValue: $0) }, profileBackgroundEmojiId: profileBackgroundEmojiId, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), approximateBoostLevel: boostLevel, subscriptionUntilDate: subscriptionUntilDate, verificationIconFileId: verificationIconFileId, sendPaidMessageStars: sendPaidMessageStars.flatMap { StarsAmount(value: $0, nanos: 0) }) + return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: date, version: 0, participationStatus: participationStatus, info: info, flags: channelFlags, restrictionInfo: restrictionInfo, adminRights: adminRights.flatMap(TelegramChatAdminRights.init), bannedRights: bannedRights.flatMap(TelegramChatBannedRights.init), defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColorIndex.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId, profileColor: profileColorIndex.flatMap { PeerNameColor(rawValue: $0) }, profileBackgroundEmojiId: profileBackgroundEmojiId, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), approximateBoostLevel: boostLevel, subscriptionUntilDate: subscriptionUntilDate, verificationIconFileId: verificationIconFileId, sendPaidMessageStars: sendPaidMessageStars.flatMap { StarsAmount(value: $0, nanos: 0) }, linkedMonoforumId: linkedMonoforumId.flatMap { PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value($0)) }) case let .channelForbidden(flags, id, accessHash, title, untilDate): let info: TelegramChannelInfo if (flags & Int32(1 << 8)) != 0 { @@ -194,7 +194,7 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? { info = .broadcast(TelegramChannelBroadcastInfo(flags: [])) } - return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: .personal(accessHash), title: title, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .kicked, info: info, flags: TelegramChannelFlags(), restrictionInfo: nil, adminRights: nil, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: untilDate ?? Int32.max), defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil) + return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: .personal(accessHash), title: title, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .kicked, info: info, flags: TelegramChannelFlags(), restrictionInfo: nil, adminRights: nil, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: untilDate ?? Int32.max), defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil) } } @@ -202,7 +202,7 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? { switch rhs { case .chat, .chatEmpty, .chatForbidden, .channelForbidden: return parseTelegramGroupOrChannel(chat: rhs) - case let .channel(flags, flags2, _, accessHash, title, username, photo, _, _, _, _, defaultBannedRights, _, usernames, _, color, profileColor, emojiStatus, boostLevel, subscriptionUntilDate, verificationIconFileId, sendPaidMessageStars): + case let .channel(flags, flags2, _, accessHash, title, username, photo, _, _, _, _, defaultBannedRights, _, usernames, _, color, profileColor, emojiStatus, boostLevel, subscriptionUntilDate, verificationIconFileId, sendPaidMessageStars, linkedMonoforumIdValue): let isMin = (flags & (1 << 12)) != 0 if accessHash != nil && !isMin { return parseTelegramGroupOrChannel(chat: rhs) @@ -266,7 +266,9 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? { let parsedEmojiStatus = emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)) - return TelegramChannel(id: lhs.id, accessHash: lhs.accessHash, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: lhs.creationDate, version: lhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: lhs.restrictionInfo, adminRights: lhs.adminRights, bannedRights: lhs.bannedRights, defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColorIndex.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId, profileColor: profileColorIndex.flatMap { PeerNameColor(rawValue: $0) }, profileBackgroundEmojiId: profileBackgroundEmojiId, emojiStatus: parsedEmojiStatus, approximateBoostLevel: boostLevel, subscriptionUntilDate: subscriptionUntilDate, verificationIconFileId: verificationIconFileId, sendPaidMessageStars: sendPaidMessageStars.flatMap { StarsAmount(value: $0, nanos: 0) } ?? lhs.sendPaidMessageStars) + let linkedMonoforumId = linkedMonoforumIdValue.flatMap({ PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value($0)) }) ?? lhs.linkedMonoforumId + + return TelegramChannel(id: lhs.id, accessHash: lhs.accessHash, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: lhs.creationDate, version: lhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: lhs.restrictionInfo, adminRights: lhs.adminRights, bannedRights: lhs.bannedRights, defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColorIndex.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId, profileColor: profileColorIndex.flatMap { PeerNameColor(rawValue: $0) }, profileBackgroundEmojiId: profileBackgroundEmojiId, emojiStatus: parsedEmojiStatus, approximateBoostLevel: boostLevel, subscriptionUntilDate: subscriptionUntilDate, verificationIconFileId: verificationIconFileId, sendPaidMessageStars: sendPaidMessageStars.flatMap { StarsAmount(value: $0, nanos: 0) } ?? lhs.sendPaidMessageStars, linkedMonoforumId: linkedMonoforumId) } else { return parseTelegramGroupOrChannel(chat: rhs) } @@ -320,6 +322,8 @@ func mergeChannel(lhs: TelegramChannel?, rhs: TelegramChannel) -> TelegramChanne let storiesHidden: Bool? = rhs.storiesHidden ?? lhs.storiesHidden - return TelegramChannel(id: lhs.id, accessHash: accessHash, title: rhs.title, username: rhs.username, photo: rhs.photo, creationDate: rhs.creationDate, version: rhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: rhs.restrictionInfo, adminRights: rhs.adminRights, bannedRights: rhs.bannedRights, defaultBannedRights: rhs.defaultBannedRights, usernames: rhs.usernames, storiesHidden: storiesHidden, nameColor: rhs.nameColor, backgroundEmojiId: rhs.backgroundEmojiId, profileColor: rhs.profileColor, profileBackgroundEmojiId: rhs.profileBackgroundEmojiId, emojiStatus: rhs.emojiStatus, approximateBoostLevel: rhs.approximateBoostLevel, subscriptionUntilDate: rhs.subscriptionUntilDate, verificationIconFileId: rhs.verificationIconFileId, sendPaidMessageStars: rhs.sendPaidMessageStars) + let linkedMonoforumId = rhs.linkedMonoforumId ?? lhs.linkedMonoforumId + + return TelegramChannel(id: lhs.id, accessHash: accessHash, title: rhs.title, username: rhs.username, photo: rhs.photo, creationDate: rhs.creationDate, version: rhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: rhs.restrictionInfo, adminRights: rhs.adminRights, bannedRights: rhs.bannedRights, defaultBannedRights: rhs.defaultBannedRights, usernames: rhs.usernames, storiesHidden: storiesHidden, nameColor: rhs.nameColor, backgroundEmojiId: rhs.backgroundEmojiId, profileColor: rhs.profileColor, profileBackgroundEmojiId: rhs.profileBackgroundEmojiId, emojiStatus: rhs.emojiStatus, approximateBoostLevel: rhs.approximateBoostLevel, subscriptionUntilDate: rhs.subscriptionUntilDate, verificationIconFileId: rhs.verificationIconFileId, sendPaidMessageStars: rhs.sendPaidMessageStars, linkedMonoforumId: linkedMonoforumId) } diff --git a/submodules/TelegramCore/Sources/PendingMessages/EnqueueMessage.swift b/submodules/TelegramCore/Sources/PendingMessages/EnqueueMessage.swift index 8c1cf3caaf..360e066bee 100644 --- a/submodules/TelegramCore/Sources/PendingMessages/EnqueueMessage.swift +++ b/submodules/TelegramCore/Sources/PendingMessages/EnqueueMessage.swift @@ -236,8 +236,6 @@ private func filterMessageAttributesForOutgoingMessage(_ attributes: [MessageAtt return true case _ as OutgoingQuickReplyMessageAttribute: return true - case _ as OutgoingSuggestedPostMessageAttribute: - return true case _ as EmbeddedMediaStickersMessageAttribute: return true case _ as EmojiSearchQueryMessageAttribute: @@ -277,8 +275,6 @@ private func filterMessageAttributesForForwardedMessage(_ attributes: [MessageAt return true case _ as OutgoingQuickReplyMessageAttribute: return true - case _ as OutgoingSuggestedPostMessageAttribute: - return true case _ as ForwardOptionsMessageAttribute: return true case _ as SendAsMessageAttribute: @@ -502,6 +498,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId, } } } + switch message { case let .message(_, attributes, _, _, threadId, replyToMessageId, _, _, _, _): if let replyToMessageId = replyToMessageId, (replyToMessageId.messageId.peerId != peerId && peerId.namespace == Namespaces.Peer.SecretChat), let replyMessage = transaction.getMessage(replyToMessageId.messageId) { @@ -737,9 +734,6 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId, } else if attribute is OutgoingQuickReplyMessageAttribute { messageNamespace = Namespaces.Message.QuickReplyLocal effectiveTimestamp = 0 - } else if attribute is OutgoingSuggestedPostMessageAttribute { - messageNamespace = Namespaces.Message.SuggestedPostLocal - effectiveTimestamp = 0 } else if let attribute = attribute as? SendAsMessageAttribute { if let peer = transaction.getPeer(attribute.peerId) { sendAsPeer = peer @@ -776,9 +770,6 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId, if messageNamespace != Namespaces.Message.QuickReplyLocal { attributes.removeAll(where: { $0 is OutgoingQuickReplyMessageAttribute }) } - if messageNamespace != Namespaces.Message.SuggestedPostLocal { - attributes.removeAll(where: { $0 is OutgoingSuggestedPostMessageAttribute }) - } if let peer = peer as? TelegramChannel { switch peer.info { @@ -1013,9 +1004,6 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId, } else if attribute is OutgoingQuickReplyMessageAttribute { messageNamespace = Namespaces.Message.QuickReplyLocal effectiveTimestamp = 0 - } else if attribute is OutgoingSuggestedPostMessageAttribute { - messageNamespace = Namespaces.Message.SuggestedPostLocal - effectiveTimestamp = 0 } else if let attribute = attribute as? ReplyMessageAttribute { if let threadMessageId = attribute.threadMessageId { threadId = Int64(threadMessageId.id) @@ -1048,9 +1036,6 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId, if messageNamespace != Namespaces.Message.QuickReplyLocal { attributes.removeAll(where: { $0 is OutgoingQuickReplyMessageAttribute }) } - if messageNamespace != Namespaces.Message.SuggestedPostLocal { - attributes.removeAll(where: { $0 is OutgoingSuggestedPostMessageAttribute }) - } let (tags, globalTags) = tagsForStoreMessage(incoming: false, attributes: attributes, media: sourceMessage.media, textEntities: entitiesAttribute?.entities, isPinned: false) diff --git a/submodules/TelegramCore/Sources/PendingMessages/RequestEditMessage.swift b/submodules/TelegramCore/Sources/PendingMessages/RequestEditMessage.swift index eaf279d18e..398ddb9e9c 100644 --- a/submodules/TelegramCore/Sources/PendingMessages/RequestEditMessage.swift +++ b/submodules/TelegramCore/Sources/PendingMessages/RequestEditMessage.swift @@ -179,9 +179,6 @@ private func requestEditMessageInternal(accountPeerId: PeerId, postbox: Postbox, if messageId.namespace == Namespaces.Message.QuickReplyCloud { quickReplyShortcutId = Int32(clamping: message.threadId ?? 0) flags |= Int32(1 << 17) - } else if messageId.namespace == Namespaces.Message.SuggestedPostLocal { - //TODO:release - preconditionFailure() } return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, media: inputMedia, replyMarkup: nil, entities: apiEntities, scheduleDate: effectiveScheduleTime, quickReplyShortcutId: quickReplyShortcutId)) diff --git a/submodules/TelegramCore/Sources/PendingMessages/StandaloneSendMessage.swift b/submodules/TelegramCore/Sources/PendingMessages/StandaloneSendMessage.swift index 057b989653..39add91411 100644 --- a/submodules/TelegramCore/Sources/PendingMessages/StandaloneSendMessage.swift +++ b/submodules/TelegramCore/Sources/PendingMessages/StandaloneSendMessage.swift @@ -475,7 +475,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, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), 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, sendAs: sendAsInputPeer, quickReplyShortcut: nil, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), tag: dependencyTag) |> map(NetworkRequestResult.result) } else { sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal")) diff --git a/submodules/TelegramCore/Sources/State/AccountViewTracker.swift b/submodules/TelegramCore/Sources/State/AccountViewTracker.swift index 0e11587c6e..e32b516153 100644 --- a/submodules/TelegramCore/Sources/State/AccountViewTracker.swift +++ b/submodules/TelegramCore/Sources/State/AccountViewTracker.swift @@ -72,8 +72,6 @@ private func fetchWebpage(account: Account, messageId: MessageId, threadId: Int6 targetMessageNamespace = Namespaces.Message.ScheduledCloud } else if Namespaces.Message.allQuickReply.contains(messageId.namespace) { targetMessageNamespace = Namespaces.Message.QuickReplyCloud - } else if Namespaces.Message.allSuggestedPost.contains(messageId.namespace) { - targetMessageNamespace = Namespaces.Message.SuggestedPostCloud } else { targetMessageNamespace = Namespaces.Message.Cloud } @@ -1073,10 +1071,6 @@ public final class AccountViewTracker { } else { fetchSignal = .never() } - } else if let messageId = messageIds.first, messageId.namespace == Namespaces.Message.SuggestedPostCloud { - //TODO:release - assertionFailure() - fetchSignal = .never() } else if peerIdAndThreadId.peerId.namespace == Namespaces.Peer.CloudUser || peerIdAndThreadId.peerId.namespace == Namespaces.Peer.CloudGroup { fetchSignal = account.network.request(Api.functions.messages.getMessages(id: messageIds.map { Api.InputMessage.inputMessageID(id: $0.id) })) } else if peerIdAndThreadId.peerId.namespace == Namespaces.Peer.CloudChannel { @@ -2126,36 +2120,6 @@ public final class AccountViewTracker { } return signal } - - public func postSuggestionsViewForLocation(peerId: EnginePeer.Id, additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> { - guard let account = self.account else { - return .never() - } - let chatLocation: ChatLocationInput = .peer(peerId: peerId, threadId: nil) - let signal = account.postbox.aroundMessageHistoryViewForLocation(chatLocation, anchor: .upperBound, ignoreMessagesInTimestampRange: nil, ignoreMessageIds: Set(), count: 200, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tag: nil, appendMessagesFromTheSameGroup: false, namespaces: .just(Namespaces.Message.allSuggestedPost), orderStatistics: [], additionalData: additionalData) - return withState(signal, { [weak self] () -> Int32 in - if let strongSelf = self { - return OSAtomicIncrement32(&strongSelf.nextViewId) - } else { - return -1 - } - }, next: { [weak self] next, viewId in - if let strongSelf = self { - strongSelf.queue.async { - let (messageIds, localWebpages) = pendingWebpages(entries: next.0.entries) - strongSelf.updatePendingWebpages(viewId: viewId, threadId: nil, messageIds: messageIds, localWebpages: localWebpages) - strongSelf.historyViewStateValidationContexts.updateView(id: viewId, view: next.0, location: chatLocation) - } - } - }, disposed: { [weak self] viewId in - if let strongSelf = self { - strongSelf.queue.async { - strongSelf.updatePendingWebpages(viewId: viewId, threadId: nil, messageIds: [], localWebpages: [:]) - strongSelf.historyViewStateValidationContexts.updateView(id: viewId, view: nil, location: nil) - } - } - }) - } public func aroundMessageOfInterestHistoryViewForLocation(_ chatLocation: ChatLocationInput, ignoreMessagesInTimestampRange: ClosedRange? = nil, ignoreMessageIds: Set = Set(), count: Int, tag: HistoryViewInputTag? = nil, appendMessagesFromTheSameGroup: Bool = false, orderStatistics: MessageHistoryViewOrderStatistics = [], additionalData: [AdditionalMessageHistoryViewData] = [], useRootInterfaceStateForThread: Bool = false) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> { if let account = self.account { diff --git a/submodules/TelegramCore/Sources/State/ApplyUpdateMessage.swift b/submodules/TelegramCore/Sources/State/ApplyUpdateMessage.swift index d0b2dc5fa0..3507b5eda5 100644 --- a/submodules/TelegramCore/Sources/State/ApplyUpdateMessage.swift +++ b/submodules/TelegramCore/Sources/State/ApplyUpdateMessage.swift @@ -198,14 +198,6 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes } } } - if Namespaces.Message.allSuggestedPost.contains(message.id.namespace) { - for i in 0 ..< updatedAttributes.count { - if updatedAttributes[i] is OutgoingSuggestedPostMessageAttribute { - updatedAttributes.remove(at: i) - break - } - } - } attributes = updatedAttributes text = currentMessage.text @@ -228,8 +220,6 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes } if Namespaces.Message.allQuickReply.contains(message.id.namespace) { namespace = Namespaces.Message.QuickReplyCloud - } else if Namespaces.Message.allSuggestedPost.contains(message.id.namespace) { - namespace = Namespaces.Message.SuggestedPostCloud } else if let updatedTimestamp = updatedTimestamp { if attributes.contains(where: { $0 is PendingProcessingMessageAttribute }) { namespace = Namespaces.Message.ScheduledCloud @@ -253,8 +243,6 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes if let threadId { _internal_applySentQuickReplyMessage(transaction: transaction, shortcut: attribute.shortcut, quickReplyId: Int32(clamping: threadId)) } - } else if attribute is OutgoingSuggestedPostMessageAttribute { - //TODO:release } } @@ -409,8 +397,6 @@ func applyUpdateGroupMessages(postbox: Postbox, stateManager: AccountStateManage var namespace = Namespaces.Message.Cloud if Namespaces.Message.allQuickReply.contains(messages[0].id.namespace) { namespace = Namespaces.Message.QuickReplyCloud - } else if Namespaces.Message.allSuggestedPost.contains(messages[0].id.namespace) { - namespace = Namespaces.Message.SuggestedPostCloud } else if let message = messages.first, let apiMessage = result.messages.first { if message.scheduleTime != nil && message.scheduleTime == apiMessage.timestamp { namespace = Namespaces.Message.ScheduledCloud @@ -488,8 +474,6 @@ func applyUpdateGroupMessages(postbox: Postbox, stateManager: AccountStateManage if let threadId = updatedMessage.threadId { _internal_applySentQuickReplyMessage(transaction: transaction, shortcut: attribute.shortcut, quickReplyId: Int32(clamping: threadId)) } - } else if attribute is OutgoingSuggestedPostMessageAttribute { - //TODO:release } } } diff --git a/submodules/TelegramCore/Sources/State/CloudChatRemoveMessagesOperation.swift b/submodules/TelegramCore/Sources/State/CloudChatRemoveMessagesOperation.swift index 1ace711069..acf9a30261 100644 --- a/submodules/TelegramCore/Sources/State/CloudChatRemoveMessagesOperation.swift +++ b/submodules/TelegramCore/Sources/State/CloudChatRemoveMessagesOperation.swift @@ -35,25 +35,6 @@ func cloudChatAddClearHistoryOperation(transaction: Transaction, peerId: PeerId, } else if case .forEveryone = type { transaction.operationLogAddEntry(peerId: peerId, tag: OperationLogTags.CloudChatRemoveMessages, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: CloudChatClearHistoryOperation(peerId: peerId, topMessageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: .max), threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type)) } - } else if type == .suggestedPostMessages { - var messageIds: [MessageId] = [] - transaction.withAllMessages(peerId: peerId, namespace: Namespaces.Message.SuggestedPostCloud) { message -> Bool in - messageIds.append(message.id) - return true - } - cloudChatAddRemoveMessagesOperation(transaction: transaction, peerId: peerId, threadId: threadId, messageIds: messageIds, type: .forLocalPeer) - - let topMessageId: MessageId? - if let explicitTopMessageId = explicitTopMessageId { - topMessageId = explicitTopMessageId - } else { - topMessageId = transaction.getTopPeerMessageId(peerId: peerId, namespace: Namespaces.Message.SuggestedPostCloud) - } - if let topMessageId = topMessageId { - transaction.operationLogAddEntry(peerId: peerId, tag: OperationLogTags.CloudChatRemoveMessages, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: CloudChatClearHistoryOperation(peerId: peerId, topMessageId: topMessageId, threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type)) - } else if case .forEveryone = type { - transaction.operationLogAddEntry(peerId: peerId, tag: OperationLogTags.CloudChatRemoveMessages, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: CloudChatClearHistoryOperation(peerId: peerId, topMessageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: .max), threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type)) - } } else { let topMessageId: MessageId? if let explicitTopMessageId = explicitTopMessageId { diff --git a/submodules/TelegramCore/Sources/State/ManagedCloudChatRemoveMessagesOperations.swift b/submodules/TelegramCore/Sources/State/ManagedCloudChatRemoveMessagesOperations.swift index b520f4ba7f..18743c8450 100644 --- a/submodules/TelegramCore/Sources/State/ManagedCloudChatRemoveMessagesOperations.swift +++ b/submodules/TelegramCore/Sources/State/ManagedCloudChatRemoveMessagesOperations.swift @@ -128,7 +128,6 @@ func managedCloudChatRemoveMessagesOperations(postbox: Postbox, network: Network private func removeMessages(postbox: Postbox, network: Network, stateManager: AccountStateManager, peer: Peer, operation: CloudChatRemoveMessagesOperation) -> Signal { var isScheduled = false var isQuickReply = false - var isSuggestedPost = false for id in operation.messageIds { if id.namespace == Namespaces.Message.ScheduledCloud { isScheduled = true @@ -136,9 +135,6 @@ private func removeMessages(postbox: Postbox, network: Network, stateManager: Ac } else if id.namespace == Namespaces.Message.QuickReplyCloud { isQuickReply = true break - } else if id.namespace == Namespaces.Message.SuggestedPostCloud { - isSuggestedPost = true - break } } @@ -194,10 +190,6 @@ private func removeMessages(postbox: Postbox, network: Network, stateManager: Ac } else { return .complete() } - } else if isSuggestedPost { - //TODO:release - assertionFailure() - return .complete() } else if peer.id.namespace == Namespaces.Peer.CloudChannel { if let inputChannel = apiInputChannel(peer) { var signal: Signal = .complete() diff --git a/submodules/TelegramCore/Sources/State/PendingMessageManager.swift b/submodules/TelegramCore/Sources/State/PendingMessageManager.swift index 20f4471981..5bb2814a5d 100644 --- a/submodules/TelegramCore/Sources/State/PendingMessageManager.swift +++ b/submodules/TelegramCore/Sources/State/PendingMessageManager.swift @@ -858,15 +858,11 @@ public final class PendingMessageManager { var videoTimestamp: Int32? var sendAsPeerId: PeerId? var quickReply: OutgoingQuickReplyMessageAttribute? - var suggestedPost: OutgoingSuggestedPostMessageAttribute? var messageEffect: EffectMessageAttribute? var allowPaidStars: Int64? var flags: Int32 = 0 - //TODO:release - let _ = suggestedPost - for attribute in messages[0].0.attributes { if let replyAttribute = attribute as? ReplyMessageAttribute { replyMessageId = replyAttribute.messageId.id @@ -894,8 +890,6 @@ public final class PendingMessageManager { sendAsPeerId = attribute.peerId } else if let attribute = attribute as? OutgoingQuickReplyMessageAttribute { quickReply = attribute - } else if let attribute = attribute as? OutgoingSuggestedPostMessageAttribute { - suggestedPost = attribute } else if let attribute = attribute as? EffectMessageAttribute { messageEffect = attribute } else if let _ = attribute as? InvertMediaMessageAttribute { @@ -978,7 +972,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, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), 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: nil, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), tag: dependencyTag) } else { assertionFailure() sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "Invalid forward source")) @@ -1631,7 +1625,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, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), 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, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), tag: dependencyTag) |> map(NetworkRequestResult.result) } else { sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal")) @@ -1846,8 +1840,6 @@ public final class PendingMessageManager { targetNamespace = Namespaces.Message.ScheduledCloud } else if Namespaces.Message.allQuickReply.contains(message.id.namespace) { targetNamespace = Namespaces.Message.QuickReplyCloud - } else if Namespaces.Message.allSuggestedPost.contains(message.id.namespace) { - targetNamespace = Namespaces.Message.SuggestedPostCloud } else { targetNamespace = Namespaces.Message.Cloud } @@ -1899,8 +1891,6 @@ public final class PendingMessageManager { if let message = messages.first { if message.id.namespace == Namespaces.Message.QuickReplyLocal { namespace = Namespaces.Message.QuickReplyCloud - } else if Namespaces.Message.allSuggestedPost.contains(message.id.namespace) { - namespace = Namespaces.Message.SuggestedPostCloud } else if let apiMessage = result.messages.first, message.scheduleTime != nil && message.scheduleTime == apiMessage.timestamp { namespace = Namespaces.Message.ScheduledCloud } else if let apiMessage = result.messages.first, case let .message(_, flags2, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) = apiMessage, (flags2 & (1 << 4)) != 0 { diff --git a/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift b/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift index 567c925585..d3084d9975 100644 --- a/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift +++ b/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift @@ -186,7 +186,7 @@ extension Api.Chat { return PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)) case let .chatForbidden(id, _): return PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)) - case let .channel(_, _, id, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _): + case let .channel(_, _, id, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _): return PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)) case let .channelForbidden(_, id, _, _, _): return PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)) diff --git a/submodules/TelegramCore/Sources/SyncCore/SuggestedPostMessageAttribute.swift b/submodules/TelegramCore/Sources/SyncCore/SuggestedPostMessageAttribute.swift deleted file mode 100644 index b442c2d157..0000000000 --- a/submodules/TelegramCore/Sources/SyncCore/SuggestedPostMessageAttribute.swift +++ /dev/null @@ -1,37 +0,0 @@ -import Foundation -import Postbox -import TelegramApi - -public final class OutgoingSuggestedPostMessageAttribute: Equatable, MessageAttribute { - public let price: StarsAmount - public let timestamp: Int32? - - public init(price: StarsAmount, timestamp: Int32?) { - self.price = price - self.timestamp = timestamp - } - - required public init(decoder: PostboxDecoder) { - self.price = decoder.decodeCodable(StarsAmount.self, forKey: "s") ?? StarsAmount(value: 0, nanos: 0) - self.timestamp = decoder.decodeOptionalInt32ForKey("t") - } - - public func encode(_ encoder: PostboxEncoder) { - encoder.encodeCodable(self.price, forKey: "s") - if let timestamp = self.timestamp { - encoder.encodeInt32(timestamp, forKey: "t") - } else { - encoder.encodeNil(forKey: "t") - } - } - - public static func ==(lhs: OutgoingSuggestedPostMessageAttribute, rhs: OutgoingSuggestedPostMessageAttribute) -> Bool { - if lhs.price != rhs.price { - return false - } - if lhs.timestamp != rhs.timestamp { - return false - } - return true - } -} diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift index a0f999aad1..579e2cc1a1 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedChannelData.swift @@ -247,7 +247,6 @@ public final class CachedChannelData: CachedPeerData { public let minAvailableMessageId: MessageId? public let migrationReference: ChannelMigrationReference? public let linkedDiscussionPeerId: LinkedDiscussionPeerId - public let linkedMonoforumPeerId: LinkedDiscussionPeerId public let peerGeoLocation: PeerGeoLocation? public let slowModeTimeout: Int32? public let slowModeValidUntilTimestamp: Int32? @@ -294,7 +293,6 @@ public final class CachedChannelData: CachedPeerData { self.minAvailableMessageId = nil self.migrationReference = nil self.linkedDiscussionPeerId = .unknown - self.linkedMonoforumPeerId = .unknown self.peerGeoLocation = nil self.slowModeTimeout = nil self.slowModeValidUntilTimestamp = nil @@ -334,7 +332,6 @@ public final class CachedChannelData: CachedPeerData { minAvailableMessageId: MessageId?, migrationReference: ChannelMigrationReference?, linkedDiscussionPeerId: LinkedDiscussionPeerId, - linkedMonoforumPeerId: LinkedDiscussionPeerId, peerGeoLocation: PeerGeoLocation?, slowModeTimeout: Int32?, slowModeValidUntilTimestamp: Int32?, @@ -372,7 +369,6 @@ public final class CachedChannelData: CachedPeerData { self.minAvailableMessageId = minAvailableMessageId self.migrationReference = migrationReference self.linkedDiscussionPeerId = linkedDiscussionPeerId - self.linkedMonoforumPeerId = linkedMonoforumPeerId self.peerGeoLocation = peerGeoLocation self.slowModeTimeout = slowModeTimeout self.slowModeValidUntilTimestamp = slowModeValidUntilTimestamp @@ -408,12 +404,6 @@ public final class CachedChannelData: CachedPeerData { peerIds.insert(linkedDiscussionPeerIdValue) } } - - if case let .known(linkedMonoforumPeerIdValue) = linkedMonoforumPeerId { - if let linkedMonoforumPeerIdValue = linkedMonoforumPeerIdValue { - peerIds.insert(linkedMonoforumPeerIdValue) - } - } if let invitedBy = invitedBy { peerIds.insert(invitedBy) @@ -430,151 +420,147 @@ public final class CachedChannelData: CachedPeerData { } public func withUpdatedIsNotAccessible(_ isNotAccessible: Bool) -> CachedChannelData { - return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedFlags(_ flags: CachedChannelFlags) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedAbout(_ about: String?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedParticipantsSummary(_ participantsSummary: CachedChannelParticipantsSummary) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedStickerPack(_ stickerPack: StickerPackCollectionInfo?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedMinAvailableMessageId(_ minAvailableMessageId: MessageId?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedMigrationReference(_ migrationReference: ChannelMigrationReference?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedLinkedDiscussionPeerId(_ linkedDiscussionPeerId: LinkedDiscussionPeerId) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) - } - - public func withUpdatedLinkedMonoforumPeerId(_ linkedMonoforumPeerId: LinkedDiscussionPeerId) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedSlowModeTimeout(_ slowModeTimeout: Int32?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedSlowModeValidUntilTimestamp(_ slowModeValidUntilTimestamp: Int32?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedStatsDatacenterId(_ statsDatacenterId: Int32) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedInvitedBy(_ invitedBy: PeerId?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedInvitedOn(_ invitedOn: Int32?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedPhoto(_ photo: TelegramMediaImage?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedActiveCall(_ activeCall: ActiveCall?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedCallJoinPeerId(_ callJoinPeerId: PeerId?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedAutoremoveTimeout(_ autoremoveTimeout: CachedPeerAutoremoveTimeout) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: autoremoveTimeout, pendingSuggestions: self.pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedPendingSuggestions(_ pendingSuggestions: [String]) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedThemeEmoticon(_ themeEmoticon: String?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedInviteRequestsPending(_ inviteRequestsPending: Int32?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedSendAsPeerId(_ sendAsPeerId: PeerId?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedReactionSettings(_ reactionSettings: EnginePeerCachedInfoItem) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedMembersHidden(_ membersHidden: EnginePeerCachedInfoItem) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedViewForumAsMessages(_ viewForumAsMessages: EnginePeerCachedInfoItem) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedWallpaper(_ wallpaper: TelegramWallpaper?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedBoostsToUnrestrict(_ boostsToUnrestrict: Int32?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedAppliedBoosts(_ appliedBoosts: Int32?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedEmojiPack(_ emojiPack: StickerPackCollectionInfo?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: emojiPack, verification: self.verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedVerification(_ verification: PeerVerification?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: verification, starGiftsCount: self.starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: verification, starGiftsCount: self.starGiftsCount) } public func withUpdatedStarGiftsCount(_ starGiftsCount: Int32?) -> CachedChannelData { - return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, linkedMonoforumPeerId: self.linkedMonoforumPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: starGiftsCount) + return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, invitedOn: self.invitedOn, photo: self.photo, activeCall: self.activeCall, callJoinPeerId: self.callJoinPeerId, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions, themeEmoticon: self.themeEmoticon, inviteRequestsPending: self.inviteRequestsPending, sendAsPeerId: self.sendAsPeerId, reactionSettings: self.reactionSettings, membersHidden: self.membersHidden, viewForumAsMessages: self.viewForumAsMessages, wallpaper: self.wallpaper, boostsToUnrestrict: self.boostsToUnrestrict, appliedBoosts: self.appliedBoosts, emojiPack: self.emojiPack, verification: self.verification, starGiftsCount: starGiftsCount) } public init(decoder: PostboxDecoder) { @@ -635,16 +621,6 @@ public final class CachedChannelData: CachedPeerData { self.linkedDiscussionPeerId = .unknown } - if let linkedMonoforumPeerId = decoder.decodeOptionalInt64ForKey("monfrmi") { - if linkedMonoforumPeerId == 0 { - self.linkedMonoforumPeerId = .known(nil) - } else { - self.linkedMonoforumPeerId = .known(PeerId(linkedMonoforumPeerId)) - } - } else { - self.linkedMonoforumPeerId = .unknown - } - if let peerGeoLocation = decoder.decodeObjectForKey("pgl", decoder: { PeerGeoLocation(decoder: $0) }) as? PeerGeoLocation { self.peerGeoLocation = peerGeoLocation } else { @@ -705,12 +681,6 @@ public final class CachedChannelData: CachedPeerData { peerIds.insert(linkedDiscussionPeerIdValue) } } - - if case let .known(linkedMonoforumPeerIdValue) = self.linkedMonoforumPeerId { - if let linkedMonoforumPeerIdValue = linkedMonoforumPeerIdValue { - peerIds.insert(linkedMonoforumPeerIdValue) - } - } self.boostsToUnrestrict = decoder.decodeOptionalInt32ForKey("bu") @@ -806,17 +776,6 @@ public final class CachedChannelData: CachedPeerData { encoder.encodeInt64(0, forKey: "dgi") } } - - switch self.linkedMonoforumPeerId { - case .unknown: - encoder.encodeNil(forKey: "monfrmi") - case let .known(value): - if let value = value { - encoder.encodeInt64(value.toInt64(), forKey: "monfrmi") - } else { - encoder.encodeInt64(0, forKey: "monfrmi") - } - } if let peerGeoLocation = self.peerGeoLocation { encoder.encodeObject(peerGeoLocation, forKey: "pgl") @@ -951,10 +910,6 @@ public final class CachedChannelData: CachedPeerData { return false } - if other.linkedMonoforumPeerId != self.linkedMonoforumPeerId { - return false - } - if other.about != self.about { return false } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CloudChatRemoveMessagesOperation.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CloudChatRemoveMessagesOperation.swift index f3a5be61bf..41e23ccdcf 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CloudChatRemoveMessagesOperation.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CloudChatRemoveMessagesOperation.swift @@ -97,7 +97,6 @@ public enum CloudChatClearHistoryType: Int32 { case forEveryone case scheduledMessages case quickReplyMessages - case suggestedPostMessages } public enum InteractiveHistoryClearingType: Int32 { diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift index ad26500ad9..f4e68f4760 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift @@ -10,13 +10,10 @@ public struct Namespaces { public static let ScheduledLocal: Int32 = 4 public static let QuickReplyCloud: Int32 = 5 public static let QuickReplyLocal: Int32 = 6 - public static let SuggestedPostLocal: Int32 = 7 - public static let SuggestedPostCloud: Int32 = 8 public static let allScheduled: Set = Set([Namespaces.Message.ScheduledCloud, Namespaces.Message.ScheduledLocal]) public static let allQuickReply: Set = Set([Namespaces.Message.QuickReplyCloud, Namespaces.Message.QuickReplyLocal]) - public static let allSuggestedPost: Set = Set([Namespaces.Message.SuggestedPostCloud, Namespaces.Message.SuggestedPostLocal]) - public static let allNonRegular: Set = Set([Namespaces.Message.ScheduledCloud, Namespaces.Message.ScheduledLocal, Namespaces.Message.QuickReplyCloud, Namespaces.Message.QuickReplyLocal, Namespaces.Message.SuggestedPostCloud, Namespaces.Message.SuggestedPostLocal]) + public static let allNonRegular: Set = Set([Namespaces.Message.ScheduledCloud, Namespaces.Message.ScheduledLocal, Namespaces.Message.QuickReplyCloud, Namespaces.Message.QuickReplyLocal]) public static let allLocal: [Int32] = [ Namespaces.Message.Local, Namespaces.Message.SecretIncoming, diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift index 198dfaaea5..a9b229dbb3 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift @@ -212,6 +212,7 @@ public final class TelegramChannel: Peer, Equatable { public let subscriptionUntilDate: Int32? public let verificationIconFileId: Int64? public let sendPaidMessageStars: StarsAmount? + public let linkedMonoforumId: PeerId? public var indexName: PeerIndexNameRepresentation { var addressNames = self.usernames.map { $0.username } @@ -284,7 +285,8 @@ public final class TelegramChannel: Peer, Equatable { approximateBoostLevel: Int32?, subscriptionUntilDate: Int32?, verificationIconFileId: Int64?, - sendPaidMessageStars: StarsAmount? + sendPaidMessageStars: StarsAmount?, + linkedMonoforumId: PeerId? ) { self.id = id self.accessHash = accessHash @@ -311,6 +313,7 @@ public final class TelegramChannel: Peer, Equatable { self.subscriptionUntilDate = subscriptionUntilDate self.verificationIconFileId = verificationIconFileId self.sendPaidMessageStars = sendPaidMessageStars + self.linkedMonoforumId = linkedMonoforumId } public init(decoder: PostboxDecoder) { @@ -349,6 +352,7 @@ public final class TelegramChannel: Peer, Equatable { self.subscriptionUntilDate = decoder.decodeOptionalInt32ForKey("sud") self.verificationIconFileId = decoder.decodeOptionalInt64ForKey("vfid") self.sendPaidMessageStars = decoder.decodeCodable(StarsAmount.self, forKey: "sendPaidMessageStars") + self.linkedMonoforumId = decoder.decodeOptionalInt64ForKey("lmid").flatMap(PeerId.init) #if DEBUG && false var builder = FlatBufferBuilder(initialSize: 1024) @@ -469,6 +473,12 @@ public final class TelegramChannel: Peer, Equatable { } else { encoder.encodeNil(forKey: "sendPaidMessageStars") } + + if let linkedMonoforumId = self.linkedMonoforumId { + encoder.encodeInt64(linkedMonoforumId.toInt64(), forKey: "lmid") + } else { + encoder.encodeNil(forKey: "lmid") + } } public func isEqual(_ other: Peer) -> Bool { @@ -536,71 +546,74 @@ public final class TelegramChannel: Peer, Equatable { if lhs.sendPaidMessageStars != rhs.sendPaidMessageStars { return false } + if lhs.linkedMonoforumId != rhs.linkedMonoforumId { + return false + } return true } public func withUpdatedAddressName(_ addressName: String?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: addressName, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: addressName, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedAddressNames(_ addressNames: [TelegramPeerUsername]) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: addressNames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: addressNames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedDefaultBannedRights(_ defaultBannedRights: TelegramChatBannedRights?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedFlags(_ flags: TelegramChannelFlags) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedInfo(_ info: TelegramChannelInfo) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedSendPaidMessageStars(_ sendPaidMessageStars: StarsAmount?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedStoriesHidden(_ storiesHidden: Bool?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedNameColor(_ nameColor: PeerNameColor?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedBackgroundEmojiId(_ backgroundEmojiId: Int64?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedProfileColor(_ profileColor: PeerNameColor?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedProfileBackgroundEmojiId(_ profileBackgroundEmojiId: Int64?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedEmojiStatus(_ emojiStatus: PeerEmojiStatus?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedApproximateBoostLevel(_ approximateBoostLevel: Int32?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedSubscriptionUntilDate(_ subscriptionUntilDate: Int32?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: subscriptionUntilDate, verificationIconFileId: self.verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public func withUpdatedVerificationIconFileId(_ verificationIconFileId: Int64?) -> TelegramChannel { - return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars) + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames, storiesHidden: self.storiesHidden, nameColor: self.nameColor, backgroundEmojiId: self.backgroundEmojiId, profileColor: self.profileColor, profileBackgroundEmojiId: self.profileBackgroundEmojiId, emojiStatus: self.emojiStatus, approximateBoostLevel: self.approximateBoostLevel, subscriptionUntilDate: self.subscriptionUntilDate, verificationIconFileId: verificationIconFileId, sendPaidMessageStars: self.sendPaidMessageStars, linkedMonoforumId: self.linkedMonoforumId) } public init(flatBuffersObject: TelegramCore_TelegramChannel) throws { - self.id = PeerId(flatBuffersObject.id) + self.id = PeerId(flatBuffersObject: flatBuffersObject.id) self.accessHash = try flatBuffersObject.accessHash.flatMap(TelegramPeerAccessHash.init) self.title = flatBuffersObject.title self.username = flatBuffersObject.username @@ -630,6 +643,7 @@ public final class TelegramChannel: Peer, Equatable { self.subscriptionUntilDate = flatBuffersObject.subscriptionUntilDate == Int32.min ? nil : flatBuffersObject.subscriptionUntilDate self.verificationIconFileId = flatBuffersObject.verificationIconFileId == Int64.min ? nil : flatBuffersObject.verificationIconFileId self.sendPaidMessageStars = try flatBuffersObject.sendPaidMessageStars.flatMap { try StarsAmount(flatBuffersObject: $0) } + self.linkedMonoforumId = flatBuffersObject.linkedMonoforumId.flatMap { PeerId(flatBuffersObject: $0) } } public func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset { @@ -707,6 +721,9 @@ public final class TelegramChannel: Peer, Equatable { if let sendPaidMessageStarsOffset { TelegramCore_TelegramChannel.add(sendPaidMessageStars: sendPaidMessageStarsOffset, &builder) } + if let linkedMonoforumId = self.linkedMonoforumId { + TelegramCore_TelegramChannel.add(linkedMonoforumId: linkedMonoforumId.asFlatBuffersObject(), &builder) + } return TelegramCore_TelegramChannel.endTelegramChannel(&builder, start: start) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift b/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift index 9305c7bb19..c566470e1e 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift @@ -2784,7 +2784,7 @@ func _internal_groupCallDisplayAsAvailablePeers(accountPeerId: PeerId, network: for chat in chats { if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) { switch chat { - case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _): + case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _): if let participantsCount = participantsCount { subscribers[groupOrChannel.id] = participantsCount } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift index 79ba26f8c4..8ae0883f6a 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift @@ -861,39 +861,6 @@ public extension TelegramEngine.EngineData.Item { } } - public struct LinkedMonoforumPeerId: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { - public typealias Result = EnginePeerCachedInfoItem - - fileprivate var id: EnginePeer.Id - public var mapKey: EnginePeer.Id { - return self.id - } - - public init(id: EnginePeer.Id) { - self.id = id - } - - var key: PostboxViewKey { - return .cachedPeerData(peerId: self.id) - } - - func extract(view: PostboxView) -> Result { - guard let view = view as? CachedPeerDataView else { - preconditionFailure() - } - if let cachedData = view.cachedPeerData as? CachedChannelData { - switch cachedData.linkedMonoforumPeerId { - case let .known(value): - return .known(value) - case .unknown: - return .unknown - } - } else { - return .unknown - } - } - } - public struct StatusSettings: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { public typealias Result = EnginePeer.StatusSettings? diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift index 7c2f4db14b..17c015060b 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift @@ -243,7 +243,8 @@ private class AdMessagesHistoryContextImpl { approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, - sendPaidMessageStars: nil + sendPaidMessageStars: nil, + linkedMonoforumId: nil ) messagePeers[author.id] = author diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ForwardGame.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ForwardGame.swift index 826ea9caf5..2a6677042f 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ForwardGame.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ForwardGame.swift @@ -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) }, scheduleDate: nil, sendAs: sendAsInputPeer, quickReplyShortcut: nil, videoTimestamp: nil, allowPaidStars: 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, sendAs: sendAsInputPeer, quickReplyShortcut: nil, videoTimestamp: nil, allowPaidStars: nil)) |> map(Optional.init) |> `catch` { _ -> Signal in return .single(nil) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift index 0f662c36e9..1b86cc4619 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift @@ -701,9 +701,6 @@ func fetchRemoteMessage(accountPeerId: PeerId, postbox: Postbox, source: FetchMe } else { signal = .never() } - } else if id.namespace == Namespaces.Message.SuggestedPostCloud { - //TODO:release - signal = .never() } else if id.peerId.namespace == Namespaces.Peer.CloudChannel { if let channel = peer.inputChannel { signal = source.request(Api.functions.channels.getMessages(channel: channel, id: [Api.InputMessage.inputMessageID(id: id.id)])) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SendAsPeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SendAsPeers.swift index 01422837b6..63405e9f01 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SendAsPeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SendAsPeers.swift @@ -145,7 +145,7 @@ func _internal_peerSendAsAvailablePeers(accountPeerId: PeerId, network: Network, for chat in chats { if let groupOrChannel = parsedPeers.get(chat.peerId) { switch chat { - case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _): + case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _): if let participantsCount = participantsCount { subscribers[groupOrChannel.id] = participantsCount } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AdPeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AdPeers.swift index 8348bd03aa..d9b889c647 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AdPeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AdPeers.swift @@ -58,7 +58,7 @@ func _internal_searchAdPeers(account: Account, query: String) -> Signal<[AdPeer] for chat in chats { if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) { switch chat { - case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _): + case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _): if let participantsCount = participantsCount { subscribers[groupOrChannel.id] = participantsCount } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddressNames.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddressNames.swift index 48d063ef92..83ee999036 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddressNames.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddressNames.swift @@ -561,7 +561,7 @@ func _internal_adminedPublicChannels(account: Account, scope: AdminedPublicChann case let .chats(apiChats): chats = apiChats for chat in apiChats { - if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _) = chat { + if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _) = chat { subscriberCounts[chat.peerId] = participantsCount.flatMap(Int.init) } } @@ -637,7 +637,7 @@ func _internal_channelsForStories(account: Account) -> Signal<[Peer], NoError> { if let peer = transaction.getPeer(chat.peerId) { peers.append(peer) - if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _) = chat, let participantsCount = participantsCount { + if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _) = chat, let participantsCount = participantsCount { transaction.updatePeerCachedData(peerIds: Set([peer.id]), update: { _, current in var current = current as? CachedChannelData ?? CachedChannelData() var participantsSummary = current.participantsSummary @@ -699,7 +699,7 @@ func _internal_channelsForPublicReaction(account: Account, useLocalCache: Bool) if let peer = transaction.getPeer(chat.peerId) { peers.append(peer) - if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _) = chat, let participantsCount = participantsCount { + if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _) = chat, let participantsCount = participantsCount { transaction.updatePeerCachedData(peerIds: Set([peer.id]), update: { _, current in var current = current as? CachedChannelData ?? CachedChannelData() var participantsSummary = current.participantsSummary diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelRecommendation.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelRecommendation.swift index 1ae086b2d9..0a4b1afec5 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelRecommendation.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelRecommendation.swift @@ -117,7 +117,7 @@ func _internal_requestRecommendedChannels(account: Account, peerId: EnginePeer.I for chat in chats { if let peer = transaction.getPeer(chat.peerId) { peers.append(EnginePeer(peer)) - if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _) = chat, let participantsCount = participantsCount { + if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _) = chat, let participantsCount = participantsCount { transaction.updatePeerCachedData(peerIds: Set([peer.id]), update: { _, current in var current = current as? CachedChannelData ?? CachedChannelData() var participantsSummary = current.participantsSummary diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/Communities.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/Communities.swift index 157e1cd8a8..73b408d759 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/Communities.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/Communities.swift @@ -282,7 +282,7 @@ func _internal_checkChatFolderLink(account: Account, slug: String) -> Signal Signal S var memberCounts: [ChatListFiltersState.ChatListFilterUpdates.MemberCount] = [] for chat in chats { - if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _) = chat { + if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _) = chat { if let participantsCount = participantsCount { memberCounts.append(ChatListFiltersState.ChatListFilterUpdates.MemberCount(id: chat.peerId, count: participantsCount)) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/InactiveChannels.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/InactiveChannels.swift index b5d53270c9..71cffeee7b 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/InactiveChannels.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/InactiveChannels.swift @@ -31,7 +31,7 @@ func _internal_inactiveChannelList(network: Network) -> Signal<[InactiveChannel] var participantsCounts: [PeerId: Int32] = [:] for chat in chats { switch chat { - case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCountValue, _, _, _, _, _, _, _, _, _): + case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCountValue, _, _, _, _, _, _, _, _, _, _): if let participantsCountValue = participantsCountValue { participantsCounts[chat.peerId] = participantsCountValue } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/SearchPeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/SearchPeers.swift index 354879cc16..90f1e186bf 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/SearchPeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/SearchPeers.swift @@ -44,7 +44,7 @@ public func _internal_searchPeers(accountPeerId: PeerId, postbox: Postbox, netwo for chat in chats { if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) { switch chat { - case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _): + case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _): if let participantsCount = participantsCount { subscribers[groupOrChannel.id] = participantsCount } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift index 298fc080ab..fe44e869b3 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift @@ -381,7 +381,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee var subscriberCount: Int32? for chat in chats { if chat.peerId == channelPeerId { - if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _) = chat { + if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _) = chat { subscriberCount = participantsCount } } @@ -583,9 +583,6 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee } } } else if let inputChannel = maybePeer.flatMap(apiInputChannel) { - if let channel = maybePeer as? TelegramChannel, channel.flags.contains(.isMonoforum) { - return .single(false) - } let fullChannelSignal = network.request(Api.functions.channels.getFullChannel(channel: inputChannel)) |> map(Optional.init) |> `catch` { error -> Signal in @@ -594,10 +591,17 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee } return .single(nil) } - let participantSignal = network.request(Api.functions.channels.getParticipant(channel: inputChannel, participant: .inputPeerSelf)) - |> map(Optional.init) - |> `catch` { error -> Signal in - return .single(nil) + + + let participantSignal: Signal + if let channel = maybePeer as? TelegramChannel, channel.flags.contains(.isMonoforum) { + participantSignal = .single(nil) + } else { + participantSignal = network.request(Api.functions.channels.getParticipant(channel: inputChannel, participant: .inputPeerSelf)) + |> map(Optional.init) + |> `catch` { error -> Signal in + return .single(nil) + } } return combineLatest(fullChannelSignal, participantSignal) @@ -607,14 +611,14 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee switch result { case let .chatFull(fullChat, chats, users): switch fullChat { - case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, _, _, notifySettings, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _): + case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, _, _, notifySettings, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _): transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)]) case .chatFull: break } switch fullChat { - case let .channelFull(flags, flags2, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, _, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, _, inputCall, ttl, pendingSuggestions, groupcallDefaultJoinAs, themeEmoticon, requestsPending, _, defaultSendAs, allowedReactions, reactionsLimit, _, wallpaper, appliedBoosts, boostsUnrestrict, emojiSet, verification, starGiftsCount, linkedMonoforumId): + case let .channelFull(flags, flags2, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, _, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, _, inputCall, ttl, pendingSuggestions, groupcallDefaultJoinAs, themeEmoticon, requestsPending, _, defaultSendAs, allowedReactions, reactionsLimit, _, wallpaper, appliedBoosts, boostsUnrestrict, emojiSet, verification, starGiftsCount): var channelFlags = CachedChannelFlags() if (flags & (1 << 3)) != 0 { channelFlags.insert(.canDisplayParticipants) @@ -670,13 +674,6 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee } else { linkedDiscussionPeerId = nil } - - let linkedMonoforumPeerId: PeerId? - if let linkedMonoforumId, linkedMonoforumId != 0 { - linkedMonoforumPeerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(Int64(linkedMonoforumId))) - } else { - linkedMonoforumPeerId = nil - } let autoremoveTimeout: CachedPeerAutoremoveTimeout = .known(CachedPeerAutoremoveTimeout.Value(ttl)) @@ -841,7 +838,6 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee .withUpdatedMinAvailableMessageId(minAvailableMessageId) .withUpdatedMigrationReference(migrationReference) .withUpdatedLinkedDiscussionPeerId(.known(linkedDiscussionPeerId)) - .withUpdatedLinkedMonoforumPeerId(.known(linkedMonoforumPeerId)) .withUpdatedPeerGeoLocation(peerGeoLocation) .withUpdatedSlowModeTimeout(slowmodeSeconds) .withUpdatedSlowModeValidUntilTimestamp(slowmodeNextSendDate) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Privacy/UpdatedAccountPrivacySettings.swift b/submodules/TelegramCore/Sources/TelegramEngine/Privacy/UpdatedAccountPrivacySettings.swift index 5a9d7d9b8b..b10afb4e58 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Privacy/UpdatedAccountPrivacySettings.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Privacy/UpdatedAccountPrivacySettings.swift @@ -226,7 +226,7 @@ func _internal_requestAccountPrivacySettings(account: Account) -> Signal UIImage? { return theme.image(PresentationResourceKey.chatFreeNavigateButtonIcon.rawValue, { _ in - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/NavigateToMessageIcon"), color: bubbleVariableColor(variableColor: theme.chat.message.shareButtonForegroundColor, wallpaper: wallpaper)) + return generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: bubbleVariableColor(variableColor: theme.chat.message.shareButtonForegroundColor, wallpaper: wallpaper)) + }) + } + + public static func chatFreeNavigateToThreadButtonIcon(_ theme: PresentationTheme, wallpaper: TelegramWallpaper) -> UIImage? { + return theme.image(PresentationResourceKey.chatFreeNavigateToThreadButtonIcon.rawValue, { _ in + return generateImage(CGSize(width: 8.0, height: 14.0), rotatedContext: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + context.setStrokeColor(bubbleVariableColor(variableColor: theme.chat.message.shareButtonForegroundColor, wallpaper: wallpaper).cgColor) + context.setLineWidth(1.66) + context.setLineCap(.round) + context.setLineJoin(.round) + context.beginPath() + context.move(to: CGPoint(x: 1.0, y: 1.0)) + context.addLine(to: CGPoint(x: size.width - 1.0, y: size.height / 2.0)) + context.addLine(to: CGPoint(x: 1.0, y: size.height - 1.0)) + context.strokePath() + }) }) } diff --git a/submodules/TelegramUI/Components/Chat/ChatEmptyNode/Sources/ChatEmptyNode.swift b/submodules/TelegramUI/Components/Chat/ChatEmptyNode/Sources/ChatEmptyNode.swift index f577d0ffc1..c26c8e5ce1 100644 --- a/submodules/TelegramUI/Components/Chat/ChatEmptyNode/Sources/ChatEmptyNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatEmptyNode/Sources/ChatEmptyNode.swift @@ -781,10 +781,6 @@ private final class ChatEmptyNodeCloudChatContent: ASDisplayNode, ChatEmptyNodeC insets.top = -9.0 imageSpacing = 4.0 titleSpacing = 5.0 - case .postSuggestions: - insets.top = 10.0 - imageSpacing = 5.0 - titleSpacing = 5.0 case .hashTagSearch: break } @@ -846,7 +842,7 @@ private final class ChatEmptyNodeCloudChatContent: ASDisplayNode, ChatEmptyNodeC } self.businessLink = link - case .hashTagSearch, .postSuggestions: + case .hashTagSearch: titleString = "" strings = [] } @@ -1303,10 +1299,7 @@ public final class ChatEmptyNodePremiumRequiredChatContent: ASDisplayNode, ChatE let starsString = presentationStringsFormattedNumber(Int32(amount), interfaceState.dateTimeFormat.groupingSeparator) let rawText: String - if case let .customChatContents(customChatContents) = interfaceState.subject, case .postSuggestions = customChatContents.kind { - //TODO:localize - rawText = "\(peerTitle) charges $ \(starsString) per message suggestion." - } else if self.isPremiumDisabled { + if self.isPremiumDisabled { rawText = interfaceState.strings.Chat_EmptyStatePaidMessagingDisabled_Text(peerTitle, " $ \(starsString)").string } else { rawText = interfaceState.strings.Chat_EmptyStatePaidMessaging_Text(peerTitle, " $ \(starsString)").string @@ -1369,14 +1362,7 @@ public final class ChatEmptyNodePremiumRequiredChatContent: ASDisplayNode, ChatE contentsHeight += iconTextSpacing let iconComponent: AnyComponent - if case let .customChatContents(customChatContents) = interfaceState.subject, case .postSuggestions = customChatContents.kind { - iconComponent = AnyComponent( - BundleIconComponent( - name: "Chat/Empty Chat/PostSuggestions", - tintColor: serviceColor.primaryText - ) - ) - } else { + do { iconComponent = AnyComponent( LottieComponent( content: LottieComponent.AppBundleContent(name: "PremiumRequired"), @@ -1447,7 +1433,6 @@ private enum ChatEmptyNodeContentType: Equatable { case topic case premiumRequired case starsRequired(Int64) - case postSuggestions(Int64) } private final class EmptyAttachedDescriptionNode: HighlightTrackingButtonNode { @@ -1816,12 +1801,8 @@ public final class ChatEmptyNode: ASDisplayNode { case let .emptyChat(emptyType): if case .customGreeting = emptyType { contentType = .greeting - } else if case let .customChatContents(customChatContents) = interfaceState.subject { - if case let .postSuggestions(postSuggestions) = customChatContents.kind { - contentType = .postSuggestions(postSuggestions.value) - } else { - contentType = .cloud - } + } else if case .customChatContents = interfaceState.subject { + contentType = .cloud } else if case .replyThread = interfaceState.chatLocation { if case .topic = emptyType { contentType = .topic @@ -1908,8 +1889,6 @@ public final class ChatEmptyNode: ASDisplayNode { node = ChatEmptyNodePremiumRequiredChatContent(context: self.context, interaction: self.interaction, stars: nil) case let .starsRequired(stars): node = ChatEmptyNodePremiumRequiredChatContent(context: self.context, interaction: self.interaction, stars: stars) - case let .postSuggestions(stars): - node = ChatEmptyNodePremiumRequiredChatContent(context: self.context, interaction: self.interaction, stars: stars) } self.content = (contentType, node) self.addSubnode(node) @@ -1921,7 +1900,7 @@ public final class ChatEmptyNode: ASDisplayNode { } } switch contentType { - case .peerNearby, .greeting, .premiumRequired, .starsRequired, .cloud, .postSuggestions: + case .peerNearby, .greeting, .premiumRequired, .starsRequired, .cloud: self.isUserInteractionEnabled = true default: self.isUserInteractionEnabled = false diff --git a/submodules/TelegramUI/Components/Chat/ChatInputTextNode/ChatInputTextViewImpl/BUILD b/submodules/TelegramUI/Components/Chat/ChatInputTextNode/ChatInputTextViewImpl/BUILD index a588d9c601..7f5eebb851 100644 --- a/submodules/TelegramUI/Components/Chat/ChatInputTextNode/ChatInputTextViewImpl/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatInputTextNode/ChatInputTextViewImpl/BUILD @@ -7,7 +7,7 @@ objc_library( "Sources/**/*.m", "Sources/**/*.c", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageAnimatedStickerItemNode/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageAnimatedStickerItemNode/Sources/ChatMessageAnimatedStickerItemNode.swift index da52aa556f..289c647211 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageAnimatedStickerItemNode/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageAnimatedStickerItemNode/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -801,7 +801,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } } - override public func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { + override public func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: ChatMessageHeaderSpec) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { var displaySize = CGSize(width: 180.0, height: 180.0) let telegramFile = self.telegramFile let emojiFile = self.emojiFile @@ -823,7 +823,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let textLayout = TextNodeWithEntities.asyncLayout(self.textNode) - func continueAsyncLayout(_ weakSelf: Weak, _ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { + func continueAsyncLayout(_ weakSelf: Weak, _ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: ChatMessageHeaderSpec) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { let accessibilityData = ChatMessageAccessibilityData(item: item, isSelected: nil) let layoutConstants = chatMessageItemLayoutConstants(layoutConstants, params: params, presentationData: item.presentationData) let incoming = item.content.effectivelyIncoming(item.context.account.peerId, associatedData: item.associatedData) @@ -1005,8 +1005,15 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } var layoutInsets = UIEdgeInsets(top: mergedTop.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, left: 0.0, bottom: mergedBottom.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, right: 0.0) - if dateHeaderAtBottom { - layoutInsets.top += layoutConstants.timestampHeaderHeight + if dateHeaderAtBottom.hasDate && dateHeaderAtBottom.hasTopic { + layoutInsets.top += layoutConstants.timestampDateAndTopicHeaderHeight + } else { + if dateHeaderAtBottom.hasDate { + layoutInsets.top += layoutConstants.timestampHeaderHeight + } + if dateHeaderAtBottom.hasTopic { + layoutInsets.top += layoutConstants.timestampHeaderHeight + } } var deliveryFailedInset: CGFloat = 0.0 @@ -1377,6 +1384,8 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { strongSelf.appliedForwardInfo = (forwardSource, forwardAuthorSignature) strongSelf.updateAccessibilityData(accessibilityData) + strongSelf.updateAttachedDateHeader(hasDate: dateHeaderAtBottom.hasDate, hasPeer: dateHeaderAtBottom.hasTopic) + strongSelf.messageAccessibilityArea.frame = CGRect(origin: CGPoint(), size: layoutSize) strongSelf.containerNode.frame = CGRect(origin: CGPoint(), size: layoutSize) strongSelf.contextSourceNode.frame = CGRect(origin: CGPoint(), size: layoutSize) @@ -1829,7 +1838,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } let weakSelf = Weak(self) - return { (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) in + return { (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: ChatMessageHeaderSpec) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) in return continueAsyncLayout(weakSelf, item, params, mergedTop, mergedBottom, dateHeaderAtBottom) } } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/BUILD index 4f948fc37e..26f2d17330 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/BUILD @@ -89,6 +89,7 @@ swift_library( "//submodules/TelegramAnimatedStickerNode", "//submodules/TelegramUI/Components/LottieMetal", "//submodules/TelegramStringFormatting", + "//submodules/AvatarNode", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift index 9154d474d5..ac63032d20 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift @@ -78,6 +78,7 @@ import ChatMessageTransitionNode import AnimatedStickerNode import TelegramAnimatedStickerNode import LottieMetal +import AvatarNode private struct BubbleItemAttributes { var index: Int? @@ -629,10 +630,12 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI private var swipeToReplyNode: ChatMessageSwipeToReplyNode? private var swipeToReplyFeedback: HapticFeedback? + private var nameAvatarNode: AvatarNode? private var nameNode: TextNode? private var nameButtonNode: HighlightTrackingButtonNode? private var nameHighlightNode: ASImageNode? private var viaMeasureNode: TextNode? + private var nameNavigateButton: NameNavigateButton? private var adminBadgeNode: TextNode? private var credibilityIconView: ComponentHostView? @@ -725,7 +728,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI private var forceStopAnimations: Bool = false - typealias Params = (item: ChatMessageItem, params: ListViewItemLayoutParams, mergedTop: ChatMessageMerge, mergedBottom: ChatMessageMerge, dateHeaderAtBottom: Bool) + typealias Params = (item: ChatMessageItem, params: ListViewItemLayoutParams, mergedTop: ChatMessageMerge, mergedBottom: ChatMessageMerge, dateHeaderAtBottom: ChatMessageHeaderSpec) private var currentInputParams: Params? private var currentApplyParams: ListViewItemApply? @@ -1391,7 +1394,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } } - override public func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { + override public func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: ChatMessageHeaderSpec) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { var currentContentClassesPropertiesAndLayouts: [(Message, AnyClass, Bool, Int?, (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, CGSize?, CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))))] = [] for contentNode in self.contentNodes { if let message = contentNode.item?.message { @@ -1428,7 +1431,13 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI return { item, params, mergedTop, mergedBottom, dateHeaderAtBottom in let layoutConstants = chatMessageItemLayoutConstants(layoutConstants, params: params, presentationData: item.presentationData) - return ChatMessageBubbleItemNode.beginLayout(selfReference: weakSelf, item, params, mergedTop, mergedBottom, dateHeaderAtBottom, + return ChatMessageBubbleItemNode.beginLayout( + selfReference: weakSelf, + item: item, + params: params, + mergedTop: mergedTop, + mergedBottom: mergedBottom, + dateHeaderAtBottom: dateHeaderAtBottom, currentContentClassesPropertiesAndLayouts: currentContentClassesPropertiesAndLayouts, authorNameLayout: authorNameLayout, viaMeasureLayout: viaMeasureLayout, @@ -1453,11 +1462,11 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI private static func beginLayout( selfReference: Weak, - _ item: ChatMessageItem, - _ params: ListViewItemLayoutParams, - _ mergedTop: ChatMessageMerge, - _ mergedBottom: ChatMessageMerge, - _ dateHeaderAtBottom: Bool, + item: ChatMessageItem, + params: ListViewItemLayoutParams, + mergedTop: ChatMessageMerge, + mergedBottom: ChatMessageMerge, + dateHeaderAtBottom: ChatMessageHeaderSpec, currentContentClassesPropertiesAndLayouts: [(Message, AnyClass, Bool, Int?, (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, CGSize?, CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))))], authorNameLayout: (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode), viaMeasureLayout: (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode), @@ -1479,6 +1488,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI ) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { let isPreview = item.presentationData.isPreview let accessibilityData = ChatMessageAccessibilityData(item: item, isSelected: isSelected) + let isSidePanelOpen = item.controllerInteraction.isSidePanelOpen let fontSize = floor(item.presentationData.fontSize.baseDisplaySize * 14.0 / 17.0) let nameFont = Font.semibold(fontSize) @@ -1579,6 +1589,18 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI if let forwardInfo = firstMessage.forwardInfo, forwardInfo.psaType != nil { displayAuthorInfo = false } + + var isMonoForum = false + if let peer = firstMessage.peers[firstMessage.id.peerId] as? TelegramChannel { + if peer.isMonoForum { + isMonoForum = true + } + } + if isMonoForum { + if case .replyThread = item.chatLocation { + displayAuthorInfo = false + } + } } if let channel = firstMessage.peers[firstMessage.id.peerId] as? TelegramChannel, case let .broadcast(info) = channel.info { @@ -1605,9 +1627,14 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI if !peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { if peerId.isGroupOrChannel && effectiveAuthor != nil { var isBroadcastChannel = false - if let peer = firstMessage.peers[firstMessage.id.peerId] as? TelegramChannel, case .broadcast = peer.info { - isBroadcastChannel = true - allowFullWidth = true + var isMonoForum = false + if let peer = firstMessage.peers[firstMessage.id.peerId] as? TelegramChannel { + if case .broadcast = peer.info { + isBroadcastChannel = true + allowFullWidth = true + } else if peer.isMonoForum { + isMonoForum = true + } } if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.isChannelPost, replyThreadMessage.effectiveTopId == firstMessage.id { @@ -1621,6 +1648,12 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } else if overrideEffectiveAuthor { hasAvatar = true } + + if isMonoForum { + if case .replyThread = item.chatLocation { + hasAvatar = false + } + } } } else if incoming { hasAvatar = true @@ -1651,10 +1684,14 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } avatarInset = hasAvatar ? layoutConstants.avatarDiameter : 0.0 + if isSidePanelOpen { + avatarInset = 0.0 + } let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp()) var needsShareButton = false + if incoming, case let .customChatContents(contents) = item.associatedData.subject, case .hashTagSearch = contents.kind { needsShareButton = true } else if case .pinnedMessages = item.associatedData.subject { @@ -1676,6 +1713,10 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } } else if item.message.id.peerId.isRepliesOrVerificationCodes { needsShareButton = false + } else if let channel = item.content.firstMessage.peers[item.content.firstMessage.id.peerId] as? TelegramChannel, channel.isMonoForum, channel.adminRights != nil, case .peer = item.chatLocation { + if incoming { + needsShareButton = true + } } else if incoming { if let _ = sourceReference { needsShareButton = true @@ -1755,14 +1796,14 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI var tmpWidth: CGFloat if allowFullWidth { tmpWidth = baseWidth - if needsShareButton || isAd { + if (needsShareButton && !isSidePanelOpen) || isAd { tmpWidth -= 45.0 } else { tmpWidth -= 4.0 } } else { tmpWidth = layoutConstants.bubble.maximumWidthFill.widthFor(baseWidth) - if (needsShareButton || isAd) && tmpWidth + 32.0 > baseWidth { + if ((needsShareButton && !isSidePanelOpen) || isAd) && tmpWidth + 32.0 > baseWidth { tmpWidth = baseWidth - 32.0 } } @@ -1777,7 +1818,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI let (contentNodeMessagesAndClasses, needSeparateContainers, needReactions) = contentNodeMessagesAndClassesForItem(item) var maximumContentWidth = floor(tmpWidth - layoutConstants.bubble.edgeInset * 3.0 - layoutConstants.bubble.contentInsets.left - layoutConstants.bubble.contentInsets.right - avatarInset) - if needsShareButton { + if (needsShareButton && !isSidePanelOpen) { maximumContentWidth -= 10.0 } @@ -2387,6 +2428,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI var unlockButtonSizeApply: (CGSize, (Bool) -> ChatMessageUnlockMediaNode?) = (CGSize(), { _ in nil }) var mediaInfoSizeApply: (CGSize, (Bool) -> ChatMessageStarsMediaInfoNode?) = (CGSize(), { _ in nil }) + var hasTitleAvatar = false + if displayHeader { let bubbleWidthInsets: CGFloat = mosaicRange == nil ? layoutConstants.text.bubbleInsets.left + layoutConstants.text.bubbleInsets.right : 0.0 if authorNameString != nil || inlineBotNameString != nil { @@ -2394,6 +2437,10 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI headerSize.height += 7.0 } + if isSidePanelOpen { + hasTitleAvatar = true + } + let inlineBotNameColor = messageTheme.accentTextColor let attributedString: NSAttributedString @@ -2493,8 +2540,15 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } nameNodeOriginY = headerSize.height + + var nameAvatarSpaceWidth: CGFloat = 0.0 + if hasTitleAvatar { + headerSize.height += 12.0 + nameAvatarSpaceWidth += 26.0 + 5.0 + 4.0 + 26.0 + nameNodeOriginY += 5.0 + } - headerSize.width = max(headerSize.width, nameNodeSizeApply.0.width + 8.0 + adminBadgeSizeAndApply.0.size.width + credibilityIconWidth + boostBadgeWidth + closeButtonWidth + bubbleWidthInsets) + headerSize.width = max(headerSize.width, nameAvatarSpaceWidth + nameNodeSizeApply.0.width + 8.0 + adminBadgeSizeAndApply.0.size.width + credibilityIconWidth + boostBadgeWidth + closeButtonWidth + bubbleWidthInsets) headerSize.height += nameNodeSizeApply.0.height } @@ -2572,7 +2626,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } var hasThreadInfo = false - if case let .peer(peerId) = item.chatLocation, (peerId == replyMessage?.id.peerId || item.message.threadId == 1 || item.associatedData.isRecentActions), let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, channel.isForumOrMonoForum, item.message.associatedThreadInfo != nil { + if case let .peer(peerId) = item.chatLocation, (peerId == replyMessage?.id.peerId || item.message.threadId == 1 || item.associatedData.isRecentActions), let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, channel.isForum, item.message.associatedThreadInfo != nil { hasThreadInfo = true } else if case let .customChatContents(contents) = item.associatedData.subject, case .hashTagSearch = contents.kind { if let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { @@ -3119,13 +3173,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } var suggestedPostInfoNodeLayout: (CGSize, () -> ChatMessageSuggestedPostInfoNode)? - for attribute in item.message.attributes { - if let attribute = attribute as? OutgoingSuggestedPostMessageAttribute { - let _ = attribute - let suggestedPostInfoNodeLayoutValue = makeSuggestedPostInfoNodeLayout(item, baseWidth) - suggestedPostInfoNodeLayout = suggestedPostInfoNodeLayoutValue - } - } + suggestedPostInfoNodeLayout = nil if let suggestedPostInfoNodeLayout { additionalTopHeight += 4.0 + suggestedPostInfoNodeLayout.0.height + 8.0 @@ -3177,11 +3225,18 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } var layoutInsets = UIEdgeInsets(top: mergedTop.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, left: 0.0, bottom: mergedBottom.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, right: 0.0) - if dateHeaderAtBottom { - layoutInsets.top += layoutConstants.timestampHeaderHeight - } - if isAd { - layoutInsets.top += 4.0 + if dateHeaderAtBottom.hasDate && dateHeaderAtBottom.hasTopic { + layoutInsets.top += layoutConstants.timestampDateAndTopicHeaderHeight + } else { + if dateHeaderAtBottom.hasDate { + layoutInsets.top += layoutConstants.timestampHeaderHeight + } + if dateHeaderAtBottom.hasTopic { + layoutInsets.top += layoutConstants.timestampHeaderHeight + } + if isAd { + layoutInsets.top += 4.0 + } } let layout = ListViewItemNodeLayout(contentSize: layoutSize, insets: layoutInsets) @@ -3229,6 +3284,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI viaWidth: viaWidth, contentOrigin: contentOrigin, nameNodeOriginY: nameNodeOriginY + detachedContentNodesHeight + additionalTopHeight, + hasTitleAvatar: hasTitleAvatar, authorNameColor: authorNameColor, layoutConstants: layoutConstants, currentCredibilityIcon: currentCredibilityIcon, @@ -3259,7 +3315,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI hidesHeaders: hidesHeaders, disablesComments: disablesComments, suggestedPostInfoNodeLayout: suggestedPostInfoNodeLayout, - alignment: alignment + alignment: alignment, + isSidePanelOpen: isSidePanelOpen ) }) } @@ -3290,6 +3347,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI viaWidth: CGFloat, contentOrigin: CGPoint, nameNodeOriginY: CGFloat, + hasTitleAvatar: Bool, authorNameColor: UIColor?, layoutConstants: ChatMessageItemLayoutConstants, currentCredibilityIcon: (EmojiStatusComponent.Content, UIColor?)?, @@ -3320,7 +3378,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI hidesHeaders: Bool, disablesComments: Bool, suggestedPostInfoNodeLayout: (CGSize, () -> ChatMessageSuggestedPostInfoNode)?, - alignment: ChatMessageBubbleContentAlignment + alignment: ChatMessageBubbleContentAlignment, + isSidePanelOpen: Bool ) -> Void { guard let strongSelf = selfReference.value else { return @@ -3418,9 +3477,11 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI suggestedPostInfoNode.removeFromSupernode() } - if let avatarOffset = avatarOffset { + if let avatarOffset { strongSelf.updateAttachedAvatarNodeOffset(offset: avatarOffset, transition: .animated(duration: 0.3, curve: .spring)) } + strongSelf.updateAttachedAvatarNodeIsHidden(isHidden: isSidePanelOpen, transition: animation.transition) + strongSelf.updateAttachedDateHeader(hasDate: inputParams.dateHeaderAtBottom.hasDate, hasPeer: inputParams.dateHeaderAtBottom.hasTopic) let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp()) if isFailed { @@ -3458,8 +3519,91 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI strongSelf.nameNode = nameNode nameNode.displaysAsynchronously = !item.presentationData.isPreview && !item.presentationData.theme.theme.forceSync - //let previousNameNodeFrame = nameNode.frame - let nameNodeFrame = CGRect(origin: CGPoint(x: contentOrigin.x + layoutConstants.text.bubbleInsets.left, y: layoutConstants.bubble.contentInsets.top + nameNodeOriginY), size: nameNodeSizeApply.0) + let previousNameNodeFrame = nameNode.frame + + var nameNodeFrame = CGRect(origin: CGPoint(x: contentOrigin.x + layoutConstants.text.bubbleInsets.left, y: layoutConstants.bubble.contentInsets.top + nameNodeOriginY), size: nameNodeSizeApply.0) + + var nameNavigateButtonOffset: CGFloat = currentCredibilityIcon == nil ? 4.0 : 28.0 + nameNavigateButtonOffset += 34.0 + + if hasTitleAvatar { + let nameAvatarNode: AvatarNode + var animateNameAvatar = true + if let current = strongSelf.nameAvatarNode { + nameAvatarNode = current + } else { + animateNameAvatar = false + nameAvatarNode = AvatarNode(font: avatarPlaceholderFont(size: 8.0)) + strongSelf.nameAvatarNode = nameAvatarNode + strongSelf.clippingNode.addSubnode(nameAvatarNode) + } + + let nameNavigateButton: NameNavigateButton + if let current = strongSelf.nameNavigateButton { + nameNavigateButton = current + } else { + nameNavigateButton = NameNavigateButton(frame: CGRect()) + strongSelf.nameNavigateButton = nameNavigateButton + strongSelf.clippingNode.view.addSubview(nameNavigateButton) + nameNavigateButton.action = { [weak strongSelf] in + guard let strongSelf, let item = strongSelf.item else { + return + } + item.controllerInteraction.updateChatLocationThread(item.content.firstMessage.threadId) + } + } + + let nameAvatarFrame = CGRect(origin: CGPoint(x: nameNodeFrame.minX, y: nameNodeFrame.minY - 4.0), size: CGSize(width: 26.0, height: 26.0)) + let nameNavigateFrame = CGRect(origin: CGPoint(x: nameNodeFrame.maxX + 4.0 + nameNavigateButtonOffset, y: nameNodeFrame.minY - 4.0), size: CGSize(width: 26.0, height: 26.0)) + + if let peer = item.content.firstMessage.author, peer.smallProfileImage != nil { + nameAvatarNode.setPeerV2(context: item.context, theme: item.presentationData.theme.theme, peer: EnginePeer(peer), displayDimensions: nameAvatarFrame.size) + } else { + nameAvatarNode.setPeer(context: item.context, theme: item.presentationData.theme.theme, peer: item.content.firstMessage.author.flatMap(EnginePeer.init), displayDimensions: nameAvatarFrame.size) + } + nameAvatarNode.updateSize(size: nameAvatarFrame.size) + + nameNavigateButton.update(size: nameNavigateFrame.size, color: authorNameColor ?? item.presentationData.theme.theme.chat.message.incoming.accentTextColor) + + if animateNameAvatar { + animation.animator.updateFrame(layer: nameAvatarNode.layer, frame: nameAvatarFrame, completion: nil) + animation.animator.updateFrame(layer: nameNavigateButton.layer, frame: nameNavigateFrame, completion: nil) + } else { + nameAvatarNode.frame = CGRect(origin: CGPoint(x: previousNameNodeFrame.minX - 26.0 * 0.5, y: previousNameNodeFrame.minY - 4.0), size: CGSize(width: 26.0, height: 26.0)) + animation.animator.updateFrame(layer: nameAvatarNode.layer, frame: nameAvatarFrame, completion: nil) + if animation.isAnimated { + animation.transition.animateTransformScale(view: nameAvatarNode.view, from: 0.001) + nameAvatarNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1) + } + + nameNavigateButton.frame = CGRect(origin: CGPoint(x: previousNameNodeFrame.maxX + nameNavigateButtonOffset - 26.0 * 0.5, y: previousNameNodeFrame.minY - 4.0), size: CGSize(width: 26.0, height: 26.0)) + animation.animator.updateFrame(layer: nameNavigateButton.layer, frame: nameNavigateFrame, completion: nil) + if animation.isAnimated { + animation.transition.animateTransformScale(view: nameNavigateButton, from: 0.001) + nameNavigateButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1) + } + } + + nameNodeFrame.origin.x += 26.0 + 5.0 + } else { + if let nameAvatarNode = strongSelf.nameAvatarNode { + strongSelf.nameAvatarNode = nil + nameAvatarNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1, removeOnCompletion: false, completion: { [weak nameAvatarNode] _ in + nameAvatarNode?.removeFromSupernode() + }) + animation.animator.updateFrame(layer: nameAvatarNode.layer, frame: CGRect(origin: CGPoint(x: nameNodeFrame.minX - 26.0 * 0.5, y: nameNodeFrame.minY - 4.0), size: CGSize(width: 26.0, height: 26.0)), completion: nil) + animation.transition.updateTransformScale(node: nameAvatarNode, scale: CGPoint(x: 0.001, y: 0.001)) + } + if let nameNavigateButton = strongSelf.nameNavigateButton { + strongSelf.nameNavigateButton = nil + nameNavigateButton.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1, removeOnCompletion: false, completion: { [weak nameNavigateButton] _ in + nameNavigateButton?.removeFromSuperview() + }) + animation.animator.updateFrame(layer: nameNavigateButton.layer, frame: CGRect(origin: CGPoint(x: nameNodeFrame.maxX + nameNavigateButtonOffset - 26.0 * 0.5, y: nameNodeFrame.minY - 4.0), size: CGSize(width: 26.0, height: 26.0)), completion: nil) + animation.transition.updateTransformScale(layer: nameNavigateButton.layer, scale: CGPoint(x: 0.001, y: 0.001)) + } + } + if nameNode.supernode == nil { if !nameNode.isNodeLoaded { nameNode.isUserInteractionEnabled = false @@ -3516,9 +3660,11 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI if let (currentCredibilityIcon, currentParticleColor) = currentCredibilityIcon { let credibilityIconView: ComponentHostView + var animateCredibilityIconFrame = true if let current = strongSelf.credibilityIconView { credibilityIconView = current } else { + animateCredibilityIconFrame = false credibilityIconView = ComponentHostView() credibilityIconView.isUserInteractionEnabled = false strongSelf.credibilityIconView = credibilityIconView @@ -3549,7 +3695,10 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI ) let credibilityIconFrame = CGRect(origin: CGPoint(x: nameNode.frame.maxX + 3.0, y: nameNode.frame.minY + floor((nameNode.bounds.height - credibilityIconSize.height) / 2.0)), size: credibilityIconSize) - credibilityIconView.frame = credibilityIconFrame + if !animateCredibilityIconFrame { + credibilityIconView.frame = CGRect(origin: CGPoint(x: previousNameNodeFrame.maxX + 3.0, y: previousNameNodeFrame.minY + floor((previousNameNodeFrame.height - credibilityIconSize.height) / 2.0)), size: credibilityIconSize) + } + animation.animator.updateFrame(layer: credibilityIconView.layer, frame: credibilityIconFrame, completion: nil) let credibilityButtonNode: HighlightTrackingButtonNode let credibilityHighlightNode: ASImageNode @@ -3780,6 +3929,12 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } } else { if animation.isAnimated { + if let nameAvatarNode = strongSelf.nameAvatarNode { + strongSelf.nameAvatarNode = nil + nameAvatarNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1, removeOnCompletion: false, completion: { [weak nameAvatarNode] _ in + nameAvatarNode?.removeFromSupernode() + }) + } if let nameNode = strongSelf.nameNode { strongSelf.nameNode = nil nameNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1, removeOnCompletion: false, completion: { [weak nameNode] _ in @@ -3811,6 +3966,10 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI }) } } else { + strongSelf.nameAvatarNode?.removeFromSupernode() + strongSelf.nameAvatarNode = nil + strongSelf.nameNavigateButton?.removeFromSuperview() + strongSelf.nameNavigateButton = nil strongSelf.nameNode?.removeFromSupernode() strongSelf.nameNode = nil strongSelf.adminBadgeNode?.removeFromSupernode() @@ -4582,9 +4741,15 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI buttonFrame.origin.y = buttonFrame.origin.y - (buttonSize.height - 30.0) } - animation.animator.updateFrame(layer: shareButtonNode.layer, frame: buttonFrame, completion: nil) - animation.animator.updateAlpha(layer: shareButtonNode.layer, alpha: isCurrentlyPlayingMedia ? 0.0 : 1.0, completion: nil) - + if isSidePanelOpen { + buttonFrame.origin.x -= buttonFrame.width * 0.5 + buttonFrame.origin.y += buttonFrame.height * 0.5 + } + + animation.animator.updatePosition(layer: shareButtonNode.layer, position: buttonFrame.center, completion: nil) + animation.animator.updateBounds(layer: shareButtonNode.layer, bounds: CGRect(origin: CGPoint(), size: buttonFrame.size), completion: nil) + animation.animator.updateAlpha(layer: shareButtonNode.layer, alpha: (isCurrentlyPlayingMedia || isSidePanelOpen) ? 0.0 : 1.0, completion: nil) + animation.animator.updateScale(layer: shareButtonNode.layer, scale: (isCurrentlyPlayingMedia || isSidePanelOpen) ? 0.001 : 1.0, completion: nil) } } else { /*if let _ = strongSelf.backgroundFrameTransition { @@ -4609,8 +4774,16 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI } else if !disablesComments { buttonFrame.origin.y = buttonFrame.origin.y - (buttonSize.height - 30.0) } - shareButtonNode.frame = buttonFrame - shareButtonNode.alpha = isCurrentlyPlayingMedia ? 0.0 : 1.0 + + if isSidePanelOpen { + buttonFrame.origin.x -= buttonFrame.width * 0.5 + buttonFrame.origin.y += buttonFrame.height * 0.5 + } + + animation.animator.updatePosition(layer: shareButtonNode.layer, position: buttonFrame.center, completion: nil) + animation.animator.updateBounds(layer: shareButtonNode.layer, bounds: CGRect(origin: CGPoint(), size: buttonFrame.size), completion: nil) + animation.animator.updateAlpha(layer: shareButtonNode.layer, alpha: (isCurrentlyPlayingMedia || isSidePanelOpen) ? 0.0 : 1.0, completion: nil) + animation.animator.updateScale(layer: shareButtonNode.layer, scale: (isCurrentlyPlayingMedia || isSidePanelOpen) ? 0.001 : 1.0, completion: nil) } if case .System = animation, strongSelf.mainContextSourceNode.isExtractedToContextPreview { @@ -5826,6 +5999,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI break } } + } else if let channel = item.message.peers[item.message.id.peerId], channel.isMonoForum, case .peer = item.chatLocation { + item.controllerInteraction.updateChatLocationThread(item.message.threadId) } else { if !self.disablesComments { if let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { @@ -6482,3 +6657,54 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI return nil } } + +private func generateNameNavigateButtonImage() -> UIImage { + return generateImage(CGSize(width: 26.0, height: 26.0), rotatedContext: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + context.setFillColor(UIColor(white: 1.0, alpha: 0.1).cgColor) + context.fillEllipse(in: CGRect(origin: CGPoint(), size: size)) + + let arrowRect = CGSize(width: 4.0, height: 8.0).centered(in: CGRect(origin: CGPoint(), size: size)).offsetBy(dx: 1.0, dy: 0.0) + + context.setStrokeColor(UIColor.white.cgColor) + context.setLineWidth(1.0) + context.setLineCap(.round) + context.setLineJoin(.round) + context.beginPath() + context.move(to: arrowRect.origin) + context.addLine(to: CGPoint(x: arrowRect.maxX, y: arrowRect.midY)) + context.addLine(to: CGPoint(x: arrowRect.minX, y: arrowRect.maxY)) + context.strokePath() + + })!.withRenderingMode(.alwaysTemplate) +} + +public final class NameNavigateButton: HighlightableButton { + private static let sharedImage: UIImage = generateNameNavigateButtonImage() + + private let backgroundView: UIImageView + public var action: (() -> Void)? + + override public init(frame: CGRect) { + self.backgroundView = UIImageView(image: NameNavigateButton.sharedImage) + + super.init(frame: frame) + + self.addSubview(self.backgroundView) + + self.addTarget(self, action: #selector(self.pressed), for: .touchUpInside) + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc private func pressed() { + self.action?() + } + + public func update(size: CGSize, color: UIColor) { + self.backgroundView.frame = CGRect(origin: CGPoint(), size: size) + self.backgroundView.tintColor = color + } +} diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageSuggestedPostInfoNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageSuggestedPostInfoNode.swift index 59430f93c2..210e0770b6 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageSuggestedPostInfoNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageSuggestedPostInfoNode.swift @@ -49,12 +49,18 @@ public final class ChatMessageSuggestedPostInfoNode: ASDisplayNode { var amount: Int64 = 0 var timestamp: Int32? - for attribute in item.message.attributes { + + if "".isEmpty { + amount = 0 + timestamp = nil + } + + /*for attribute in item.message.attributes { if let attribute = attribute as? OutgoingSuggestedPostMessageAttribute { amount = attribute.price.value timestamp = attribute.timestamp } - } + }*/ //TODO:localize let amountString: String diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/Sources/StringForMessageTimestampStatus.swift b/submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/Sources/StringForMessageTimestampStatus.swift index a9f0a5a929..a751806322 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/Sources/StringForMessageTimestampStatus.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/Sources/StringForMessageTimestampStatus.swift @@ -95,17 +95,6 @@ public func stringForMessageTimestampStatus(accountPeerId: PeerId, message: Mess dateText = " " } - for attribute in message.attributes { - if let attribute = attribute as? OutgoingSuggestedPostMessageAttribute { - if let timestamp = attribute.timestamp { - dateText = stringForMessageTimestamp(timestamp: timestamp, dateTimeFormat: dateTimeFormat) - } else { - //TODO:localize - dateText = "Anytime" - } - } - } - if message.id.namespace == Namespaces.Message.ScheduledCloud, let _ = message.pendingProcessingAttribute { return "appx. \(dateText)" } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift index 2bbaf56794..4a4932ecf2 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode/Sources/ChatMessageInstantVideoItemNode.swift @@ -277,7 +277,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, ASGestureReco } } - override public func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { + override public func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: ChatMessageHeaderSpec) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { let layoutConstants = self.layoutConstants let makeVideoLayout = self.interactiveVideoNode.asyncLayout() @@ -296,7 +296,7 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, ASGestureReco let currentForwardInfo = self.appliedForwardInfo let currentPlaying = self.appliedCurrentlyPlaying - func continueAsyncLayout(_ weakSelf: Weak, _ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { + func continueAsyncLayout(_ weakSelf: Weak, _ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: ChatMessageHeaderSpec) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { let accessibilityData = ChatMessageAccessibilityData(item: item, isSelected: nil) let layoutConstants = chatMessageItemLayoutConstants(layoutConstants, params: params, presentationData: item.presentationData) @@ -391,8 +391,15 @@ public class ChatMessageInstantVideoItemNode: ChatMessageItemView, ASGestureReco } var layoutInsets = layoutConstants.instantVideo.insets - if dateHeaderAtBottom { - layoutInsets.top += layoutConstants.timestampHeaderHeight + if dateHeaderAtBottom.hasDate && dateHeaderAtBottom.hasTopic { + layoutInsets.top += layoutConstants.timestampDateAndTopicHeaderHeight + } else { + if dateHeaderAtBottom.hasDate { + layoutInsets.top += layoutConstants.timestampHeaderHeight + } + if dateHeaderAtBottom.hasTopic { + layoutInsets.top += layoutConstants.timestampHeaderHeight + } } var deliveryFailedInset: CGFloat = 0.0 diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItem/Sources/ChatMessageItem.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItem/Sources/ChatMessageItem.swift index 9cf52317b8..f736e8cbee 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItem/Sources/ChatMessageItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItem/Sources/ChatMessageItem.swift @@ -104,8 +104,23 @@ public enum ChatMessageMerge: Int32 { } } +public struct ChatMessageHeaderSpec: Equatable { + public var hasDate: Bool + public var hasTopic: Bool + + public init(hasDate: Bool, hasTopic: Bool) { + self.hasDate = hasDate + self.hasTopic = hasTopic + } +} + +public protocol ChatMessageDateHeaderNode: ListViewItemHeaderNode { + func updateItem(hasDate: Bool, hasPeer: Bool) +} + public protocol ChatMessageAvatarHeaderNode: ListViewItemHeaderNode { func updateSelectionState(animated: Bool) + func updateAvatarIsHidden(isHidden: Bool, transition: ContainedViewLayoutTransition) } public protocol ChatMessageItem: ListViewItem { @@ -127,7 +142,7 @@ public protocol ChatMessageItem: ListViewItem { var sending: Bool { get } var failed: Bool { get } - func mergedWithItems(top: ListViewItem?, bottom: ListViewItem?, isRotated: Bool) -> (top: ChatMessageMerge, bottom: ChatMessageMerge, dateAtBottom: Bool) + func mergedWithItems(top: ListViewItem?, bottom: ListViewItem?, isRotated: Bool) -> (top: ChatMessageMerge, bottom: ChatMessageMerge, dateAtBottom: ChatMessageHeaderSpec) } public func hasCommentButton(item: ChatMessageItem) -> Bool { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift index f749c3c46a..1b79cf3821 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift @@ -108,6 +108,7 @@ public struct ChatMessageItemWallpaperLayoutConstants { public struct ChatMessageItemLayoutConstants { public var avatarDiameter: CGFloat public var timestampHeaderHeight: CGFloat + public var timestampDateAndTopicHeaderHeight: CGFloat public var bubble: ChatMessageItemBubbleLayoutConstants public var image: ChatMessageItemImageLayoutConstants @@ -117,9 +118,10 @@ public struct ChatMessageItemLayoutConstants { public var instantVideo: ChatMessageItemInstantVideoConstants public var wallpapers: ChatMessageItemWallpaperLayoutConstants - public init(avatarDiameter: CGFloat, timestampHeaderHeight: CGFloat, bubble: ChatMessageItemBubbleLayoutConstants, image: ChatMessageItemImageLayoutConstants, video: ChatMessageItemVideoLayoutConstants, text: ChatMessageItemTextLayoutConstants, file: ChatMessageItemFileLayoutConstants, instantVideo: ChatMessageItemInstantVideoConstants, wallpapers: ChatMessageItemWallpaperLayoutConstants) { + public init(avatarDiameter: CGFloat, timestampHeaderHeight: CGFloat, timestampDateAndTopicHeaderHeight: CGFloat, bubble: ChatMessageItemBubbleLayoutConstants, image: ChatMessageItemImageLayoutConstants, video: ChatMessageItemVideoLayoutConstants, text: ChatMessageItemTextLayoutConstants, file: ChatMessageItemFileLayoutConstants, instantVideo: ChatMessageItemInstantVideoConstants, wallpapers: ChatMessageItemWallpaperLayoutConstants) { self.avatarDiameter = avatarDiameter self.timestampHeaderHeight = timestampHeaderHeight + self.timestampDateAndTopicHeaderHeight = timestampDateAndTopicHeaderHeight self.bubble = bubble self.image = image self.video = video @@ -142,7 +144,7 @@ public struct ChatMessageItemLayoutConstants { let instantVideo = ChatMessageItemInstantVideoConstants(insets: UIEdgeInsets(top: 4.0, left: 0.0, bottom: 4.0, right: 0.0), dimensions: CGSize(width: 212.0, height: 212.0)) let wallpapers = ChatMessageItemWallpaperLayoutConstants(maxTextWidth: 180.0) - return ChatMessageItemLayoutConstants(avatarDiameter: 37.0, timestampHeaderHeight: 34.0, bubble: bubble, image: image, video: video, text: text, file: file, instantVideo: instantVideo, wallpapers: wallpapers) + return ChatMessageItemLayoutConstants(avatarDiameter: 37.0, timestampHeaderHeight: 34.0, timestampDateAndTopicHeaderHeight: 7.0 * 2.0 + 20.0 * 2.0 + 7.0, bubble: bubble, image: image, video: video, text: text, file: file, instantVideo: instantVideo, wallpapers: wallpapers) } public static var regular: ChatMessageItemLayoutConstants { @@ -154,7 +156,7 @@ public struct ChatMessageItemLayoutConstants { let instantVideo = ChatMessageItemInstantVideoConstants(insets: UIEdgeInsets(top: 4.0, left: 0.0, bottom: 4.0, right: 0.0), dimensions: CGSize(width: 240.0, height: 240.0)) let wallpapers = ChatMessageItemWallpaperLayoutConstants(maxTextWidth: 180.0) - return ChatMessageItemLayoutConstants(avatarDiameter: 37.0, timestampHeaderHeight: 34.0, bubble: bubble, image: image, video: video, text: text, file: file, instantVideo: instantVideo, wallpapers: wallpapers) + return ChatMessageItemLayoutConstants(avatarDiameter: 37.0, timestampHeaderHeight: 34.0, timestampDateAndTopicHeaderHeight: 7.0 * 2.0 + 20.0 * 2.0 + 7.0, bubble: bubble, image: image, video: video, text: text, file: file, instantVideo: instantVideo, wallpapers: wallpapers) } } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift index ec987e7b89..290c6dcfa4 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift @@ -16,6 +16,7 @@ import WallpaperBackgroundNode import ChatControllerInteraction import AvatarVideoNode import ChatMessageItem +import AvatarNode private let timezoneOffset: Int32 = { let nowTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) @@ -28,25 +29,55 @@ private let timezoneOffset: Int32 = { private let granularity: Int32 = 60 * 60 * 24 public final class ChatMessageDateHeader: ListViewItemHeader { + public struct Id: Hashable { + public let roundedTimestamp: Int64? + public let separableThreadId: Int64? + + public init(roundedTimestamp: Int64?, separableThreadId: Int64?) { + self.roundedTimestamp = roundedTimestamp + self.separableThreadId = separableThreadId + } + } + + public final class PeerData { + public let peer: EnginePeer + + public init(peer: EnginePeer) { + self.peer = peer + } + } + private let timestamp: Int32 private let roundedTimestamp: Int32 private let scheduled: Bool + public let displayPeer: PeerData? public let id: ListViewItemNode.HeaderId + public let stackingId: ListViewItemNode.HeaderId? + public let idValue: Id public let presentationData: ChatPresentationData public let controllerInteraction: ChatControllerInteraction? public let context: AccountContext public let action: ((Int32, Bool) -> Void)? - public init(timestamp: Int32, scheduled: Bool, presentationData: ChatPresentationData, controllerInteraction: ChatControllerInteraction?, context: AccountContext, action: ((Int32, Bool) -> Void)? = nil) { + public init(timestamp: Int32, separableThreadId: Int64?, scheduled: Bool, displayPeer: PeerData?, presentationData: ChatPresentationData, controllerInteraction: ChatControllerInteraction?, context: AccountContext, action: ((Int32, Bool) -> Void)? = nil) { self.timestamp = timestamp self.scheduled = scheduled + self.displayPeer = displayPeer self.presentationData = presentationData self.controllerInteraction = controllerInteraction self.context = context self.action = action self.roundedTimestamp = dateHeaderTimestampId(timestamp: timestamp) - self.id = ListViewItemNode.HeaderId(space: 0, id: Int64(self.roundedTimestamp)) + if let _ = self.displayPeer { + self.idValue = ChatMessageDateHeader.Id(roundedTimestamp: 0, separableThreadId: separableThreadId) + self.id = ListViewItemNode.HeaderId(space: 3, id: self.idValue) + self.stackingId = ListViewItemNode.HeaderId(space: 2, id: ChatMessageDateHeader.Id(roundedTimestamp: Int64(self.roundedTimestamp), separableThreadId: nil)) + } else { + self.idValue = ChatMessageDateHeader.Id(roundedTimestamp: Int64(self.roundedTimestamp), separableThreadId: nil) + self.id = ListViewItemNode.HeaderId(space: 2, id: self.idValue) + self.stackingId = nil + } let isRotated = controllerInteraction?.chatIsRotated ?? true @@ -67,11 +98,11 @@ public final class ChatMessageDateHeader: ListViewItemHeader { } public func node(synchronousLoad: Bool) -> ListViewItemHeaderNode { - return ChatMessageDateHeaderNode(localTimestamp: self.roundedTimestamp, scheduled: self.scheduled, presentationData: self.presentationData, controllerInteraction: self.controllerInteraction, context: self.context, action: self.action) + return ChatMessageDateHeaderNodeImpl(localTimestamp: self.roundedTimestamp, scheduled: self.scheduled, displayPeer: self.displayPeer, presentationData: self.presentationData, controllerInteraction: self.controllerInteraction, context: self.context, action: self.action) } public func updateNode(_ node: ListViewItemHeaderNode, previous: ListViewItemHeader?, next: ListViewItemHeader?) { - guard let node = node as? ChatMessageDateHeaderNode, let next = next as? ChatMessageDateHeader else { + guard let node = node as? ChatMessageDateHeaderNodeImpl, let next = next as? ChatMessageDateHeader else { return } node.updatePresentationData(next.presentationData, context: next.context) @@ -119,32 +150,71 @@ private func dateHeaderTimestampId(timestamp: Int32) -> Int32 { } } -public final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { +private final class ChatMessageDateSectionSeparatorNode: ASDisplayNode { + private let controllerInteraction: ChatControllerInteraction? + private let presentationData: ChatPresentationData + + private let backgroundNode: NavigationBackgroundNode + private let patternLayer: SimpleShapeLayer + + init( + controllerInteraction: ChatControllerInteraction?, + presentationData: ChatPresentationData + ) { + self.controllerInteraction = controllerInteraction + self.presentationData = presentationData + + self.backgroundNode = NavigationBackgroundNode(color: .clear) + self.backgroundNode.isUserInteractionEnabled = false + + self.patternLayer = SimpleShapeLayer() + + super.init() + + self.backgroundColor = nil + self.isOpaque = false + + self.addSubnode(self.backgroundNode) + + let fullTranslucency: Bool = self.controllerInteraction?.enableFullTranslucency ?? true + + self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: self.presentationData.theme.theme, wallpaper: self.presentationData.theme.wallpaper), enableBlur: fullTranslucency && dateFillNeedsBlur(theme: self.presentationData.theme.theme, wallpaper: self.presentationData.theme.wallpaper), transition: .immediate) + + self.patternLayer.lineWidth = 1.66 + self.patternLayer.strokeColor = UIColor.white.cgColor + + let linePath = CGMutablePath() + linePath.move(to: CGPoint(x: 0.0, y: self.patternLayer.lineWidth * 0.5)) + linePath.addLine(to: CGPoint(x: 10000.0, y: self.patternLayer.lineWidth * 0.5)) + self.patternLayer.path = linePath + self.patternLayer.lineDashPattern = [6.0 as NSNumber, 2.0 as NSNumber] as [NSNumber] + + self.backgroundNode.layer.mask = self.patternLayer + } + + func update(size: CGSize, transition: ContainedViewLayoutTransition) { + let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: 10.0)) + transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame) + self.backgroundNode.update(size: backgroundFrame.size, transition: transition) + + transition.updateFrame(layer: self.patternLayer, frame: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: 1.66))) + } +} + +private final class ChatMessageDateContentNode: ASDisplayNode { + private var presentationData: ChatPresentationData + private let controllerInteraction: ChatControllerInteraction? + public let labelNode: TextNode public let backgroundNode: NavigationBackgroundNode public let stickBackgroundNode: ASImageNode private var backgroundContent: WallpaperBubbleBackgroundNode? + private var text: String - private let localTimestamp: Int32 - private var presentationData: ChatPresentationData - private let controllerInteraction: ChatControllerInteraction? - private let context: AccountContext - private let text: String - - private var flashingOnScrolling = false - private var stickDistanceFactor: CGFloat = 0.0 - private var action: ((Int32, Bool) -> Void)? = nil - - private var absolutePosition: (CGRect, CGSize)? - - public init(localTimestamp: Int32, scheduled: Bool, presentationData: ChatPresentationData, controllerInteraction: ChatControllerInteraction?, context: AccountContext, action: ((Int32, Bool) -> Void)? = nil) { + init(presentationData: ChatPresentationData, controllerInteraction: ChatControllerInteraction?, localTimestamp: Int32, scheduled: Bool) { self.presentationData = presentationData self.controllerInteraction = controllerInteraction - self.context = context - - self.localTimestamp = localTimestamp - self.action = action self.labelNode = TextNode() self.labelNode.isUserInteractionEnabled = false @@ -195,13 +265,7 @@ public final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { } self.text = text - let isRotated = controllerInteraction?.chatIsRotated ?? true - - super.init(layerBacked: false, dynamicBounce: true, isRotated: isRotated, seeThrough: false) - - if isRotated { - self.transform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) - } + super.init() let graphics = PresentationResourcesChat.principalGraphics(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) @@ -210,7 +274,7 @@ public final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: fullTranslucency && dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) self.stickBackgroundNode.image = graphics.dateFloatingBackground self.stickBackgroundNode.alpha = 0.0 - + if let backgroundContent = self.backgroundContent { self.addSubnode(backgroundContent) } else { @@ -227,14 +291,8 @@ public final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { let _ = apply() self.labelNode.frame = CGRect(origin: CGPoint(), size: size.size) } - - override public func didLoad() { - super.didLoad() - - self.view.addGestureRecognizer(ListViewTapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) - } - public func updatePresentationData(_ presentationData: ChatPresentationData, context: AccountContext) { + func updatePresentationData(_ presentationData: ChatPresentationData, context: AccountContext) { let previousPresentationData = self.presentationData self.presentationData = presentationData @@ -256,55 +314,343 @@ public final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { if presentationData.fontSize != previousPresentationData.fontSize { self.labelNode.bounds = CGRect(origin: CGPoint(), size: size.size) } - - self.setNeedsLayout() } - public func updateBackgroundColor(color: UIColor, enableBlur: Bool) { + func updateBackgroundColor(color: UIColor, enableBlur: Bool) { self.backgroundNode.updateColor(color: color, enableBlur: enableBlur, transition: .immediate) } - override public func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) { - self.absolutePosition = (rect, containerSize) - if let backgroundContent = self.backgroundContent { - var backgroundFrame = backgroundContent.frame - backgroundFrame.origin.x += rect.minX - backgroundFrame.origin.y += containerSize.height - rect.minY - backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate) - } - } - - override public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) { + func update(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { let chatDateSize: CGFloat = 20.0 let chatDateInset: CGFloat = 6.0 let labelSize = self.labelNode.bounds.size let backgroundSize = CGSize(width: labelSize.width + chatDateInset * 2.0, height: chatDateSize) - let backgroundFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - backgroundSize.width) / 2.0), y: (34.0 - chatDateSize) / 2.0), size: backgroundSize) - self.stickBackgroundNode.frame = CGRect(origin: CGPoint(), size: backgroundFrame.size) - self.backgroundNode.frame = backgroundFrame - self.backgroundNode.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.size.height / 2.0, transition: .immediate) - self.labelNode.frame = CGRect(origin: CGPoint(x: backgroundFrame.origin.x + chatDateInset, y: backgroundFrame.origin.y + floorToScreenPixels((backgroundSize.height - labelSize.height) / 2.0)), size: labelSize) + let backgroundFrame = CGRect(origin: CGPoint(x: leftInset + floorToScreenPixels((size.width - leftInset - rightInset - backgroundSize.width) / 2.0), y: (size.height - chatDateSize) / 2.0), size: backgroundSize) + + transition.updateFrame(node: self.stickBackgroundNode, frame: CGRect(origin: CGPoint(), size: backgroundFrame.size)) + transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame) + self.backgroundNode.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.size.height / 2.0, transition: transition) + let labelFrame = CGRect(origin: CGPoint(x: backgroundFrame.origin.x + chatDateInset, y: backgroundFrame.origin.y + floorToScreenPixels((backgroundSize.height - labelSize.height) / 2.0)), size: labelSize) + + transition.updatePosition(node: self.labelNode, position: labelFrame.center) + self.labelNode.bounds = CGRect(origin: CGPoint(), size: labelFrame.size) if let backgroundContent = self.backgroundContent { backgroundContent.allowsGroupOpacity = true self.backgroundNode.isHidden = true - backgroundContent.frame = self.backgroundNode.frame + + transition.updateFrame(node: backgroundContent, frame: self.backgroundNode.frame) backgroundContent.cornerRadius = backgroundFrame.size.height / 2.0 - if let (rect, containerSize) = self.absolutePosition { + /*if let (rect, containerSize) = self.absolutePosition { var backgroundFrame = backgroundContent.frame backgroundFrame.origin.x += rect.minX backgroundFrame.origin.y += containerSize.height - rect.minY - backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate) - } + backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: transition) + }*/ } } - override public func updateStickDistanceFactor(_ factor: CGFloat, transition: ContainedViewLayoutTransition) { + func updateStickDistanceFactor(_ factor: CGFloat, transition: ContainedViewLayoutTransition) { + self.stickBackgroundNode.alpha = factor + } +} + +private final class ChatMessagePeerContentNode: ASDisplayNode { + private let context: AccountContext + private var presentationData: ChatPresentationData + private let controllerInteraction: ChatControllerInteraction? + private let peer: EnginePeer + + private let avatarNode: AvatarNode + public let labelNode: TextNode + public let backgroundNode: NavigationBackgroundNode + public let stickBackgroundNode: ASImageNode + + private var backgroundContent: WallpaperBubbleBackgroundNode? + private var text: String + + init(context: AccountContext, presentationData: ChatPresentationData, controllerInteraction: ChatControllerInteraction?, peer: EnginePeer) { + self.context = context + self.presentationData = presentationData + self.controllerInteraction = controllerInteraction + self.peer = peer + + self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 8.0)) + + self.labelNode = TextNode() + self.labelNode.isUserInteractionEnabled = false + self.labelNode.displaysAsynchronously = !presentationData.isPreview + + if controllerInteraction?.presentationContext.backgroundNode?.hasExtraBubbleBackground() == true, let backgroundContent = controllerInteraction?.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) { + backgroundContent.clipsToBounds = true + self.backgroundContent = backgroundContent + } + + self.backgroundNode = NavigationBackgroundNode(color: .clear) + self.backgroundNode.isUserInteractionEnabled = false + + self.stickBackgroundNode = ASImageNode() + self.stickBackgroundNode.isLayerBacked = true + self.stickBackgroundNode.displayWithoutProcessing = true + self.stickBackgroundNode.displaysAsynchronously = false + + let text = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) + self.text = text + + super.init() + + let graphics = PresentationResourcesChat.principalGraphics(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) + + let fullTranslucency: Bool = controllerInteraction?.enableFullTranslucency ?? true + + self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: fullTranslucency && dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) + self.stickBackgroundNode.image = graphics.dateFloatingBackground + self.stickBackgroundNode.alpha = 0.0 + + if let backgroundContent = self.backgroundContent { + self.addSubnode(backgroundContent) + } else { + self.addSubnode(self.backgroundNode) + } + self.addSubnode(self.avatarNode) + self.addSubnode(self.labelNode) + + let titleFont = Font.medium(min(18.0, floor(presentationData.fontSize.baseDisplaySize * 13.0 / 17.0))) + + let attributedString = NSAttributedString(string: text, font: titleFont, textColor: bubbleVariableColor(variableColor: presentationData.theme.theme.chat.serviceMessage.dateTextColor, wallpaper: presentationData.theme.wallpaper)) + let labelLayout = TextNode.asyncLayout(self.labelNode) + + let (size, apply) = labelLayout(TextNodeLayoutArguments(attributedString: attributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 320.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let _ = apply() + self.labelNode.frame = CGRect(origin: CGPoint(), size: size.size) + } + + func updatePresentationData(_ presentationData: ChatPresentationData, context: AccountContext) { + let previousPresentationData = self.presentationData + self.presentationData = presentationData + + let graphics = PresentationResourcesChat.principalGraphics(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) + + let fullTranslucency: Bool = self.controllerInteraction?.enableFullTranslucency ?? true + + self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: fullTranslucency && dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate) + self.stickBackgroundNode.image = graphics.dateFloatingBackground + + let titleFont = Font.medium(min(18.0, floor(presentationData.fontSize.baseDisplaySize * 13.0 / 17.0))) + + let attributedString = NSAttributedString(string: self.text, font: titleFont, textColor: bubbleVariableColor(variableColor: presentationData.theme.theme.chat.serviceMessage.dateTextColor, wallpaper: presentationData.theme.wallpaper)) + let labelLayout = TextNode.asyncLayout(self.labelNode) + + let (size, apply) = labelLayout(TextNodeLayoutArguments(attributedString: attributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 320.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let _ = apply() + + if presentationData.fontSize != previousPresentationData.fontSize { + self.labelNode.bounds = CGRect(origin: CGPoint(), size: size.size) + } + } + + func updateBackgroundColor(color: UIColor, enableBlur: Bool) { + self.backgroundNode.updateColor(color: color, enableBlur: enableBlur, transition: .immediate) + } + + func update(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { + let chatDateSize: CGFloat = 20.0 + let chatDateInset: CGFloat = 6.0 + + let avatarDiameter: CGFloat = 16.0 + let avatarInset: CGFloat = 2.0 + let avatarSpacing: CGFloat = 4.0 + + let labelSize = self.labelNode.bounds.size + let backgroundSize = CGSize(width: avatarInset + avatarDiameter + avatarSpacing + labelSize.width + chatDateInset, height: chatDateSize) + + let backgroundFrame = CGRect(origin: CGPoint(x: leftInset + floorToScreenPixels((size.width - leftInset - rightInset - backgroundSize.width) / 2.0), y: (size.height - chatDateSize) / 2.0), size: backgroundSize) + + let avatarFrame = CGRect(origin: CGPoint(x: backgroundFrame.minX + avatarInset, y: backgroundFrame.origin.y + floorToScreenPixels((backgroundSize.height - avatarDiameter) / 2.0)), size: CGSize(width: avatarDiameter, height: avatarDiameter)) + transition.updateFrame(node: self.avatarNode, frame: avatarFrame) + self.avatarNode.updateSize(size: avatarFrame.size) + + if self.peer.smallProfileImage != nil { + self.avatarNode.setPeerV2(context: self.context, theme: self.presentationData.theme.theme, peer: self.peer, displayDimensions: avatarFrame.size) + } else { + self.avatarNode.setPeer(context: self.context, theme: self.presentationData.theme.theme, peer: self.peer, displayDimensions: avatarFrame.size) + } + + transition.updateFrame(node: self.stickBackgroundNode, frame: CGRect(origin: CGPoint(), size: backgroundFrame.size)) + transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame) + self.backgroundNode.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.size.height / 2.0, transition: transition) + let labelFrame = CGRect(origin: CGPoint(x: backgroundFrame.origin.x + avatarInset + avatarDiameter + avatarSpacing, y: backgroundFrame.origin.y + floorToScreenPixels((backgroundSize.height - labelSize.height) / 2.0)), size: labelSize) + + transition.updatePosition(node: self.labelNode, position: labelFrame.center) + self.labelNode.bounds = CGRect(origin: CGPoint(), size: labelFrame.size) + + if let backgroundContent = self.backgroundContent { + backgroundContent.allowsGroupOpacity = true + self.backgroundNode.isHidden = true + + transition.updateFrame(node: backgroundContent, frame: self.backgroundNode.frame) + backgroundContent.cornerRadius = backgroundFrame.size.height / 2.0 + + /*if let (rect, containerSize) = self.absolutePosition { + var backgroundFrame = backgroundContent.frame + backgroundFrame.origin.x += rect.minX + backgroundFrame.origin.y += containerSize.height - rect.minY + backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: transition) + }*/ + } + } + + func updateStickDistanceFactor(_ factor: CGFloat, transition: ContainedViewLayoutTransition) { + self.stickBackgroundNode.alpha = factor + } +} + +public final class ChatMessageDateHeaderNodeImpl: ListViewItemHeaderNode, ChatMessageDateHeaderNode { + private var dateContentNode: ChatMessageDateContentNode? + private var peerContentNode: ChatMessagePeerContentNode? + + private var sectionSeparator: ChatMessageDateSectionSeparatorNode? + + private let context: AccountContext + private let localTimestamp: Int32 + private let scheduled: Bool + private let displayPeer: ChatMessageDateHeader.PeerData? + private var presentationData: ChatPresentationData + private let controllerInteraction: ChatControllerInteraction? + + private var flashingOnScrolling = false + private var stickDistanceFactor: CGFloat = 0.0 + private var action: ((Int32, Bool) -> Void)? = nil + + private var params: (size: CGSize, leftInset: CGFloat, rightInset: CGFloat)? + private var absolutePosition: (CGRect, CGSize)? + + public init(localTimestamp: Int32, scheduled: Bool, displayPeer: ChatMessageDateHeader.PeerData?, presentationData: ChatPresentationData, controllerInteraction: ChatControllerInteraction?, context: AccountContext, action: ((Int32, Bool) -> Void)? = nil) { + self.context = context + self.presentationData = presentationData + self.controllerInteraction = controllerInteraction + + self.localTimestamp = localTimestamp + self.scheduled = scheduled + self.displayPeer = displayPeer + self.action = action + + let isRotated = controllerInteraction?.chatIsRotated ?? true + + super.init(layerBacked: false, dynamicBounce: true, isRotated: isRotated, seeThrough: false) + + if isRotated { + self.transform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0) + } + + if let displayPeer { + if self.peerContentNode == nil { + let sectionSeparator = ChatMessageDateSectionSeparatorNode(controllerInteraction: controllerInteraction, presentationData: presentationData) + self.sectionSeparator = sectionSeparator + self.addSubnode(sectionSeparator) + + let peerContentNode = ChatMessagePeerContentNode(context: self.context, presentationData: self.presentationData, controllerInteraction: self.controllerInteraction, peer: displayPeer.peer) + self.peerContentNode = peerContentNode + self.addSubnode(peerContentNode) + } + } else { + if self.dateContentNode == nil { + let dateContentNode = ChatMessageDateContentNode(presentationData: self.presentationData, controllerInteraction: self.controllerInteraction, localTimestamp: self.localTimestamp, scheduled: self.scheduled) + self.dateContentNode = dateContentNode + self.addSubnode(dateContentNode) + } + } + } + + override public func didLoad() { + super.didLoad() + + self.view.addGestureRecognizer(ListViewTapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) + } + + public func updateItem(hasDate: Bool, hasPeer: Bool) { + } + + public func updatePresentationData(_ presentationData: ChatPresentationData, context: AccountContext) { + if let dateContentNode = self.dateContentNode { + dateContentNode.updatePresentationData(presentationData, context: context) + } + if let peerContentNode = self.peerContentNode { + peerContentNode.updatePresentationData(presentationData, context: context) + } + + self.setNeedsLayout() + } + + public func updateBackgroundColor(color: UIColor, enableBlur: Bool) { + if let dateContentNode = self.dateContentNode { + dateContentNode.updateBackgroundColor(color: color, enableBlur: enableBlur) + } + if let peerContentNode = self.peerContentNode { + peerContentNode.updateBackgroundColor(color: color, enableBlur: enableBlur) + } + } + + override public func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) { + /*self.absolutePosition = (rect, containerSize) + if let backgroundContent = self.backgroundContent { + var backgroundFrame = backgroundContent.frame + backgroundFrame.origin.x += rect.minX + backgroundFrame.origin.y += containerSize.height - rect.minY + backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate) + }*/ + } + + override public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { + self.params = (size, leftInset, rightInset) + + var contentOffsetY: CGFloat = 0.0 + var isFirst = true + if let dateContentNode = self.dateContentNode { + if isFirst { + isFirst = false + contentOffsetY += 7.0 + } else { + contentOffsetY += 7.0 + } + let contentFrame = CGRect(origin: CGPoint(x: 0.0, y: contentOffsetY), size: CGSize(width: size.width, height: 20.0)) + transition.updateFrame(node: dateContentNode, frame: contentFrame) + dateContentNode.update(size: contentFrame.size, leftInset: leftInset, rightInset: rightInset, transition: transition) + contentOffsetY += 20.0 + } + if let peerContentNode = self.peerContentNode { + if isFirst { + isFirst = false + contentOffsetY += 7.0 + } else { + contentOffsetY += 7.0 + } + let contentFrame = CGRect(origin: CGPoint(x: 0.0, y: contentOffsetY), size: CGSize(width: size.width, height: 20.0)) + transition.updateFrame(node: peerContentNode, frame: contentFrame) + peerContentNode.update(size: contentFrame.size, leftInset: leftInset, rightInset: rightInset, transition: transition) + contentOffsetY += 20.0 + + if let sectionSeparator = self.sectionSeparator { + let sectionSeparatorFrame = CGRect(origin: CGPoint(x: 0.0, y: contentFrame.minY + floorToScreenPixels((contentFrame.height - 1.66) * 0.5)), size: CGSize(width: size.width, height: 1.66)) + sectionSeparator.update(size: sectionSeparatorFrame.size, transition: transition) + transition.updatePosition(node: sectionSeparator, position: sectionSeparatorFrame.center) + transition.updateBounds(node: sectionSeparator, bounds: CGRect(origin: CGPoint(), size: sectionSeparatorFrame.size)) + } + } + contentOffsetY += 7.0 + } + + override public func updateStickDistanceFactor(_ factor: CGFloat, distance: CGFloat, transition: ContainedViewLayoutTransition) { if !self.stickDistanceFactor.isEqual(to: factor) { - self.stickBackgroundNode.alpha = factor + if let dateContentNode = self.dateContentNode { + dateContentNode.updateStickDistanceFactor(factor, transition: transition) + } + if let peerContentNode = self.peerContentNode { + peerContentNode.updateStickDistanceFactor(factor, transition: transition) + } let wasZero = self.stickDistanceFactor < 0.5 let isZero = factor < 0.5 @@ -318,6 +664,10 @@ public final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { self.updateFlashing(animated: animated) } } + + if let sectionSeparator = self.sectionSeparator { + transition.updateTransform(node: sectionSeparator, transform: CGAffineTransformMakeTranslation(0.0, -distance)) + } } override public func updateFlashingOnScrolling(_ isFlashingOnScrolling: Bool, animated: Bool) { @@ -329,34 +679,82 @@ public final class ChatMessageDateHeaderNode: ListViewItemHeaderNode { let flashing = self.flashingOnScrolling || self.stickDistanceFactor < 0.5 let alpha: CGFloat = flashing ? 1.0 : 0.0 - let previousAlpha = self.backgroundNode.alpha - if !previousAlpha.isEqual(to: alpha) { - self.backgroundContent?.alpha = alpha - self.backgroundNode.alpha = alpha - self.labelNode.alpha = alpha - if animated { - let duration: Double = flashing ? 0.3 : 0.4 - self.backgroundContent?.layer.animateAlpha(from: previousAlpha, to: alpha, duration: duration) - self.backgroundNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: duration) - self.labelNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: duration) + if let dateContentNode = self.dateContentNode { + let previousAlpha = dateContentNode.alpha + + if !previousAlpha.isEqual(to: alpha) { + dateContentNode.alpha = alpha + if animated { + let duration: Double = flashing ? 0.3 : 0.4 + dateContentNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: duration) + } + } + } + + if let peerContentNode = self.peerContentNode { + let previousAlpha = peerContentNode.alpha + + if !previousAlpha.isEqual(to: alpha) { + peerContentNode.alpha = alpha + if animated { + let duration: Double = flashing ? 0.3 : 0.4 + peerContentNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: duration) + } } } } + override public func animateRemoved(duration: Double) { + self.alpha = 0.0 + self.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false) + if self.dateContentNode != nil { + self.layer.animateScale(from: 1.0, to: 0.2, duration: duration, removeOnCompletion: false) + } + } + + override public func animateAdded(duration: Double) { + self.layer.animateAlpha(from: 0.0, to: self.alpha, duration: 0.2) + if self.dateContentNode != nil { + self.layer.animateScale(from: 0.2, to: 1.0, duration: 0.2) + } + } + override public func getEffectiveAlpha() -> CGFloat { - return self.backgroundNode.alpha + if let dateContentNode = self.dateContentNode { + return dateContentNode.alpha + } + if let peerContentNode = self.peerContentNode { + return peerContentNode.alpha + } + return 0.0 } override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if !self.bounds.contains(point) { return nil } - if self.labelNode.alpha.isZero { - return nil + if let dateContentNode = self.dateContentNode { + if dateContentNode.frame.contains(point) { + if dateContentNode.alpha.isZero { + return nil + } + + if dateContentNode.backgroundNode.frame.contains(point.offsetBy(dx: -dateContentNode.frame.minX, dy: -dateContentNode.frame.minY)) { + return self.view + } + } } - if self.backgroundNode.frame.contains(point) { - return self.view + if let peerContentNode = self.peerContentNode { + if peerContentNode.frame.contains(point) { + if peerContentNode.alpha.isZero { + return nil + } + + if peerContentNode.backgroundNode.frame.contains(point.offsetBy(dx: -peerContentNode.frame.minX, dy: -peerContentNode.frame.minY)) { + return self.view + } + } } return nil } @@ -379,6 +777,7 @@ public final class ChatMessageAvatarHeader: ListViewItemHeader { } public let id: ListViewItemNode.HeaderId + public let stackingId: ListViewItemNode.HeaderId? = nil public let peerId: PeerId public let peer: Peer? public let messageReference: MessageReference? @@ -472,6 +871,8 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat private var backgroundContent: WallpaperBubbleBackgroundNode? + private var isAvatarHidden: Bool = false + private var trackingIsInHierarchy: Bool = false { didSet { if self.trackingIsInHierarchy != oldValue { @@ -713,15 +1114,20 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat } } - override public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) { - self.containerNode.frame = CGRect(origin: CGPoint(x: leftInset + 3.0, y: 0.0), size: CGSize(width: 38.0, height: 38.0)) - self.avatarNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: 38.0, height: 38.0)) + override public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) { + transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(x: leftInset + 3.0, y: 0.0), size: CGSize(width: 38.0, height: 38.0))) + let avatarFrame = CGRect(origin: CGPoint(), size: CGSize(width: 38.0, height: 38.0)) + self.avatarNode.position = avatarFrame.center + self.avatarNode.bounds = CGRect(origin: CGPoint(), size: avatarFrame.size) + self.avatarNode.updateSize(size: avatarFrame.size) } override public func animateRemoved(duration: Double) { self.alpha = 0.0 self.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false) - self.avatarNode.layer.animateScale(from: 1.0, to: 0.2, duration: duration, removeOnCompletion: false) + if !self.isAvatarHidden { + self.avatarNode.layer.animateScale(from: 1.0, to: 0.2, duration: duration, removeOnCompletion: false) + } } override public func animateAdded(duration: Double) { @@ -729,7 +1135,7 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat self.avatarNode.layer.animateScale(from: 0.2, to: 1.0, duration: 0.2) } - override public func updateStickDistanceFactor(_ factor: CGFloat, transition: ContainedViewLayoutTransition) { + override public func updateStickDistanceFactor(_ factor: CGFloat, distance: CGFloat, transition: ContainedViewLayoutTransition) { } override public func updateFlashingOnScrolling(_ isFlashingOnScrolling: Bool, animated: Bool) { @@ -748,6 +1154,18 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat self.layer.animate(from: NSValue(caTransform3D: previousSubnodeTransform), to: NSValue(caTransform3D: self.subnodeTransform), keyPath: "sublayerTransform", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, duration: 0.2) } } + + public func updateAvatarIsHidden(isHidden: Bool, transition: ContainedViewLayoutTransition) { + self.isAvatarHidden = isHidden + var avatarTransform: CATransform3D = CATransform3DIdentity + if isHidden { + let scale: CGFloat = isHidden ? 0.001 : 1.0 + avatarTransform = CATransform3DTranslate(avatarTransform, -38.0 * 0.5, 38.0 * 0.5, 0.0) + avatarTransform = CATransform3DScale(avatarTransform, scale, scale, 1.0) + } + transition.updateTransform(node: self.avatarNode, transform: avatarTransform) + transition.updateAlpha(node: self.avatarNode, alpha: isHidden ? 0.0 : 1.0) + } override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if !self.bounds.contains(point) { @@ -786,7 +1204,7 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat self.avatarVideoNode?.updateVisibility(isVisible) if let videoNode = self.avatarVideoNode { - videoNode.updateLayout(size: self.avatarNode.frame.size, cornerRadius: self.avatarNode.frame.size.width / 2.0, transition: .immediate) + videoNode.updateLayout(size: self.avatarNode.bounds.size, cornerRadius: self.avatarNode.bounds.size.width / 2.0, transition: .immediate) videoNode.frame = self.avatarNode.bounds } } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift index 83bb0ae9c4..e201f39da8 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageItemImpl.swift @@ -220,6 +220,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible public let additionalContent: ChatMessageItemAdditionalContent? let dateHeader: ChatMessageDateHeader + let topicHeader: ChatMessageDateHeader? let avatarHeader: ChatMessageAvatarHeader? public let headers: [ListViewItemHeader] @@ -283,9 +284,11 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible let incoming = content.effectivelyIncoming(self.context.account.peerId) var effectiveAuthor: Peer? - let displayAuthorInfo: Bool + var displayAuthorInfo: Bool let messagePeerId: PeerId = chatLocation.peerId ?? content.firstMessage.id.peerId + var headerSeparableThreadId: Int64? + var headerDisplayPeer: ChatMessageDateHeader.PeerData? do { let peerId = messagePeerId @@ -316,6 +319,18 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible } } displayAuthorInfo = incoming && peerId.isGroupOrChannel && effectiveAuthor != nil + + if let channel = content.firstMessage.peers[content.firstMessage.id.peerId] as? TelegramChannel, channel.isMonoForum { + if case .replyThread = chatLocation { + displayAuthorInfo = false + } else { + headerSeparableThreadId = content.firstMessage.threadId + + if let threadId = content.firstMessage.threadId, let peer = content.firstMessage.peers[EnginePeer.Id(threadId)] { + headerDisplayPeer = ChatMessageDateHeader.PeerData(peer: EnginePeer(peer)) + } + } + } } } @@ -326,7 +341,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible isScheduledMessages = true } - self.dateHeader = ChatMessageDateHeader(timestamp: content.index.timestamp, scheduled: isScheduledMessages, presentationData: presentationData, controllerInteraction: controllerInteraction, context: context, action: { timestamp, alreadyThere in + self.dateHeader = ChatMessageDateHeader(timestamp: content.index.timestamp, separableThreadId: nil, scheduled: isScheduledMessages, displayPeer: nil, presentationData: presentationData, controllerInteraction: controllerInteraction, context: context, action: { timestamp, alreadyThere in var calendar = NSCalendar.current calendar.timeZone = TimeZone(abbreviation: "UTC")! let date = Date(timeIntervalSince1970: TimeInterval(timestamp)) @@ -337,6 +352,14 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible } }) + if let headerSeparableThreadId, let headerDisplayPeer { + self.topicHeader = ChatMessageDateHeader(timestamp: content.index.timestamp, separableThreadId: headerSeparableThreadId, scheduled: false, displayPeer: headerDisplayPeer, presentationData: presentationData, controllerInteraction: controllerInteraction, context: context, action: { _, _ in + controllerInteraction.updateChatLocationThread(headerSeparableThreadId) + }) + } else { + self.topicHeader = nil + } + if displayAuthorInfo { let message = content.firstMessage var hasActionMedia = false @@ -367,10 +390,6 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible } } - if let subject = associatedData.subject, case let .customChatContents(contents) = subject, case .postSuggestions = contents.kind { - hasAvatar = false - } - if hasAvatar { if let effectiveAuthor = effectiveAuthor { var storyStats: PeerStoryStats? @@ -393,6 +412,9 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible var headers: [ListViewItemHeader] = [] if !self.disableDate { headers.append(self.dateHeader) + if let topicHeader = self.topicHeader { + headers.append(topicHeader) + } } if case .messageOptions = associatedData.subject { headers = [] @@ -497,7 +519,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible } } - let (layout, apply) = nodeLayout(self, params, top, bottom, dateAtBottom && !disableDate) + let (layout, apply) = nodeLayout(self, params, top, bottom, disableDate ? ChatMessageHeaderSpec(hasDate: false, hasTopic: false) : dateAtBottom) node.contentSize = layout.contentSize node.insets = layout.insets @@ -524,7 +546,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible } } - public func mergedWithItems(top: ListViewItem?, bottom: ListViewItem?, isRotated: Bool) -> (top: ChatMessageMerge, bottom: ChatMessageMerge, dateAtBottom: Bool) { + public func mergedWithItems(top: ListViewItem?, bottom: ListViewItem?, isRotated: Bool) -> (top: ChatMessageMerge, bottom: ChatMessageMerge, dateAtBottom: ChatMessageHeaderSpec) { var top = top var bottom = bottom if !isRotated { @@ -535,7 +557,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible var mergedTop: ChatMessageMerge = .none var mergedBottom: ChatMessageMerge = .none - var dateAtBottom = false + var dateAtBottom = ChatMessageHeaderSpec(hasDate: false, hasTopic: false) if let top = top as? ChatMessageItemImpl { if top.dateHeader.id != self.dateHeader.id { mergedBottom = .none @@ -546,20 +568,35 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible if let bottom = bottom as? ChatMessageItemImpl { if bottom.dateHeader.id != self.dateHeader.id { mergedTop = .none - dateAtBottom = true - } else { + dateAtBottom.hasDate = true + } + if let topicHeader = self.topicHeader, bottom.topicHeader?.id != topicHeader.id { + mergedTop = .none + dateAtBottom.hasTopic = true + } + + if !(dateAtBottom.hasDate || dateAtBottom.hasTopic) { mergedTop = messagesShouldBeMerged(accountPeerId: self.context.account.peerId, bottom.message, message) } } else if let bottom = bottom as? ChatUnreadItem { if bottom.header.id != self.dateHeader.id { - dateAtBottom = true + dateAtBottom.hasDate = true + } + if self.topicHeader != nil { + dateAtBottom.hasTopic = true } } else if let bottom = bottom as? ChatReplyCountItem { if bottom.header.id != self.dateHeader.id { - dateAtBottom = true + dateAtBottom.hasDate = true + } + if self.topicHeader != nil { + dateAtBottom.hasTopic = true } } else { - dateAtBottom = true + dateAtBottom.hasDate = true + if self.topicHeader != nil { + dateAtBottom.hasTopic = true + } } return (mergedTop, mergedBottom, dateAtBottom) @@ -587,7 +624,7 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible } } - let (layout, apply) = nodeLayout(self, params, top, bottom, dateAtBottom && !disableDate) + let (layout, apply) = nodeLayout(self, params, top, bottom, disableDate ? ChatMessageHeaderSpec(hasDate: false, hasTopic: false) : dateAtBottom) Queue.mainQueue().async { completion(layout, { info in apply(animation, info, false) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatReplyCountItem.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatReplyCountItem.swift index aa9b14c971..3a193abfdd 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatReplyCountItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatReplyCountItem.swift @@ -25,7 +25,7 @@ public class ChatReplyCountItem: ListViewItem { self.isComments = isComments self.count = count self.presentationData = presentationData - self.header = ChatMessageDateHeader(timestamp: index.timestamp, scheduled: false, presentationData: presentationData, controllerInteraction: controllerInteraction, context: context) + self.header = ChatMessageDateHeader(timestamp: index.timestamp, separableThreadId: nil, scheduled: false, displayPeer: nil, presentationData: presentationData, controllerInteraction: controllerInteraction, context: context) self.controllerInteraction = controllerInteraction } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatUnreadItem.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatUnreadItem.swift index 28e53f9b3a..0865ae6cfc 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatUnreadItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatUnreadItem.swift @@ -22,7 +22,7 @@ public class ChatUnreadItem: ListViewItem { self.index = index self.presentationData = presentationData self.controllerInteraction = controllerInteraction - self.header = ChatMessageDateHeader(timestamp: index.timestamp, scheduled: false, presentationData: presentationData, controllerInteraction: controllerInteraction, context: context) + self.header = ChatMessageDateHeader(timestamp: index.timestamp, separableThreadId: nil, scheduled: false, displayPeer: nil, presentationData: presentationData, controllerInteraction: controllerInteraction, context: context) } public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift index 346ac78203..b8bcac5dac 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemView/Sources/ChatMessageItemView.swift @@ -716,7 +716,7 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { } } - open func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { + open func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: ChatMessageHeaderSpec) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { return { _, _, _, _, _ in return (ListViewItemNodeLayout(contentSize: CGSize(width: 32.0, height: 32.0), insets: UIEdgeInsets()), { _, _, _ in @@ -901,6 +901,9 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { } private var attachedAvatarNodeOffset: CGFloat = 0.0 + private var attachedAvatarNodeIsHidden: Bool = false + + private var attachedDateHeader: (hasDate: Bool, hasPeer: Bool) = (false, false) override open func attachedHeaderNodesUpdated() { if !self.attachedAvatarNodeOffset.isZero { @@ -912,6 +915,18 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { } } } + + for headerNode in self.attachedHeaderNodes { + if let headerNode = headerNode as? ChatMessageAvatarHeaderNode { + headerNode.updateAvatarIsHidden(isHidden: self.attachedAvatarNodeIsHidden, transition: .immediate) + } + } + + for headerNode in self.attachedHeaderNodes { + if let headerNode = headerNode as? ChatMessageDateHeaderNode { + headerNode.updateItem(hasDate: self.attachedDateHeader.hasDate, hasPeer: self.attachedDateHeader.hasPeer) + } + } } open func updateAttachedAvatarNodeOffset(offset: CGFloat, transition: ContainedViewLayoutTransition) { @@ -923,6 +938,24 @@ open class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol { } } + open func updateAttachedAvatarNodeIsHidden(isHidden: Bool, transition: ContainedViewLayoutTransition) { + self.attachedAvatarNodeIsHidden = isHidden + for headerNode in self.attachedHeaderNodes { + if let headerNode = headerNode as? ChatMessageAvatarHeaderNode { + headerNode.updateAvatarIsHidden(isHidden: self.attachedAvatarNodeIsHidden, transition: transition) + } + } + } + + open func updateAttachedDateHeader(hasDate: Bool, hasPeer: Bool) { + self.attachedDateHeader = (hasDate, hasPeer) + for headerNode in self.attachedHeaderNodes { + if let headerNode = headerNode as? ChatMessageDateHeaderNode { + headerNode.updateItem(hasDate: hasDate, hasPeer: hasPeer) + } + } + } + open func unreadMessageRangeUpdated() { } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageShareButton/Sources/ChatMessageShareButton.swift b/submodules/TelegramUI/Components/Chat/ChatMessageShareButton/Sources/ChatMessageShareButton.swift index 16d3d6d133..502bd18b5b 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageShareButton/Sources/ChatMessageShareButton.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageShareButton/Sources/ChatMessageShareButton.swift @@ -105,14 +105,19 @@ public class ChatMessageShareButton: ASDisplayNode { public func update(presentationData: ChatPresentationData, controllerInteraction: ChatControllerInteraction, chatLocation: ChatLocation, subject: ChatControllerSubject?, message: Message, account: Account, disableComments: Bool = false) -> CGSize { var isReplies = false + var isNavigate = false var replyCount = 0 - if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { - for attribute in message.attributes { - if let attribute = attribute as? ReplyThreadMessageAttribute { - replyCount = Int(attribute.count) - isReplies = true - break + if let channel = message.peers[message.id.peerId] as? TelegramChannel { + if case .broadcast = channel.info { + for attribute in message.attributes { + if let attribute = attribute as? ReplyThreadMessageAttribute { + replyCount = Int(attribute.count) + isReplies = true + break + } } + } else if channel.isMonoForum, case .peer = chatLocation { + isNavigate = true } } if case let .replyThread(replyThreadMessage) = chatLocation, replyThreadMessage.effectiveTopId == message.id { @@ -147,6 +152,9 @@ public class ChatMessageShareButton: ASDisplayNode { } else if case let .customChatContents(contents) = subject, case .hashTagSearch = contents.kind { updatedIconImage = PresentationResourcesChat.chatFreeNavigateButtonIcon(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) updatedIconOffset = CGPoint(x: UIScreenPixel, y: 1.0) + } else if isNavigate { + updatedIconImage = PresentationResourcesChat.chatFreeNavigateToThreadButtonIcon(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) + updatedIconOffset = CGPoint(x: UIScreenPixel, y: -3.0) } else if case .pinnedMessages = subject { updatedIconImage = PresentationResourcesChat.chatFreeNavigateButtonIcon(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) updatedIconOffset = CGPoint(x: UIScreenPixel, y: 1.0) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift index a2228c18aa..21d4c80c12 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageStickerItemNode/Sources/ChatMessageStickerItemNode.swift @@ -417,7 +417,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { } } - override public func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { + override public func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: ChatMessageHeaderSpec) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { let displaySize = CGSize(width: 184.0, height: 184.0) let telegramFile = self.telegramFile let layoutConstants = self.layoutConstants @@ -435,7 +435,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { let currentShareButtonNode = self.shareButtonNode let currentForwardInfo = self.appliedForwardInfo - func continueAsyncLayout(_ weakSelf: Weak, _ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { + func continueAsyncLayout(_ weakSelf: Weak, _ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: ChatMessageHeaderSpec) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) { let accessibilityData = ChatMessageAccessibilityData(item: item, isSelected: nil) let layoutConstants = chatMessageItemLayoutConstants(layoutConstants, params: params, presentationData: item.presentationData) @@ -567,8 +567,15 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { } var layoutInsets = UIEdgeInsets(top: mergedTop.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, left: 0.0, bottom: mergedBottom.merged ? layoutConstants.bubble.mergedSpacing : layoutConstants.bubble.defaultSpacing, right: 0.0) - if dateHeaderAtBottom { - layoutInsets.top += layoutConstants.timestampHeaderHeight + if dateHeaderAtBottom.hasDate && dateHeaderAtBottom.hasTopic { + layoutInsets.top += layoutConstants.timestampDateAndTopicHeaderHeight + } else { + if dateHeaderAtBottom.hasDate { + layoutInsets.top += layoutConstants.timestampHeaderHeight + } + if dateHeaderAtBottom.hasTopic { + layoutInsets.top += layoutConstants.timestampHeaderHeight + } } var deliveryFailedInset: CGFloat = 0.0 @@ -964,6 +971,8 @@ public class ChatMessageStickerItemNode: ChatMessageItemView { strongSelf.appliedForwardInfo = (forwardSource, forwardAuthorSignature) strongSelf.updateAccessibilityData(accessibilityData) + strongSelf.updateAttachedDateHeader(hasDate: dateHeaderAtBottom.hasDate, hasPeer: dateHeaderAtBottom.hasTopic) + transition.updateFrame(node: strongSelf.imageNode, frame: updatedImageFrame) strongSelf.enableSynchronousImageApply = true imageApply() diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift index 1e0dd952d7..0fc2b9719f 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift @@ -734,7 +734,21 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { spoilerTextColor: messageTheme.primaryTextColor, spoilerEffectColor: messageTheme.secondaryTextColor, areContentAnimationsEnabled: item.context.sharedContext.energyUsageSettings.loopEmoji, - spoilerExpandRect: spoilerExpandRect + spoilerExpandRect: spoilerExpandRect, + crossfadeContents: { [weak strongSelf] sourceView in + guard let strongSelf else { + return + } + if let textNodeContainer = strongSelf.textNode.textNode.view.superview { + sourceView.frame = CGRect(origin: strongSelf.textNode.textNode.frame.origin, size: sourceView.bounds.size) + textNodeContainer.addSubview(sourceView) + + sourceView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.12, removeOnCompletion: false, completion: { [weak sourceView] _ in + sourceView?.removeFromSuperview() + }) + strongSelf.textNode.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1) + } + } ) )) animation.animator.updateFrame(layer: strongSelf.textNode.textNode.layer, frame: textFrame, completion: nil) diff --git a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift index 2937054d2a..c3aa582cac 100644 --- a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift @@ -646,6 +646,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { }, forceUpdateWarpContents: { }, playShakeAnimation: { }, displayQuickShare: { _, _ ,_ in + }, updateChatLocationThread: { _ in }, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: self.backgroundNode)) self.controllerInteraction = controllerInteraction @@ -1288,7 +1289,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { if let photoRepresentation = invite.photoRepresentation { photo.append(photoRepresentation) } - let channel = TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(0)), accessHash: .genericPublic(0), title: invite.title, username: nil, photo: photo, creationDate: 0, version: 0, participationStatus: .left, info: .broadcast(TelegramChannelBroadcastInfo(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: invite.nameColor, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil) + let channel = TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(0)), accessHash: .genericPublic(0), title: invite.title, username: nil, photo: photo, creationDate: 0, version: 0, participationStatus: .left, info: .broadcast(TelegramChannelBroadcastInfo(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: invite.nameColor, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil) let invoice = TelegramMediaInvoice(title: "", description: "", photo: nil, receiptMessageId: nil, currency: "XTR", totalAmount: subscriptionPricing.amount.value, startParam: "", extendedMedia: nil, subscriptionPeriod: nil, flags: [], version: 0) inputData.set(.single(BotCheckoutController.InputData( diff --git a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsHistoryTransition.swift b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsHistoryTransition.swift index 30cff91d9b..ffb9fba05b 100644 --- a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsHistoryTransition.swift +++ b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsHistoryTransition.swift @@ -87,7 +87,7 @@ private func filterOriginalMessageFlags(_ message: Message) -> Message { private func filterMessageChannelPeer(_ peer: Peer) -> Peer { if let peer = peer as? TelegramChannel { - return TelegramChannel(id: peer.id, accessHash: peer.accessHash, title: peer.title, username: peer.username, photo: peer.photo, creationDate: peer.creationDate, version: peer.version, participationStatus: peer.participationStatus, info: .group(TelegramChannelGroupInfo(flags: [])), flags: peer.flags, restrictionInfo: peer.restrictionInfo, adminRights: peer.adminRights, bannedRights: peer.bannedRights, defaultBannedRights: peer.defaultBannedRights, usernames: peer.usernames, storiesHidden: peer.storiesHidden, nameColor: peer.nameColor, backgroundEmojiId: peer.backgroundEmojiId, profileColor: peer.profileColor, profileBackgroundEmojiId: peer.profileBackgroundEmojiId, emojiStatus: peer.emojiStatus, approximateBoostLevel: peer.approximateBoostLevel, subscriptionUntilDate: peer.subscriptionUntilDate, verificationIconFileId: peer.verificationIconFileId, sendPaidMessageStars: peer.sendPaidMessageStars) + return TelegramChannel(id: peer.id, accessHash: peer.accessHash, title: peer.title, username: peer.username, photo: peer.photo, creationDate: peer.creationDate, version: peer.version, participationStatus: peer.participationStatus, info: .group(TelegramChannelGroupInfo(flags: [])), flags: peer.flags, restrictionInfo: peer.restrictionInfo, adminRights: peer.adminRights, bannedRights: peer.bannedRights, defaultBannedRights: peer.defaultBannedRights, usernames: peer.usernames, storiesHidden: peer.storiesHidden, nameColor: peer.nameColor, backgroundEmojiId: peer.backgroundEmojiId, profileColor: peer.profileColor, profileBackgroundEmojiId: peer.profileBackgroundEmojiId, emojiStatus: peer.emojiStatus, approximateBoostLevel: peer.approximateBoostLevel, subscriptionUntilDate: peer.subscriptionUntilDate, verificationIconFileId: peer.verificationIconFileId, sendPaidMessageStars: peer.sendPaidMessageStars, linkedMonoforumId: peer.linkedMonoforumId) } return peer } diff --git a/submodules/TelegramUI/Components/Chat/ChatSendAudioMessageContextPreview/Sources/ChatSendAudioMessageContextPreview.swift b/submodules/TelegramUI/Components/Chat/ChatSendAudioMessageContextPreview/Sources/ChatSendAudioMessageContextPreview.swift index 9e7d3345f7..fb77a9c14a 100644 --- a/submodules/TelegramUI/Components/Chat/ChatSendAudioMessageContextPreview/Sources/ChatSendAudioMessageContextPreview.swift +++ b/submodules/TelegramUI/Components/Chat/ChatSendAudioMessageContextPreview/Sources/ChatSendAudioMessageContextPreview.swift @@ -501,6 +501,7 @@ public final class ChatSendGroupMediaMessageContextPreview: UIView, ChatSendMess }, forceUpdateWarpContents: { }, playShakeAnimation: { }, displayQuickShare: { _, _ ,_ in + }, updateChatLocationThread: { _ in }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: self.context, backgroundNode: self.wallpaperBackgroundNode)) diff --git a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift index 88cc604f04..0e05b95c73 100644 --- a/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift +++ b/submodules/TelegramUI/Components/Chat/ChatSideTopicsPanel/Sources/ChatSideTopicsPanel.swift @@ -239,6 +239,7 @@ public final class ChatSideTopicsPanel: Component { avatarNode = current } else { avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 11.0)) + avatarNode.isUserInteractionEnabled = false self.avatarNode = avatarNode self.containerButton.addSubview(avatarNode.view) } @@ -355,7 +356,7 @@ public final class ChatSideTopicsPanel: Component { let iconSize = self.icon.update( transition: .immediate, component: AnyComponent(BundleIconComponent( - name: "Call/PanelIcon", + name: "Chat/Title Panels/SidebarIcon", tintColor: theme.rootController.navigationBar.accentTextColor, maxSize: nil, scaleFactor: 1.0 @@ -364,7 +365,7 @@ public final class ChatSideTopicsPanel: Component { containerSize: CGSize(width: 100.0, height: 100.0) ) - let topInset: CGFloat = 12.0 + let topInset: CGFloat = 10.0 let bottomInset: CGFloat = 12.0 let contentSize: CGFloat = topInset + iconSize.height + bottomInset @@ -578,7 +579,6 @@ public final class ChatSideTopicsPanel: Component { self.scrollView.alwaysBounceHorizontal = false self.scrollView.alwaysBounceVertical = false self.scrollView.scrollsToTop = false - //self.scrollView.delegate = self.wrappedScrollViewDelegate self.addSubview(self.scrollView) self.scrollView.addSubview(self.selectedLineView) @@ -591,6 +591,24 @@ public final class ChatSideTopicsPanel: Component { deinit { self.itemsDisposable?.dispose() } + + public func updateGlobalOffset(globalOffset: CGFloat, transition: ComponentTransition) { + if let tabItemView = self.tabItemView { + transition.setTransform(view: tabItemView, transform: CATransform3DMakeTranslation(-globalOffset, 0.0, 0.0)) + } + } + + public func topicIndex(threadId: Int64?) -> Int? { + if let threadId { + if let value = self.items.firstIndex(where: { $0.id == .chatList(PeerId(threadId)) }) { + return value + 1 + } else { + return nil + } + } else { + return 0 + } + } func update(component: ChatSideTopicsPanel, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { self.isUpdating = true @@ -774,6 +792,7 @@ public final class ChatSideTopicsPanel: Component { } contentSize.height += itemSize.height + contentSize.height -= 20.0 } do { diff --git a/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift b/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift index b42b850c86..ec77cd376e 100644 --- a/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift +++ b/submodules/TelegramUI/Components/ChatControllerInteraction/Sources/ChatControllerInteraction.swift @@ -271,7 +271,6 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol public let sendGift: (EnginePeer.Id) -> Void public let openUniqueGift: (String) -> Void public let openMessageFeeException: () -> Void - public let requestMessageUpdate: (MessageId, Bool) -> Void public let cancelInteractiveKeyboardGestures: () -> Void public let dismissTextInput: () -> Void @@ -281,6 +280,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol public let forceUpdateWarpContents: () -> Void public let playShakeAnimation: () -> Void public let displayQuickShare: (MessageId, ASDisplayNode, ContextGesture) -> Void + public let updateChatLocationThread: (Int64?) -> Void public var canPlayMedia: Bool = false public var hiddenMedia: [MessageId: [Media]] = [:] @@ -328,6 +328,8 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol } } + public var isSidePanelOpen: Bool = false + public init( openMessage: @escaping (Message, OpenMessageParams) -> Bool, openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, OpenPeerSource) -> Void, @@ -441,6 +443,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol forceUpdateWarpContents: @escaping () -> Void, playShakeAnimation: @escaping () -> Void, displayQuickShare: @escaping (MessageId, ASDisplayNode, ContextGesture) -> Void, + updateChatLocationThread: @escaping (Int64?) -> Void, automaticMediaDownloadSettings: MediaAutoDownloadSettings, pollActionState: ChatInterfacePollActionState, stickerSettings: ChatInterfaceStickerSettings, @@ -559,6 +562,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol self.forceUpdateWarpContents = forceUpdateWarpContents self.playShakeAnimation = playShakeAnimation self.displayQuickShare = displayQuickShare + self.updateChatLocationThread = updateChatLocationThread self.automaticMediaDownloadSettings = automaticMediaDownloadSettings diff --git a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift index cea4348d69..2413db2468 100644 --- a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift +++ b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift @@ -1816,8 +1816,6 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { case .businessLinkSetup: stickerContent = nil gifContent = nil - case .postSuggestions: - break } } diff --git a/submodules/TelegramUI/Components/FullScreenEffectView/BUILD b/submodules/TelegramUI/Components/FullScreenEffectView/BUILD index 75349b1053..afc8189acc 100644 --- a/submodules/TelegramUI/Components/FullScreenEffectView/BUILD +++ b/submodules/TelegramUI/Components/FullScreenEffectView/BUILD @@ -44,7 +44,7 @@ filegroup( name = "FullScreenEffectViewResources", srcs = glob([ "Resources/**/*", - ], exclude = ["Resources/**/.*"]), + ], allow_empty=True, exclude = ["Resources/**/.*"]), visibility = ["//visibility:public"], ) diff --git a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftTransferAlertController.swift b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftTransferAlertController.swift index ccfb5f2d93..986e0dbfc5 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftTransferAlertController.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftTransferAlertController.swift @@ -201,7 +201,6 @@ private final class GiftTransferAlertContentNode: AlertContentNode { let maxActionWidth: CGFloat = floor(size.width / CGFloat(self.actionNodes.count)) let actionTitleInsets: CGFloat = 8.0 - let effectiveActionLayout = TextAlertContentActionLayout.vertical for actionNode in self.actionNodes { let actionTitleSize = actionNode.titleNode.updateLayout(CGSize(width: maxActionWidth, height: actionButtonHeight)) minActionsWidth = max(minActionsWidth, actionTitleSize.width + actionTitleInsets) @@ -217,39 +216,42 @@ private final class GiftTransferAlertContentNode: AlertContentNode { transition.updateFrame(node: self.actionNodesSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight - UIScreenPixel), size: CGSize(width: resultSize.width, height: UIScreenPixel))) var actionOffset: CGFloat = 0.0 - let actionWidth: CGFloat = floor(resultSize.width / CGFloat(self.actionNodes.count)) + //let actionWidth: CGFloat = floor(resultSize.width / CGFloat(self.actionNodes.count)) var separatorIndex = -1 var nodeIndex = 0 for actionNode in self.actionNodes { if separatorIndex >= 0 { let separatorNode = self.actionVerticalSeparators[separatorIndex] - switch effectiveActionLayout { + /*switch effectiveActionLayout { case .horizontal: transition.updateFrame(node: separatorNode, frame: CGRect(origin: CGPoint(x: actionOffset - UIScreenPixel, y: resultSize.height - actionsHeight), size: CGSize(width: UIScreenPixel, height: actionsHeight - UIScreenPixel))) - case .vertical: + case .vertical:*/ + do { transition.updateFrame(node: separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight + actionOffset - UIScreenPixel), size: CGSize(width: resultSize.width, height: UIScreenPixel))) } } separatorIndex += 1 let currentActionWidth: CGFloat - switch effectiveActionLayout { + /*switch effectiveActionLayout { case .horizontal: if nodeIndex == self.actionNodes.count - 1 { currentActionWidth = resultSize.width - actionOffset } else { currentActionWidth = actionWidth } - case .vertical: + case .vertical:*/ + do { currentActionWidth = resultSize.width } let actionNodeFrame: CGRect - switch effectiveActionLayout { + /*switch effectiveActionLayout { case .horizontal: actionNodeFrame = CGRect(origin: CGPoint(x: actionOffset, y: resultSize.height - actionsHeight), size: CGSize(width: currentActionWidth, height: actionButtonHeight)) actionOffset += currentActionWidth - case .vertical: + case .vertical:*/ + do { actionNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight + actionOffset), size: CGSize(width: currentActionWidth, height: actionButtonHeight)) actionOffset += actionButtonHeight } diff --git a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftWithdrawAlertController.swift b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftWithdrawAlertController.swift index 517e0a777d..9e00be92f4 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftWithdrawAlertController.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftWithdrawAlertController.swift @@ -207,7 +207,11 @@ private final class GiftWithdrawAlertContentNode: AlertContentNode { let maxActionWidth: CGFloat = floor(size.width / CGFloat(self.actionNodes.count)) let actionTitleInsets: CGFloat = 8.0 - let effectiveActionLayout = TextAlertContentActionLayout.vertical + var effectiveActionLayout = TextAlertContentActionLayout.vertical + if !"".isEmpty { + // Silence the warning + effectiveActionLayout = .horizontal + } for actionNode in self.actionNodes { let actionTitleSize = actionNode.titleNode.updateLayout(CGSize(width: maxActionWidth, height: actionButtonHeight)) minActionsWidth = max(minActionsWidth, actionTitleSize.width + actionTitleInsets) diff --git a/submodules/TelegramUI/Components/InteractiveTextComponent/Sources/InteractiveTextComponent.swift b/submodules/TelegramUI/Components/InteractiveTextComponent/Sources/InteractiveTextComponent.swift index db6bb21216..e11c583606 100644 --- a/submodules/TelegramUI/Components/InteractiveTextComponent/Sources/InteractiveTextComponent.swift +++ b/submodules/TelegramUI/Components/InteractiveTextComponent/Sources/InteractiveTextComponent.swift @@ -1099,19 +1099,22 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn public let spoilerEffectColor: UIColor public let areContentAnimationsEnabled: Bool public let spoilerExpandRect: CGRect? + public var crossfadeContents: ((UIView) -> Void)? public init( animation: ListViewItemUpdateAnimation, spoilerTextColor: UIColor, spoilerEffectColor: UIColor, areContentAnimationsEnabled: Bool, - spoilerExpandRect: CGRect? + spoilerExpandRect: CGRect?, + crossfadeContents: ((UIView) -> Void)? = nil ) { self.animation = animation self.spoilerTextColor = spoilerTextColor self.spoilerEffectColor = spoilerEffectColor self.areContentAnimationsEnabled = areContentAnimationsEnabled self.spoilerExpandRect = spoilerExpandRect + self.crossfadeContents = crossfadeContents } } diff --git a/submodules/TelegramUI/Components/InteractiveTextComponent/Sources/InteractiveTextNodeWithEntities.swift b/submodules/TelegramUI/Components/InteractiveTextComponent/Sources/InteractiveTextNodeWithEntities.swift index 1949e4f8c6..4d4c9e26c8 100644 --- a/submodules/TelegramUI/Components/InteractiveTextComponent/Sources/InteractiveTextNodeWithEntities.swift +++ b/submodules/TelegramUI/Components/InteractiveTextComponent/Sources/InteractiveTextNodeWithEntities.swift @@ -216,9 +216,14 @@ public final class InteractiveTextNodeWithEntities { return (layout, { applyArguments in let animation: ListViewItemUpdateAnimation = applyArguments.applyArguments.animation + var crossfadeSourceView: UIView? + if let maybeNode, applyArguments.applyArguments.animation.transition.isAnimated, let animator = applyArguments.applyArguments.animation.animator as? ControlledTransition.LegacyAnimator, animator.transition.isAnimated, maybeNode.textNode.bounds.size != layout.size { + crossfadeSourceView = maybeNode.textNode.view.snapshotView(afterScreenUpdates: false) + } + let result = apply(applyArguments.applyArguments) - if let maybeNode = maybeNode { + if let maybeNode { maybeNode.attributedString = arguments.attributedString maybeNode.updateInteractiveContents( @@ -234,6 +239,10 @@ public final class InteractiveTextNodeWithEntities { applyArguments: applyArguments.applyArguments ) + if let crossfadeSourceView { + applyArguments.applyArguments.crossfadeContents?(crossfadeSourceView) + } + return maybeNode } else { let resultNode = InteractiveTextNodeWithEntities(textNode: result) diff --git a/submodules/TelegramUI/Components/MediaEditor/Sources/DrawingMessageRenderer.swift b/submodules/TelegramUI/Components/MediaEditor/Sources/DrawingMessageRenderer.swift index acf33642b9..4a57e7cefd 100644 --- a/submodules/TelegramUI/Components/MediaEditor/Sources/DrawingMessageRenderer.swift +++ b/submodules/TelegramUI/Components/MediaEditor/Sources/DrawingMessageRenderer.swift @@ -326,7 +326,7 @@ public final class DrawingMessageRenderer { } avatarHeaderNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 3.0), size: CGSize(width: layout.size.width, height: avatarHeaderItem.height)) - avatarHeaderNode.updateLayout(size: size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right) + avatarHeaderNode.updateLayout(size: size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: .immediate) } var finalWidth: CGFloat = width diff --git a/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift b/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift index 6c70ad4e9c..a75a51de5f 100644 --- a/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift +++ b/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift @@ -332,7 +332,7 @@ private func notificationsPeerCategoryEntries(peerId: EnginePeer.Id, notificatio } } existingThreadIds.insert(value.threadId) - entries.append(.exception(Int32(index), presentationData.dateTimeFormat, presentationData.nameDisplayOrder, .channel(TelegramChannel(id: peerId, accessHash: nil, title: "", username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(TelegramChannelGroupInfo(flags: [])), flags: [.isForum], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil)), value.threadId, value.info, title, value.notificationSettings._asNotificationSettings(), state.editing, state.revealedThreadId == value.threadId)) + entries.append(.exception(Int32(index), presentationData.dateTimeFormat, presentationData.nameDisplayOrder, .channel(TelegramChannel(id: peerId, accessHash: nil, title: "", username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(TelegramChannelGroupInfo(flags: [])), flags: [.isForum], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil)), value.threadId, value.info, title, value.notificationSettings._asNotificationSettings(), state.editing, state.revealedThreadId == value.threadId)) index += 1 } diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index b6638b9372..2db2475d9d 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -3790,6 +3790,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro }, forceUpdateWarpContents: { }, playShakeAnimation: { }, displayQuickShare: { _, _ ,_ in + }, updateChatLocationThread: { _ in }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil)) self.hiddenMediaDisposable = context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().startStrict(next: { [weak self] ids in diff --git a/submodules/TelegramUI/Components/PeerInfo/PostSuggestionsSettingsScreen/Sources/PostSuggestionsChatContents.swift b/submodules/TelegramUI/Components/PeerInfo/PostSuggestionsSettingsScreen/Sources/PostSuggestionsChatContents.swift deleted file mode 100644 index 462c656fd4..0000000000 --- a/submodules/TelegramUI/Components/PeerInfo/PostSuggestionsSettingsScreen/Sources/PostSuggestionsChatContents.swift +++ /dev/null @@ -1,153 +0,0 @@ -import Foundation -import UIKit -import SwiftSignalKit -import Postbox -import TelegramCore -import AccountContext - -public final class PostSuggestionsChatContents: ChatCustomContentsProtocol { - private final class Impl { - let queue: Queue - let context: AccountContext - - private var peerId: EnginePeer.Id - - private(set) var mergedHistoryView: MessageHistoryView? - private var sourceHistoryView: MessageHistoryView? - - private var historyViewDisposable: Disposable? - private var pendingHistoryViewDisposable: Disposable? - let historyViewStream = ValuePipe<(MessageHistoryView, ViewUpdateType)>() - private var nextUpdateIsHoleFill: Bool = false - - init(queue: Queue, context: AccountContext, peerId: EnginePeer.Id) { - self.queue = queue - self.context = context - self.peerId = peerId - - self.updateHistoryViewRequest(reload: false) - } - - deinit { - self.historyViewDisposable?.dispose() - self.pendingHistoryViewDisposable?.dispose() - } - - private func updateHistoryViewRequest(reload: Bool) { - self.pendingHistoryViewDisposable?.dispose() - self.pendingHistoryViewDisposable = nil - - if self.historyViewDisposable == nil || reload { - self.historyViewDisposable?.dispose() - - self.historyViewDisposable = (self.context.account.viewTracker.postSuggestionsViewForLocation(peerId: self.peerId) - |> deliverOn(self.queue)).start(next: { [weak self] view, update, _ in - guard let self else { - return - } - if update == .FillHole { - self.nextUpdateIsHoleFill = true - self.updateHistoryViewRequest(reload: true) - return - } - - let nextUpdateIsHoleFill = self.nextUpdateIsHoleFill - self.nextUpdateIsHoleFill = false - - self.sourceHistoryView = view - - self.updateHistoryView(updateType: nextUpdateIsHoleFill ? .FillHole : .Generic) - }) - } - } - - private func updateHistoryView(updateType: ViewUpdateType) { - var entries = self.sourceHistoryView?.entries ?? [] - entries.sort(by: { $0.message.index < $1.message.index }) - - let mergedHistoryView = MessageHistoryView(tag: nil, namespaces: .just(Namespaces.Message.allSuggestedPost), entries: entries, holeEarlier: false, holeLater: false, isLoading: false) - self.mergedHistoryView = mergedHistoryView - - self.historyViewStream.putNext((mergedHistoryView, updateType)) - } - - func enqueueMessages(messages: [EnqueueMessage]) { - let _ = (TelegramCore.enqueueMessages(account: self.context.account, peerId: self.peerId, messages: messages.compactMap { message -> EnqueueMessage? in - if !message.attributes.contains(where: { $0 is OutgoingSuggestedPostMessageAttribute }) { - return nil - } - return message - }) - |> deliverOn(self.queue)).startStandalone() - } - - func deleteMessages(ids: [EngineMessage.Id]) { - let _ = self.context.engine.messages.deleteMessagesInteractively(messageIds: ids, type: .forEveryone).startStandalone() - } - - func editMessage(id: EngineMessage.Id, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, webpagePreviewAttribute: WebpagePreviewMessageAttribute?, disableUrlPreview: Bool) { - } - } - - public let peerId: EnginePeer.Id - public var kind: ChatCustomContentsKind - - public var historyView: Signal<(MessageHistoryView, ViewUpdateType), NoError> { - return self.impl.signalWith({ impl, subscriber in - if let mergedHistoryView = impl.mergedHistoryView { - subscriber.putNext((mergedHistoryView, .Initial)) - } - return impl.historyViewStream.signal().start(next: subscriber.putNext) - }) - } - - public var messageLimit: Int? { - return 20 - } - - private let queue: Queue - private let impl: QueueLocalObject - - public init(context: AccountContext, peerId: EnginePeer.Id) { - self.peerId = peerId - self.kind = .postSuggestions(price: StarsAmount(value: 250, nanos: 0)) - - let queue = Queue() - self.queue = queue - self.impl = QueueLocalObject(queue: queue, generate: { - return Impl(queue: queue, context: context, peerId: peerId) - }) - } - - public func enqueueMessages(messages: [EnqueueMessage]) { - self.impl.with { impl in - impl.enqueueMessages(messages: messages) - } - } - - public func deleteMessages(ids: [EngineMessage.Id]) { - self.impl.with { impl in - impl.deleteMessages(ids: ids) - } - } - - public func editMessage(id: EngineMessage.Id, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, webpagePreviewAttribute: WebpagePreviewMessageAttribute?, disableUrlPreview: Bool) { - self.impl.with { impl in - impl.editMessage(id: id, text: text, media: media, entities: entities, webpagePreviewAttribute: webpagePreviewAttribute, disableUrlPreview: disableUrlPreview) - } - } - - public func quickReplyUpdateShortcut(value: String) { - } - - public func businessLinkUpdate(message: String, entities: [MessageTextEntity], title: String?) { - } - - public func loadMore() { - } - - public func hashtagSearchUpdate(query: String) { - } - - public var hashtagSearchResultsUpdate: ((SearchMessagesResult, SearchMessagesState)) -> Void = { _ in } -} diff --git a/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/AutomaticBusinessMessageSetupChatContents.swift b/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/AutomaticBusinessMessageSetupChatContents.swift index 54794848fd..c8c10bdc99 100644 --- a/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/AutomaticBusinessMessageSetupChatContents.swift +++ b/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/AutomaticBusinessMessageSetupChatContents.swift @@ -211,8 +211,6 @@ final class AutomaticBusinessMessageSetupChatContents: ChatCustomContentsProtoco initialShortcut = "" case .hashTagSearch: initialShortcut = "" - case .postSuggestions: - initialShortcut = "" } let queue = Queue() @@ -251,8 +249,6 @@ final class AutomaticBusinessMessageSetupChatContents: ChatCustomContentsProtoco break case .hashTagSearch: break - case .postSuggestions: - break } } diff --git a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorChatPreviewItem.swift b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorChatPreviewItem.swift index 221bd2b1a3..f59ec62296 100644 --- a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorChatPreviewItem.swift +++ b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorChatPreviewItem.swift @@ -337,8 +337,8 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode { header.updateNode(headerNode, previous: nil, next: nil) headerNode.item = header } - headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset) - headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, transition: .immediate) + headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset, transition: .immediate) + headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, distance: 0.0, transition: .immediate) } else { headerNode = header.node(synchronousLoad: true) if headerNode.item !== header { @@ -346,11 +346,11 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode { headerNode.item = header } headerNode.frame = headerFrame - headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset) + headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset, transition: .immediate) strongSelf.itemHeaderNodes[id] = headerNode strongSelf.containerNode.addSubnode(headerNode) - headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, transition: .immediate) + headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, distance: 0.0, transition: .immediate) } } } diff --git a/submodules/TelegramUI/Components/Settings/ThemeAccentColorScreen/Sources/ThemeAccentColorControllerNode.swift b/submodules/TelegramUI/Components/Settings/ThemeAccentColorScreen/Sources/ThemeAccentColorControllerNode.swift index 673e91f7e2..24fad05cc3 100644 --- a/submodules/TelegramUI/Components/Settings/ThemeAccentColorScreen/Sources/ThemeAccentColorControllerNode.swift +++ b/submodules/TelegramUI/Components/Settings/ThemeAccentColorScreen/Sources/ThemeAccentColorControllerNode.swift @@ -963,7 +963,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, ASScrollViewDelegate let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) - let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil)) + let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil)) let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)) @@ -1180,7 +1180,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, ASScrollViewDelegate } transition.updateFrame(node: dateHeaderNode, frame: CGRect(origin: CGPoint(x: 0.0, y: bottomOffset), size: CGSize(width: layout.size.width, height: headerItem.height))) - dateHeaderNode.updateLayout(size: self.messagesContainerNode.frame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right) + dateHeaderNode.updateLayout(size: self.messagesContainerNode.frame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: .immediate) } func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { diff --git a/submodules/TelegramUI/Components/SpaceWarpView/STCMeshView/BUILD b/submodules/TelegramUI/Components/SpaceWarpView/STCMeshView/BUILD index 0c1146bbcc..edab36b4b8 100644 --- a/submodules/TelegramUI/Components/SpaceWarpView/STCMeshView/BUILD +++ b/submodules/TelegramUI/Components/SpaceWarpView/STCMeshView/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Title Panels/SidebarIcon.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Title Panels/SidebarIcon.imageset/Contents.json new file mode 100644 index 0000000000..de77409537 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Title Panels/SidebarIcon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "list_24.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Title Panels/SidebarIcon.imageset/list_24.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Title Panels/SidebarIcon.imageset/list_24.pdf new file mode 100644 index 0000000000..5b9942caa1 Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat/Title Panels/SidebarIcon.imageset/list_24.pdf differ diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index c22df4eb3e..76ffbe7991 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -2400,30 +2400,33 @@ private func extractAccountManagerState(records: AccountRecordsView Signal { diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift index d1e97ab6bb..f492488a24 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift @@ -403,10 +403,14 @@ extension ChatControllerImpl { } else { messageOptionsTitleInfo = .single(nil) } - + + var isFirstTimeValue = true self.titleDisposable.set((combineLatest(queue: Queue.mainQueue(), peerView.get(), onlineMemberCount, displayedCountSignal, subtitleTextSignal, self.presentationInterfaceStatePromise.get(), hasPeerInfo, messageOptionsTitleInfo) |> deliverOnMainQueue).startStrict(next: { [weak self] peerView, onlineMemberCount, displayedCount, subtitleText, presentationInterfaceState, hasPeerInfo, messageOptionsTitleInfo in if let strongSelf = self { + let isFirstTime = isFirstTimeValue + isFirstTimeValue = false + var isScheduledMessages = false if case .scheduledMessages = presentationInterfaceState.subject { isScheduledMessages = true @@ -446,6 +450,8 @@ extension ChatControllerImpl { } else if let peer = peerViewMainPeer(peerView) { if case .pinnedMessages = presentationInterfaceState.subject { strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Chat_TitlePinnedMessages(Int32(displayedCount ?? 1)), nil, false) + } else if let channel = peer as? TelegramChannel, channel.isMonoForum { + strongSelf.chatTitleView?.titleContent = .custom(channel.debugDisplayTitle, nil, false) } else { strongSelf.chatTitleView?.titleContent = .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: nil, onlineMemberCount: onlineMemberCount, isScheduledMessages: isScheduledMessages, isMuted: nil, customMessageCount: nil, isEnabled: hasPeerInfo) let imageOverride: AvatarNodeImageOverride? @@ -460,7 +466,7 @@ extension ChatControllerImpl { } else { imageOverride = nil } - (strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.setPeer(context: strongSelf.context, theme: strongSelf.presentationData.theme, peer: EnginePeer(peer), overrideImage: imageOverride) + (strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.setPeer(context: strongSelf.context, theme: strongSelf.presentationData.theme, peer: EnginePeer(peer), overrideImage: imageOverride, synchronousLoad: isFirstTime) if case .standard(.previewing) = strongSelf.mode { (strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.contextActionIsEnabled = false } else { @@ -767,16 +773,20 @@ extension ChatControllerImpl { autoremoveTimeout = value?.effectiveValue } } else if let cachedChannelData = peerView.cachedData as? CachedChannelData { - currentSendAsPeerId = cachedChannelData.sendAsPeerId - if let channel = peer as? TelegramChannel, case .group = channel.info { - if !cachedChannelData.botInfos.isEmpty { - hasBots = true - } - let botCommands = cachedChannelData.botInfos.reduce(into: [], { result, info in - result.append(contentsOf: info.botInfo.commands) - }) - if !botCommands.isEmpty { - hasBotCommands = true + if let channel = peer as? TelegramChannel, channel.isMonoForum { + currentSendAsPeerId = channel.linkedMonoforumId + } else { + currentSendAsPeerId = cachedChannelData.sendAsPeerId + if let channel = peer as? TelegramChannel, case .group = channel.info { + if !cachedChannelData.botInfos.isEmpty { + hasBots = true + } + let botCommands = cachedChannelData.botInfos.reduce(into: [], { result, info in + result.append(contentsOf: info.botInfo.commands) + }) + if !botCommands.isEmpty { + hasBotCommands = true + } } } if case let .known(value) = cachedChannelData.autoremoveTimeout { @@ -1139,22 +1149,39 @@ extension ChatControllerImpl { savedMessagesPeerId = nil } - let savedMessagesPeer: Signal<(peer: EnginePeer?, messageCount: Int)?, NoError> + let savedMessagesPeer: Signal<(peer: EnginePeer?, messageCount: Int, presence: EnginePeer.Presence?)?, NoError> if let savedMessagesPeerId { let threadPeerId = savedMessagesPeerId - let basicPeerKey: PostboxViewKey = .basicPeer(threadPeerId) + let basicPeerKey: PostboxViewKey = .peer(peerId: threadPeerId, components: []) let countViewKey: PostboxViewKey = .historyTagSummaryView(tag: MessageTags(), peerId: peerId, threadId: savedMessagesPeerId.toInt64(), namespace: Namespaces.Message.Cloud, customTag: nil) savedMessagesPeer = context.account.postbox.combinedView(keys: [basicPeerKey, countViewKey]) - |> map { views -> (peer: EnginePeer?, messageCount: Int)? in - let peer = ((views.views[basicPeerKey] as? BasicPeerView)?.peer).flatMap(EnginePeer.init) + |> map { views -> (peer: EnginePeer?, messageCount: Int, presence: EnginePeer.Presence?)? in + var peer: EnginePeer? + var presence: EnginePeer.Presence? + if let peerView = views.views[basicPeerKey] as? PeerView { + peer = peerViewMainPeer(peerView).flatMap(EnginePeer.init) + presence = peerView.peerPresences[threadPeerId].flatMap(EnginePeer.Presence.init) + } var messageCount = 0 if let summaryView = views.views[countViewKey] as? MessageHistoryTagSummaryView, let count = summaryView.count { messageCount += Int(count) } - return (peer, messageCount) + return (peer, messageCount, presence) } + |> distinctUntilChanged(isEqual: { lhs, rhs in + if lhs?.peer != rhs?.peer { + return false + } + if lhs?.messageCount != rhs?.messageCount { + return false + } + if lhs?.presence != rhs?.presence { + return false + } + return true + }) } else { savedMessagesPeer = .single(nil) } @@ -1261,6 +1288,7 @@ extension ChatControllerImpl { let globalPrivacySettings = context.engine.data.get(TelegramEngine.EngineData.Item.Configuration.GlobalPrivacy()) self.titleDisposable.set(nil) + var isFirstTimeValue = true self.peerDisposable.set((combineLatest(queue: Queue.mainQueue(), peerView, messageAndTopic, @@ -1275,6 +1303,9 @@ extension ChatControllerImpl { ) |> deliverOnMainQueue).startStrict(next: { [weak self] peerView, messageAndTopic, savedMessagesPeer, onlineMemberCount, hasScheduledMessages, hasSearchTags, hasSavedChats, isPremiumRequiredForMessaging, managingBot, globalPrivacySettings in if let strongSelf = self { + let isFirstTime = isFirstTimeValue + isFirstTimeValue = false + strongSelf.hasScheduledMessages = hasScheduledMessages var renderedPeer: RenderedPeer? @@ -1334,16 +1365,27 @@ extension ChatControllerImpl { } if let savedMessagesPeerId { + var peerPresences: [PeerId: PeerPresence] = [:] + if let presence = savedMessagesPeer?.presence { + peerPresences[savedMessagesPeerId] = presence._asPresence() + } let mappedPeerData = ChatTitleContent.PeerData( peerId: savedMessagesPeerId, peer: savedMessagesPeer?.peer?._asPeer(), isContact: true, isSavedMessages: true, notificationSettings: nil, - peerPresences: [:], + peerPresences: peerPresences, cachedData: nil ) - strongSelf.chatTitleView?.titleContent = .peer(peerView: mappedPeerData, customTitle: nil, onlineMemberCount: (nil, nil), isScheduledMessages: false, isMuted: false, customMessageCount: savedMessagesPeer?.messageCount ?? 0, isEnabled: true) + + var customMessageCount: Int? + if let peer = peerView.peers[peerView.peerId] as? TelegramChannel, peer.isMonoForum { + } else { + customMessageCount = savedMessagesPeer?.messageCount ?? 0 + } + + strongSelf.chatTitleView?.titleContent = .peer(peerView: mappedPeerData, customTitle: nil, onlineMemberCount: (nil, nil), isScheduledMessages: false, isMuted: false, customMessageCount: customMessageCount, isEnabled: true) strongSelf.peerView = peerView @@ -1374,7 +1416,7 @@ extension ChatControllerImpl { .updatedHasScheduledMessages(hasScheduledMessages) }) - (strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.setPeer(context: strongSelf.context, theme: strongSelf.presentationData.theme, peer: savedMessagesPeer?.peer, overrideImage: imageOverride) + (strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.setPeer(context: strongSelf.context, theme: strongSelf.presentationData.theme, peer: savedMessagesPeer?.peer, overrideImage: imageOverride, synchronousLoad: isFirstTime) (strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.contextActionIsEnabled = false strongSelf.chatInfoNavigationButton?.buttonItem.accessibilityLabel = strongSelf.presentationData.strings.Conversation_ContextMenuOpenProfile } else { @@ -1464,12 +1506,16 @@ extension ChatControllerImpl { var peerGeoLocation: PeerGeoLocation? var currentSendAsPeerId: PeerId? if let peer = peerView.peers[peerView.peerId] as? TelegramChannel, let cachedData = peerView.cachedData as? CachedChannelData { - currentSendAsPeerId = cachedData.sendAsPeerId - if case .group = peer.info { - peerGeoLocation = cachedData.peerGeoLocation - } - if case let .known(value) = cachedData.linkedDiscussionPeerId { - peerDiscussionId = value + if peer.isMonoForum { + currentSendAsPeerId = peer.linkedMonoforumId + } else { + currentSendAsPeerId = cachedData.sendAsPeerId + if case .group = peer.info { + peerGeoLocation = cachedData.peerGeoLocation + } + if case let .known(value) = cachedData.linkedDiscussionPeerId { + peerDiscussionId = value + } } } @@ -1656,7 +1702,7 @@ extension ChatControllerImpl { self.reportIrrelvantGeoNoticePromise.set(.single(nil)) self.titleDisposable.set(nil) - var peerView: Signal = .single(nil) + let peerView: Signal = .single(nil) if case let .customChatContents(customChatContents) = self.subject { switch customChatContents.kind { @@ -1680,23 +1726,20 @@ extension ChatControllerImpl { } self.chatTitleView?.titleContent = .custom(link.title ?? self.presentationData.strings.Business_Links_EditLinkTitle, linkUrl, false) - case .postSuggestions: - if let customChatContents = customChatContents as? PostSuggestionsChatContents { - peerView = context.account.viewTracker.peerView(customChatContents.peerId) |> map(Optional.init) - } - - //TODO:localize - self.chatTitleView?.titleContent = .custom("Message Suggestions", nil, false) } } else { self.chatTitleView?.titleContent = .custom(" ", nil, false) } + var isFirstTimeValue = true self.peerDisposable.set((peerView |> deliverOnMainQueue).startStrict(next: { [weak self] peerView in guard let self else { return } + + let isFirstTime = isFirstTimeValue + isFirstTimeValue = false var renderedPeer: RenderedPeer? if let peerView, let peer = peerView.peers[peerView.peerId] { @@ -1707,7 +1750,7 @@ extension ChatControllerImpl { } renderedPeer = RenderedPeer(peerId: peer.id, peers: peers, associatedMedia: peerView.media) - (self.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.setPeer(context: self.context, theme: self.presentationData.theme, peer: EnginePeer(peer), overrideImage: nil) + (self.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.setPeer(context: self.context, theme: self.presentationData.theme, peer: EnginePeer(peer), overrideImage: nil, synchronousLoad: isFirstTime) } self.peerView = peerView @@ -2334,6 +2377,10 @@ extension ChatControllerImpl { return } + if let channel = peerViewMainPeer(peerView) as? TelegramChannel, channel.isMonoForum { + return + } + let isPremium = strongSelf.presentationInterfaceState.isPremium var allPeers: [SendAsPeer]? @@ -3038,46 +3085,6 @@ extension ChatControllerImpl { } strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .succeed(text: strongSelf.presentationData.strings.Business_Links_EditLinkToastSaved, timeout: nil, customUndoText: nil), elevatedLayout: false, action: { _ in return false }), in: .current) - case let .postSuggestions(postSuggestions): - if let customChatContents = customChatContents as? PostSuggestionsChatContents { - //TODO:release - strongSelf.chatDisplayNode.dismissInput() - - let _ = (ChatSendStarsScreen.initialData(context: strongSelf.context, peerId: customChatContents.peerId, suggestMessageAmount: postSuggestions, completion: { [weak strongSelf] amount, timestamp in - guard let strongSelf else { - return - } - guard case let .customChatContents(customChatContents) = strongSelf.subject else { - return - } - if amount == 0 { - return - } - let messages = messages.map { message in - return message.withUpdatedAttributes { attributes in - var attributes = attributes - attributes.removeAll(where: { $0 is OutgoingSuggestedPostMessageAttribute }) - attributes.append(OutgoingSuggestedPostMessageAttribute( - price: StarsAmount(value: amount, nanos: 0), - timestamp: timestamp - )) - return attributes - } - } - customChatContents.enqueueMessages(messages: messages) - strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory() - }) - |> deliverOnMainQueue).startStandalone(next: { [weak strongSelf] initialData in - guard let strongSelf, let initialData else { - return - } - let sendStarsScreen = ChatSendStarsScreen( - context: strongSelf.context, - initialData: initialData - ) - strongSelf.push(sendStarsScreen) - }) - } } } strongSelf.updateChatPresentationInterfaceState(interactive: true, { $0.updatedShowCommands(false) }) @@ -5747,47 +5754,25 @@ extension ChatControllerImpl { guard let self else { return } - guard let peerId = self.chatLocation.peerId else { + guard let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel else { + return + } + guard let monoforumPeerId = channel.linkedMonoforumId else { return } let _ = (self.context.engine.data.get( - TelegramEngine.EngineData.Item.Peer.LinkedMonoforumPeerId(id: peerId) + TelegramEngine.EngineData.Item.Peer.Peer(id: monoforumPeerId) ) - |> deliverOnMainQueue).startStandalone(next: { [weak self] monoforumPeerIdValue in - guard let self, case let .known(monoforumPeerIdValue) = monoforumPeerIdValue, let monoforumPeerId = monoforumPeerIdValue else { + |> deliverOnMainQueue).startStandalone(next: { [weak self] monoforumPeer in + guard let self, let monoforumPeer else { return } - - let _ = (self.context.engine.data.get( - TelegramEngine.EngineData.Item.Peer.Peer(id: monoforumPeerId) - ) - |> deliverOnMainQueue).startStandalone(next: { [weak self] monoforumPeer in - guard let self, let monoforumPeer else { - return - } - guard let navigationController = self.effectiveNavigationController else { - return - } - self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(monoforumPeer), keepStack: .always)) - }) + guard let navigationController = self.effectiveNavigationController else { + return + } + self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(monoforumPeer), keepStack: .always)) }) - - /*let contents = PostSuggestionsChatContents( - context: self.context, - peerId: peerId - ) - let chatController = self.context.sharedContext.makeChatController( - context: self.context, - chatLocation: .customChatContents, - subject: .customChatContents(contents: contents), - botStart: nil, - mode: .standard(.default), - params: nil - ) - chatController.navigationPresentation = .modal - - self.push(chatController)*/ }, editMessageMedia: { [weak self] messageId, draw in if let strongSelf = self { strongSelf.controllerInteraction?.editMessageMedia(messageId, draw) diff --git a/submodules/TelegramUI/Sources/Chat/UpdateChatPresentationInterfaceState.swift b/submodules/TelegramUI/Sources/Chat/UpdateChatPresentationInterfaceState.swift index 14ae0ce885..29048bb5c4 100644 --- a/submodules/TelegramUI/Sources/Chat/UpdateChatPresentationInterfaceState.swift +++ b/submodules/TelegramUI/Sources/Chat/UpdateChatPresentationInterfaceState.swift @@ -23,6 +23,8 @@ func updateChatPresentationInterfaceStateImpl( _ f: (ChatPresentationInterfaceState) -> ChatPresentationInterfaceState, completion externalCompletion: @escaping (ContainedViewLayoutTransition) -> Void ) { + let previousChatLocation = selfController.chatDisplayNode.historyNode.chatLocation + var completion = externalCompletion var temporaryChatPresentationInterfaceState = f(selfController.presentationInterfaceState) @@ -230,8 +232,6 @@ func updateChatPresentationInterfaceStateImpl( break case .businessLinkSetup: canHaveUrlPreview = false - case .postSuggestions: - break } } @@ -436,6 +436,11 @@ func updateChatPresentationInterfaceStateImpl( selfController.presentationInterfaceState = updatedChatPresentationInterfaceState + if selfController.chatDisplayNode.chatLocation != selfController.presentationInterfaceState.chatLocation { + let tabSwitchDirection = selfController.chatDisplayNode.chatLocationTabSwitchDirection(from: selfController.chatDisplayNode.chatLocation, to: selfController.presentationInterfaceState.chatLocation) + selfController.chatDisplayNode.updateChatLocation(chatLocation: selfController.presentationInterfaceState.chatLocation, transition: transition, tabSwitchDirection: tabSwitchDirection) + } + selfController.updateSlowmodeStatus() switch updatedChatPresentationInterfaceState.inputMode { @@ -491,6 +496,8 @@ func updateChatPresentationInterfaceStateImpl( selfController.leftNavigationButton = nil } + /*if let channel = selfController.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isForumOrMonoForum { + } else {*/ var buttonsAnimated = transition.isAnimated if let button = rightNavigationButtonForChatInterfaceState(context: selfController.context, presentationInterfaceState: updatedChatPresentationInterfaceState, strings: updatedChatPresentationInterfaceState.strings, currentButton: selfController.rightNavigationButton, target: selfController, selector: #selector(selfController.rightNavigationButtonAction), chatInfoNavigationButton: selfController.chatInfoNavigationButton, moreInfoNavigationButton: selfController.moreInfoNavigationButton) { if selfController.rightNavigationButton != button { @@ -500,6 +507,9 @@ func updateChatPresentationInterfaceStateImpl( if case .replyThread = selfController.chatLocation { buttonsAnimated = false } + if let channel = updatedChatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum { + buttonsAnimated = false + } selfController.rightNavigationButton = button } } else if let _ = selfController.rightNavigationButton { @@ -589,12 +599,10 @@ func updateChatPresentationInterfaceStateImpl( } } - if selfController.chatDisplayNode.historyNode.chatLocation != selfController.presentationInterfaceState.chatLocation { + if previousChatLocation != selfController.presentationInterfaceState.chatLocation { selfController.chatLocation = selfController.presentationInterfaceState.chatLocation - selfController.chatDisplayNode.chatLocation = selfController.presentationInterfaceState.chatLocation selfController.reloadChatLocation() selfController.reloadCachedData() - selfController.chatDisplayNode.historyNode.updateChatLocation(chatLocation: selfController.presentationInterfaceState.chatLocation) } selfController.updateDownButtonVisibility() diff --git a/submodules/TelegramUI/Sources/ChatBusinessLinkTitlePanelNode.swift b/submodules/TelegramUI/Sources/ChatBusinessLinkTitlePanelNode.swift index 993979ecc4..4fe8585ec1 100644 --- a/submodules/TelegramUI/Sources/ChatBusinessLinkTitlePanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatBusinessLinkTitlePanelNode.swift @@ -196,8 +196,6 @@ final class ChatBusinessLinkTitlePanelNode: ChatTitleAccessoryPanelNode { self.link = link case .hashTagSearch: break - case .postSuggestions: - break } default: break diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 6770d41ca7..af5d8d608d 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -777,8 +777,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } case .hashTagSearch: break - case .postSuggestions: - break } } @@ -844,7 +842,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return true case let .quickReplyMessageInput(_, shortcutType): if let historyView = strongSelf.chatDisplayNode.historyNode.originalHistoryView, historyView.entries.isEmpty { - let titleString: String let textString: String switch shortcutType { @@ -885,8 +882,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return false } - case .postSuggestions: - break } } @@ -4833,6 +4828,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } self.displayQuickShare(id: messageId, node: node, gesture: gesture) + }, updateChatLocationThread: { [weak self] threadId in + guard let self else { + return + } + self.interfaceInteraction?.updateChatLocationThread(threadId) }, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: self.stickerSettings, presentationContext: ChatPresentationContext(context: context, backgroundNode: self.chatBackgroundNode)) controllerInteraction.enableFullTranslucency = context.sharedContext.energyUsageSettings.fullTranslucency @@ -5227,14 +5227,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G chatInfoButtonItem = UIBarButtonItem(customDisplayNode: avatarNode)! self.avatarNode = avatarNode case .customChatContents: - if case let .customChatContents(customChatContents) = self.subject, case .postSuggestions = customChatContents.kind { - let avatarNode = ChatAvatarNavigationNode() - chatInfoButtonItem = UIBarButtonItem(customDisplayNode: avatarNode)! - chatInfoButtonItem.isEnabled = false - self.avatarNode = avatarNode - } else { - chatInfoButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) - } + chatInfoButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) } chatInfoButtonItem.target = self chatInfoButtonItem.action = #selector(self.rightNavigationButtonAction) @@ -7925,6 +7918,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G attributes.append(OutgoingScheduleInfoMessageAttribute(scheduleTime: scheduleTime)) } } + + if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum { + attributes.removeAll(where: { $0 is SendAsMessageAttribute }) + if channel.adminRights != nil, let sendAsPeerId = self.presentationInterfaceState.currentSendAsPeerId { + attributes.append(SendAsMessageAttribute(peerId: sendAsPeerId)) + } + } if let sendAsPeerId = self.presentationInterfaceState.currentSendAsPeerId { if attributes.first(where: { $0 is SendAsMessageAttribute }) == nil { attributes.append(SendAsMessageAttribute(peerId: sendAsPeerId)) diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 1e8ec3690c..fdcd28bf4f 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -135,7 +135,8 @@ class HistoryNodeContainer: ASDisplayNode { class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { let context: AccountContext - var chatLocation: ChatLocation + private(set) var chatLocation: ChatLocation + private let chatLocationContextHolder: Atomic let controllerInteraction: ChatControllerInteraction private weak var controller: ChatControllerImpl? @@ -158,7 +159,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { let contentContainerNode: ChatNodeContainer let contentDimNode: ASDisplayNode let backgroundNode: WallpaperBackgroundNode - let historyNode: ChatHistoryListNodeImpl + var historyNode: ChatHistoryListNodeImpl var blurredHistoryNode: ASImageNode? let historyNodeContainer: HistoryNodeContainer let loadingNode: ChatLoadingNode @@ -183,6 +184,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { private(set) var validLayout: (ContainerViewLayout, CGFloat)? private var visibleAreaInset = UIEdgeInsets() + private var currentListViewLayout: (size: CGSize, insets: UIEdgeInsets, scrollIndicatorInsets: UIEdgeInsets)? private(set) var searchNavigationNode: ChatSearchNavigationContentNode? @@ -209,6 +211,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { private(set) var feePanelNode: ChatFeePanelNode? private let titleAccessoryPanelContainer: ChatControllerTitlePanelNodeContainer + private var titleTopicsAccessoryPanelNode: ChatTopicListTitleAccessoryPanelNode? private var titleAccessoryPanelNode: ChatTitleAccessoryPanelNode? private var chatTranslationPanel: ChatTranslationPanelNode? @@ -292,7 +295,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { private var dropDimNode: ASDisplayNode? - let messageTransitionNode: ChatMessageTransitionNodeImpl + var messageTransitionNode: ChatMessageTransitionNodeImpl private let presentationContextMarker = ASDisplayNode() @@ -404,6 +407,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, chatPresentationInterfaceState: ChatPresentationInterfaceState, automaticMediaDownloadSettings: MediaAutoDownloadSettings, navigationBar: NavigationBar?, statusBar: StatusBar?, backgroundNode: WallpaperBackgroundNode, controller: ChatControllerImpl?) { self.context = context self.chatLocation = chatLocation + self.chatLocationContextHolder = chatLocationContextHolder self.controllerInteraction = controllerInteraction self.chatPresentationInterfaceState = chatPresentationInterfaceState self.automaticMediaDownloadSettings = automaticMediaDownloadSettings @@ -761,34 +765,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { assert(Queue.mainQueue().isCurrent()) - self.historyNode.setLoadStateUpdated { [weak self] loadState, animated in - if let strongSelf = self { - let wasLoading = strongSelf.isLoadingValue - if case let .loading(earlier) = loadState { - strongSelf.updateIsLoading(isLoading: true, earlier: earlier, animated: animated) - } else { - strongSelf.updateIsLoading(isLoading: false, earlier: false, animated: animated) - } - - var emptyType: ChatHistoryNodeLoadState.EmptyType? - if case let .empty(type) = loadState { - if case .botInfo = type { - } else { - emptyType = type - if case .joined = type { - if strongSelf.didDisplayEmptyGreeting { - emptyType = .generic - } else { - strongSelf.didDisplayEmptyGreeting = true - } - } - } - } else if case .messages = loadState { - strongSelf.didDisplayEmptyGreeting = true - } - strongSelf.updateIsEmpty(emptyType, wasLoading: wasLoading, animated: animated) - } - } + self.setupHistoryNode() self.interactiveEmojisDisposable = (self.context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration]) |> map { preferencesView -> InteractiveEmojiConfiguration in @@ -800,31 +777,6 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { strongSelf.interactiveEmojis = emojis } }) - - var backgroundColors: [UInt32] = [] - switch chatPresentationInterfaceState.chatWallpaper { - case let .file(file): - if file.isPattern { - backgroundColors = file.settings.colors - } - case let .gradient(gradient): - backgroundColors = gradient.colors - case let .color(color): - backgroundColors = [color] - default: - break - } - if !backgroundColors.isEmpty { - let averageColor = UIColor.average(of: backgroundColors.map(UIColor.init(rgb:))) - if averageColor.hsb.b >= 0.3 { - self.historyNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3) - } else { - self.historyNode.verticalScrollIndicatorColor = UIColor(white: 1.0, alpha: 0.3) - } - } else { - self.historyNode.verticalScrollIndicatorColor = UIColor(white: 0.5, alpha: 0.8) - } - self.historyNode.enableExtractedBackgrounds = true self.addSubnode(self.wrappingNode) self.wrappingNode.contentNode.addSubnode(self.contentContainerNode) @@ -865,8 +817,6 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { self.navigationBar?.additionalContentNode.addSubnode(self.titleAccessoryPanelContainer) - self.historyNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) - self.textInputPanelNode = ChatTextInputPanelNode(context: context, presentationInterfaceState: chatPresentationInterfaceState, presentationContext: ChatPresentationContext(context: context, backgroundNode: backgroundNode), presentController: { [weak self] controller in self?.interfaceInteraction?.presentController(controller, nil) }) @@ -1013,44 +963,6 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { return false } - - self.displayVideoUnmuteTipDisposable = (combineLatest(queue: Queue.mainQueue(), ApplicationSpecificNotice.getVolumeButtonToUnmute(accountManager: self.context.sharedContext.accountManager), self.historyNode.hasVisiblePlayableItemNodes, self.historyNode.isInteractivelyScrolling) - |> mapToSignal { notice, hasVisiblePlayableItemNodes, isInteractivelyScrolling -> Signal in - let display = !notice && hasVisiblePlayableItemNodes && !isInteractivelyScrolling - if display { - return .complete() - |> delay(2.5, queue: Queue.mainQueue()) - |> then( - .single(display) - ) - } else { - return .single(display) - } - }).startStrict(next: { [weak self] display in - if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction { - if display { - var nodes: [(CGFloat, ChatMessageItemView, ASDisplayNode)] = [] - var skip = false - strongSelf.historyNode.forEachVisibleItemNode { itemNode in - if let itemNode = itemNode as? ChatMessageItemView, let (_, soundEnabled, isVideoMessage, _, badgeNode) = itemNode.playMediaWithSound(), let node = badgeNode { - if soundEnabled { - skip = true - } else if !skip && !isVideoMessage, case let .visible(fraction, _) = itemNode.visibility { - nodes.insert((fraction, itemNode, node), at: 0) - } - } - } - for (fraction, _, badgeNode) in nodes { - if fraction > 0.7 { - interfaceInteraction.displayVideoUnmuteTip(badgeNode.view.convert(badgeNode.view.bounds, to: strongSelf.view).origin.offsetBy(dx: 42.0, dy: -1.0)) - break - } - } - } else { - interfaceInteraction.displayVideoUnmuteTip(nil) - } - } - }) } private func updateIsEmpty(_ emptyType: ChatHistoryNodeLoadState.EmptyType?, wasLoading: Bool, animated: Bool) { @@ -1363,13 +1275,39 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { previousInputPanelOrigin.y -= secondaryInputPanelNode.bounds.size.height } self.containerLayoutAndNavigationBarHeight = (layout, navigationBarHeight) + + var extraTransition = transition + + var dismissedTitleTopicsAccessoryPanelNode: ChatTopicListTitleAccessoryPanelNode? + var immediatelyLayoutTitleTopicsAccessoryPanelNodeAndAnimateAppearance = false + var titleTopicsAccessoryPanelHeight: CGFloat? + var titleTopicsAccessoryPanelBackgroundHeight: CGFloat? + var titleTopicsAccessoryPanelHitTestSlop: CGFloat? + if let titleTopicsAccessoryPanelNode = titleTopicsPanelForChatPresentationInterfaceState(self.chatPresentationInterfaceState, context: self.context, currentPanel: self.titleTopicsAccessoryPanelNode, controllerInteraction: self.controllerInteraction, interfaceInteraction: self.interfaceInteraction, force: false) { + if self.titleTopicsAccessoryPanelNode != titleTopicsAccessoryPanelNode { + dismissedTitleTopicsAccessoryPanelNode = self.titleTopicsAccessoryPanelNode + self.titleTopicsAccessoryPanelNode = titleTopicsAccessoryPanelNode + immediatelyLayoutTitleTopicsAccessoryPanelNodeAndAnimateAppearance = true + self.titleAccessoryPanelContainer.addSubnode(titleTopicsAccessoryPanelNode) + + titleTopicsAccessoryPanelNode.clipsToBounds = true + } + + let layoutResult = titleTopicsAccessoryPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: immediatelyLayoutTitleTopicsAccessoryPanelNodeAndAnimateAppearance ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState) + titleTopicsAccessoryPanelHeight = layoutResult.insetHeight + titleTopicsAccessoryPanelBackgroundHeight = layoutResult.backgroundHeight + titleTopicsAccessoryPanelHitTestSlop = layoutResult.hitTestSlop + } else if let titleTopicsAccessoryPanelNode = self.titleTopicsAccessoryPanelNode { + dismissedTitleTopicsAccessoryPanelNode = titleTopicsAccessoryPanelNode + self.titleTopicsAccessoryPanelNode = nil + } var dismissedTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode? var immediatelyLayoutTitleAccessoryPanelNodeAndAnimateAppearance = false var titleAccessoryPanelHeight: CGFloat? var titleAccessoryPanelBackgroundHeight: CGFloat? var titleAccessoryPanelHitTestSlop: CGFloat? - var extraTransition = transition + if let titleAccessoryPanelNode = titlePanelForChatPresentationInterfaceState(self.chatPresentationInterfaceState, context: self.context, currentPanel: self.titleAccessoryPanelNode, controllerInteraction: self.controllerInteraction, interfaceInteraction: self.interfaceInteraction, force: false) { if self.titleAccessoryPanelNode != titleAccessoryPanelNode { dismissedTitleAccessoryPanelNode = self.titleAccessoryPanelNode @@ -1575,6 +1513,8 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { self.leftPanel = nil } + self.controllerInteraction.isSidePanelOpen = self.leftPanel != nil + var inputPanelNodeBaseHeight: CGFloat = 0.0 if let inputPanelNode = self.inputPanelNode { inputPanelNodeBaseHeight += inputPanelNode.minimalHeight(interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics) @@ -1859,12 +1799,27 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { var extraNavigationBarHeight: CGFloat = 0.0 var extraNavigationBarHitTestSlop: CGFloat = 0.0 + + var titlePanelsContentOffset: CGFloat = 0.0 + + let sidePanelTopInset: CGFloat = insets.top + + var titleTopicsAccessoryPanelFrame: CGRect? + if let _ = self.titleTopicsAccessoryPanelNode, let panelHeight = titleTopicsAccessoryPanelHeight { + titleTopicsAccessoryPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: titlePanelsContentOffset), size: CGSize(width: layout.size.width, height: panelHeight)) + insets.top += panelHeight + extraNavigationBarHeight += titleTopicsAccessoryPanelBackgroundHeight ?? 0.0 + extraNavigationBarHitTestSlop = titleTopicsAccessoryPanelHitTestSlop ?? 0.0 + titlePanelsContentOffset += panelHeight + } + var titleAccessoryPanelFrame: CGRect? if let _ = self.titleAccessoryPanelNode, let panelHeight = titleAccessoryPanelHeight { - titleAccessoryPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: panelHeight)) + titleAccessoryPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: titlePanelsContentOffset), size: CGSize(width: layout.size.width, height: panelHeight)) insets.top += panelHeight extraNavigationBarHeight += titleAccessoryPanelBackgroundHeight ?? 0.0 extraNavigationBarHitTestSlop = titleAccessoryPanelHitTestSlop ?? 0.0 + titlePanelsContentOffset += panelHeight } var translationPanelFrame: CGRect? @@ -2226,18 +2181,20 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { self.controller?.presentationContext.containerLayoutUpdated(childrenLayout, transition: transition) self.controller?.galleryPresentationContext.containerLayoutUpdated(layout, transition: transition) - listViewTransaction(ListViewUpdateSizeAndInsets(size: contentBounds.size, insets: listInsets, scrollIndicatorInsets: listScrollIndicatorInsets, duration: duration, curve: curve, ensureTopInsetForOverlayHighlightedItems: ensureTopInsetForOverlayHighlightedItems), additionalScrollDistance, scrollToTop, { [weak self] in + var customListAnimationTransition: ControlledTransition? + if case let .animated(duration, curve) = transition { + if immediatelyLayoutLeftPanelNodeAndAnimateAppearance || dismissedLeftPanel != nil { + customListAnimationTransition = ControlledTransition(duration: duration, curve: curve, interactive: false) + } + } + + self.currentListViewLayout = (contentBounds.size, insets: listInsets, scrollIndicatorInsets: listScrollIndicatorInsets) + listViewTransaction(ListViewUpdateSizeAndInsets(size: contentBounds.size, insets: listInsets, scrollIndicatorInsets: listScrollIndicatorInsets, duration: duration, curve: curve, ensureTopInsetForOverlayHighlightedItems: ensureTopInsetForOverlayHighlightedItems, customAnimationTransition: customListAnimationTransition), additionalScrollDistance, scrollToTop, { [weak self] in if let strongSelf = self { strongSelf.notifyTransitionCompletionListeners(transition: transition) } }) - if immediatelyLayoutLeftPanelNodeAndAnimateAppearance { - transition.animatePositionAdditive(layer: self.historyNode.layer, offset: CGPoint(x: -defaultLeftPanelWidth, y: 0.0)) - } else if dismissedLeftPanel != nil { - transition.animatePositionAdditive(layer: self.historyNode.layer, offset: CGPoint(x: defaultLeftPanelWidth, y: 0.0)) - } - if self.isScrollingLockedAtTop { switch self.historyNode.visibleContentOffset() { case let .known(value) where value <= CGFloat.ulpOfOne: @@ -2298,7 +2255,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { component: leftPanel.component.component, environment: { ChatSidePanelEnvironment(insets: UIEdgeInsets( - top: containerInsets.top, + top: sidePanelTopInset, left: leftPanelLeftInset, bottom: containerInsets.bottom + contentBottomInset, right: 0.0 @@ -2313,8 +2270,14 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { } if immediatelyLayoutLeftPanelNodeAndAnimateAppearance { leftPanelView.frame = leftPanelFrame.offsetBy(dx: -leftPanelSize.width, dy: 0.0) + if let leftPanelView = leftPanelView as? ChatSideTopicsPanel.View { + leftPanelView.updateGlobalOffset(globalOffset: -leftPanelSize.width, transition: ComponentTransition(transition)) + } } transition.updateFrame(view: leftPanelView, frame: leftPanelFrame) + if let leftPanelView = leftPanelView as? ChatSideTopicsPanel.View { + leftPanelView.updateGlobalOffset(globalOffset: 0.0, transition: ComponentTransition(transition)) + } } } if let dismissedLeftPanel, let dismissedLeftPanelView = dismissedLeftPanel.view.view { @@ -2323,7 +2286,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { component: dismissedLeftPanel.component.component, environment: { ChatSidePanelEnvironment(insets: UIEdgeInsets( - top: containerInsets.top, + top: sidePanelTopInset, left: leftPanelLeftInset, bottom: containerInsets.bottom + contentBottomInset, right: 0.0 @@ -2334,6 +2297,9 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { transition.updateFrame(view: dismissedLeftPanelView, frame: CGRect(origin: CGPoint(x: -dismissedLeftPanelSize.width, y: 0.0), size: dismissedLeftPanelSize), completion: { [weak dismissedLeftPanelView] _ in dismissedLeftPanelView?.removeFromSuperview() }) + if let dismissedLeftPanelView = dismissedLeftPanelView as? ChatSideTopicsPanel.View { + dismissedLeftPanelView.updateGlobalOffset(globalOffset: -dismissedLeftPanelSize.width, transition: ComponentTransition(transition)) + } } if let navigationBarBackgroundContent = self.navigationBarBackgroundContent { @@ -2382,6 +2348,23 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { transition.updateFrame(node: self.inputPanelBackgroundSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: apparentInputBackgroundFrame.origin.y), size: CGSize(width: apparentInputBackgroundFrame.size.width, height: UIScreenPixel))) transition.updateFrame(node: self.navigateButtons, frame: apparentNavigateButtonsFrame) self.navigateButtons.update(rect: apparentNavigateButtonsFrame, within: layout.size, transition: transition) + + if let titleTopicsAccessoryPanelNode = self.titleTopicsAccessoryPanelNode, let titleTopicsAccessoryPanelFrame, (immediatelyLayoutTitleTopicsAccessoryPanelNodeAndAnimateAppearance || !titleTopicsAccessoryPanelNode.frame.equalTo(titleTopicsAccessoryPanelFrame)) { + if immediatelyLayoutTitleTopicsAccessoryPanelNodeAndAnimateAppearance { + titleTopicsAccessoryPanelNode.frame = titleTopicsAccessoryPanelFrame.offsetBy(dx: 0.0, dy: -titleTopicsAccessoryPanelFrame.height) + titleTopicsAccessoryPanelNode.updateGlobalOffset(globalOffset: -titleTopicsAccessoryPanelFrame.height, transition: .immediate) + + transition.updateFrame(node: titleTopicsAccessoryPanelNode, frame: titleTopicsAccessoryPanelFrame) + titleTopicsAccessoryPanelNode.updateGlobalOffset(globalOffset: 0.0, transition: ComponentTransition(transition)) + } else { + let previousFrame = titleTopicsAccessoryPanelNode.frame + titleTopicsAccessoryPanelNode.frame = titleTopicsAccessoryPanelFrame + if transition.isAnimated && previousFrame.width != titleTopicsAccessoryPanelFrame.width { + } else { + transition.animatePositionAdditive(node: titleTopicsAccessoryPanelNode, offset: CGPoint(x: 0.0, y: -titleTopicsAccessoryPanelFrame.height)) + } + } + } if let titleAccessoryPanelNode = self.titleAccessoryPanelNode, let titleAccessoryPanelFrame, !titleAccessoryPanelNode.frame.equalTo(titleAccessoryPanelFrame) { let previousFrame = titleAccessoryPanelNode.frame @@ -2504,6 +2487,15 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { } } } + + if let dismissedTitleTopicsAccessoryPanelNode { + var dismissedTopPanelFrame = dismissedTitleTopicsAccessoryPanelNode.frame + dismissedTopPanelFrame.origin.y = -dismissedTopPanelFrame.size.height + transition.updateFrame(node: dismissedTitleTopicsAccessoryPanelNode, frame: dismissedTopPanelFrame, completion: { [weak dismissedTitleTopicsAccessoryPanelNode] _ in + dismissedTitleTopicsAccessoryPanelNode?.removeFromSupernode() + }) + dismissedTitleTopicsAccessoryPanelNode.updateGlobalOffset(globalOffset: -dismissedTopPanelFrame.height, transition: ComponentTransition(transition)) + } if let dismissedTitleAccessoryPanelNode { var dismissedPanelFrame = dismissedTitleAccessoryPanelNode.frame @@ -4375,7 +4367,6 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { } var postEmptyMessages = false - var isPostSuggestions = false if case let .customChatContents(customChatContents) = self.chatPresentationInterfaceState.subject { switch customChatContents.kind { case .hashTagSearch: @@ -4384,11 +4375,8 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { break case .businessLinkSetup: postEmptyMessages = true - case .postSuggestions: - isPostSuggestions = true } } - let _ = isPostSuggestions if !messages.isEmpty, let messageEffect { messages[0] = messages[0].withUpdatedAttributes { attributes in @@ -4805,4 +4793,199 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { transition.updateSublayerTransformOffset(layer: inputPanelNode.layer, offset: CGPoint(x: 0.0, y: overscrollNode == nil ? 0.0 : -5.0)) } } + + private func setupHistoryNode() { + var backgroundColors: [UInt32] = [] + switch self.chatPresentationInterfaceState.chatWallpaper { + case let .file(file): + if file.isPattern { + backgroundColors = file.settings.colors + } + case let .gradient(gradient): + backgroundColors = gradient.colors + case let .color(color): + backgroundColors = [color] + default: + break + } + if !backgroundColors.isEmpty { + let averageColor = UIColor.average(of: backgroundColors.map(UIColor.init(rgb:))) + if averageColor.hsb.b >= 0.3 { + self.historyNode.verticalScrollIndicatorColor = UIColor(white: 0.0, alpha: 0.3) + } else { + self.historyNode.verticalScrollIndicatorColor = UIColor(white: 1.0, alpha: 0.3) + } + } else { + self.historyNode.verticalScrollIndicatorColor = UIColor(white: 0.5, alpha: 0.8) + } + self.historyNode.enableExtractedBackgrounds = true + + self.historyNode.setLoadStateUpdated { [weak self] loadState, animated in + guard let strongSelf = self else { + return + } + let wasLoading = strongSelf.isLoadingValue + if case let .loading(earlier) = loadState { + strongSelf.updateIsLoading(isLoading: true, earlier: earlier, animated: animated) + } else { + strongSelf.updateIsLoading(isLoading: false, earlier: false, animated: animated) + } + + var emptyType: ChatHistoryNodeLoadState.EmptyType? + if case let .empty(type) = loadState { + if case .botInfo = type { + } else { + emptyType = type + if case .joined = type { + if strongSelf.didDisplayEmptyGreeting { + emptyType = .generic + } else { + strongSelf.didDisplayEmptyGreeting = true + } + } + } + } else if case .messages = loadState { + strongSelf.didDisplayEmptyGreeting = true + } + strongSelf.updateIsEmpty(emptyType, wasLoading: wasLoading, animated: animated) + } + + self.historyNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) + + self.displayVideoUnmuteTipDisposable?.dispose() + self.displayVideoUnmuteTipDisposable = (combineLatest(queue: Queue.mainQueue(), ApplicationSpecificNotice.getVolumeButtonToUnmute(accountManager: self.context.sharedContext.accountManager), self.historyNode.hasVisiblePlayableItemNodes, self.historyNode.isInteractivelyScrolling) + |> mapToSignal { notice, hasVisiblePlayableItemNodes, isInteractivelyScrolling -> Signal in + let display = !notice && hasVisiblePlayableItemNodes && !isInteractivelyScrolling + if display { + return .complete() + |> delay(2.5, queue: Queue.mainQueue()) + |> then( + .single(display) + ) + } else { + return .single(display) + } + }).startStrict(next: { [weak self] display in + if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction { + if display { + var nodes: [(CGFloat, ChatMessageItemView, ASDisplayNode)] = [] + var skip = false + strongSelf.historyNode.forEachVisibleItemNode { itemNode in + if let itemNode = itemNode as? ChatMessageItemView, let (_, soundEnabled, isVideoMessage, _, badgeNode) = itemNode.playMediaWithSound(), let node = badgeNode { + if soundEnabled { + skip = true + } else if !skip && !isVideoMessage, case let .visible(fraction, _) = itemNode.visibility { + nodes.insert((fraction, itemNode, node), at: 0) + } + } + } + for (fraction, _, badgeNode) in nodes { + if fraction > 0.7 { + interfaceInteraction.displayVideoUnmuteTip(badgeNode.view.convert(badgeNode.view.bounds, to: strongSelf.view).origin.offsetBy(dx: 42.0, dy: -1.0)) + break + } + } + } else { + interfaceInteraction.displayVideoUnmuteTip(nil) + } + } + }) + } + + func chatLocationTabSwitchDirection(from fromLocation: ChatLocation, to toLocation: ChatLocation) -> Bool? { + var leftIndex: Int? + var rightIndex: Int? + if let titleTopicsAccessoryPanelNode = self.titleTopicsAccessoryPanelNode { + leftIndex = titleTopicsAccessoryPanelNode.topicIndex(threadId: fromLocation.threadId) + rightIndex = titleTopicsAccessoryPanelNode.topicIndex(threadId: toLocation.threadId) + } else if let leftPanelView = self.leftPanel?.view.view as? ChatSideTopicsPanel.View { + leftIndex = leftPanelView.topicIndex(threadId: fromLocation.threadId) + rightIndex = leftPanelView.topicIndex(threadId: toLocation.threadId) + } + guard let leftIndex, let rightIndex else { + return nil + } + return leftIndex < rightIndex + } + + func updateChatLocation(chatLocation: ChatLocation, transition: ContainedViewLayoutTransition, tabSwitchDirection: Bool?) { + if chatLocation == self.chatLocation { + return + } + self.chatLocation = chatLocation + + let historyNode = ChatHistoryListNodeImpl( + context: self.context, + updatedPresentationData: self.controller?.updatedPresentationData ?? (self.context.sharedContext.currentPresentationData.with({ $0 }), self.context.sharedContext.presentationData), + chatLocation: chatLocation, + chatLocationContextHolder: self.chatLocationContextHolder, + tag: nil, + source: .default, + subject: nil, + controllerInteraction: self.controllerInteraction, + selectedMessages: self.selectedMessagesPromise.get(), + rotated: self.controllerInteraction.chatIsRotated, + isChatPreview: false, + messageTransitionNode: { [weak self] in + return self?.messageTransitionNode + } + ) + + var getContentAreaInScreenSpaceImpl: (() -> CGRect)? + var onTransitionEventImpl: ((ContainedViewLayoutTransition) -> Void)? + let messageTransitionNode = ChatMessageTransitionNodeImpl(listNode: historyNode, getContentAreaInScreenSpace: { + return getContentAreaInScreenSpaceImpl?() ?? CGRect() + }, onTransitionEvent: { transition in + onTransitionEventImpl?(transition) + }) + + getContentAreaInScreenSpaceImpl = { [weak self] in + guard let strongSelf = self else { + return CGRect() + } + + return strongSelf.view.convert(strongSelf.frameForVisibleArea(), to: nil) + } + + onTransitionEventImpl = { [weak self] transition in + guard let strongSelf = self else { + return + } + if (strongSelf.context.sharedContext.currentPresentationData.with({ $0 })).reduceMotion { + return + } + if strongSelf.context.sharedContext.energyUsageSettings.fullTranslucency { + strongSelf.backgroundNode.animateEvent(transition: transition, extendAnimation: false) + } + } + + self.wrappingNode.contentNode.insertSubnode(messageTransitionNode, aboveSubnode: self.messageTransitionNode) + self.messageTransitionNode.removeFromSupernode() + self.messageTransitionNode = messageTransitionNode + + let previousHistoryNode = self.historyNode + previousHistoryNode.supernode?.insertSubnode(historyNode, aboveSubnode: previousHistoryNode) + self.historyNode = historyNode + + self.setupHistoryNode() + + historyNode.position = previousHistoryNode.position + historyNode.bounds = previousHistoryNode.bounds + historyNode.transform = previousHistoryNode.transform + + if let currentListViewLayout = self.currentListViewLayout { + let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: currentListViewLayout.size, insets: currentListViewLayout.insets, scrollIndicatorInsets: currentListViewLayout.scrollIndicatorInsets, duration: 0.0, curve: .Default(duration: nil), ensureTopInsetForOverlayHighlightedItems: nil, customAnimationTransition: nil) + historyNode.updateLayout(transition: .immediate, updateSizeAndInsets: updateSizeAndInsets, additionalScrollDistance: 0.0, scrollToTop: false, completion: {}) + } + + if let validLayout = self.validLayout, transition.isAnimated, let tabSwitchDirection { + let offsetMultiplier: CGFloat = tabSwitchDirection ? 1.0 : -1.0 + transition.animatePosition(layer: historyNode.layer, from: CGPoint(x: offsetMultiplier * validLayout.0.size.width, y: 0.0), to: CGPoint(), removeOnCompletion: true, additive: true) + transition.animatePosition(layer: previousHistoryNode.layer, from: CGPoint(), to: CGPoint(x: -offsetMultiplier * validLayout.0.size.width, y: 0.0), removeOnCompletion: false, additive: true, completion: { [weak previousHistoryNode] _ in + previousHistoryNode?.removeFromSupernode() + }) + } else { + previousHistoryNode.removeFromSupernode() + } + } } diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 8c1a5f8e09..5a03a0dfba 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -848,7 +848,8 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, - sendPaidMessageStars: nil + sendPaidMessageStars: nil, + linkedMonoforumId: nil ) messagePeers[author.id] = author @@ -985,7 +986,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto self.preloadPages = false - self.beginChatHistoryTransitions(resetScrolling: false) + self.beginChatHistoryTransitions(resetScrolling: false, switchedToAnotherSource: false) self.beginReadHistoryManagement() @@ -1230,15 +1231,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto } self.tag = tag - self.beginChatHistoryTransitions(resetScrolling: true) - } - - public func updateChatLocation(chatLocation: ChatLocation) { - if self.chatLocation == chatLocation { - return - } - self.chatLocation = chatLocation - self.beginChatHistoryTransitions(resetScrolling: false) + self.beginChatHistoryTransitions(resetScrolling: true, switchedToAnotherSource: false) } private func beginAdMessageManagement(adMessages: Signal<(interPostInterval: Int32?, messages: [Message]), NoError>) { @@ -1293,7 +1286,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto private let previousView = Atomic<(ChatHistoryView, Int, Set?, Int)?>(value: nil) private let previousHistoryAppearsCleared = Atomic(value: nil) - private func beginChatHistoryTransitions(resetScrolling: Bool) { + private func beginChatHistoryTransitions(resetScrolling: Bool, switchedToAnotherSource: Bool) { self.historyDisposable.set(nil) self._isReady.set(false) @@ -2085,6 +2078,10 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto var disableAnimations = false var forceSynchronous = false + if switchedToAnotherSource { + disableAnimations = true + } + if let previousValueAndVersion = previousValueAndVersion, allAdMessages.version != previousValueAndVersion.3 { reason = ChatHistoryViewTransitionReason.Reload disableAnimations = true @@ -2243,7 +2240,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto mappedTransition.options.remove(.AnimateTopItemPosition) mappedTransition.options.remove(.RequestItemInsertionAnimations) } - if forceSynchronous || resetScrolling { + if forceSynchronous || resetScrolling || switchedToAnotherSource { mappedTransition.options.insert(.Synchronous) } if resetScrolling { @@ -2358,7 +2355,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto strongSelf.dynamicBounceEnabled = false strongSelf.forEachItemHeaderNode { itemHeaderNode in - if let dateNode = itemHeaderNode as? ChatMessageDateHeaderNode { + if let dateNode = itemHeaderNode as? ChatMessageDateHeaderNodeImpl { dateNode.updatePresentationData(chatPresentationData, context: strongSelf.context) } else if let avatarNode = itemHeaderNode as? ChatMessageAvatarHeaderNodeImpl { avatarNode.updatePresentationData(chatPresentationData, context: strongSelf.context) diff --git a/submodules/TelegramUI/Sources/ChatInterfaceInputContexts.swift b/submodules/TelegramUI/Sources/ChatInterfaceInputContexts.swift index 0488f21816..43afa00b7a 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceInputContexts.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceInputContexts.swift @@ -63,8 +63,6 @@ func inputContextQueriesForChatPresentationIntefaceState(_ chatPresentationInter break case .businessLinkSetup: return [] - case .postSuggestions: - return [] } } @@ -243,8 +241,6 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte break case .businessLinkSetup: stickersEnabled = false - case .postSuggestions: - break } } diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index 6d82545c2b..f71aca16fa 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -2108,39 +2108,6 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState } case .businessLinkSetup: actions.removeAll() - case .postSuggestions: - //TODO:release - actions.removeAll() - - actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_MessageDialogEdit, icon: { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Edit"), color: theme.actionSheet.primaryTextColor) - }, action: { c, f in - interfaceInteraction.setupEditMessage(messages[0].id, { transition in - f(.custom(transition)) - }) - }))) - actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.ScheduledMessages_EditTime, icon: { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Schedule"), color: theme.actionSheet.primaryTextColor) - }, action: { _, f in - controllerInteraction.editScheduledMessagesTime(messages.map { $0.id }) - f(.dismissWithoutContent) - }))) - actions.append(.action(ContextMenuActionItem(text: "Edit Price", icon: { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Tag"), color: theme.actionSheet.primaryTextColor) - }, action: { _, f in - f(.dismissWithoutContent) - }))) - actions.append(.action(ContextMenuActionItem(text: "Delete", textColor: .destructive, icon: { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor) - }, action: { controller, f in - interfaceInteraction.deleteMessages(messages, controller, f) - }))) - actions.append(.separator) - let presentationData = context.sharedContext.currentPresentationData.with { $0 } - let action: ((ContextControllerProtocol?, @escaping (ContextMenuActionResult) -> Void) -> Void)? = nil - actions.append(.action(ContextMenuActionItem(text: "Deleting suggested post will auto-refund your order.", textColor: .primary, textLayout: .multiline, textFont: .custom(font: Font.regular(floor(presentationData.listsFontSize.baseDisplaySize * 0.8)), height: nil, verticalOffset: nil), badge: nil, icon: { theme in - return nil - }, iconSource: nil, action: action))) } } diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift index 27fe1a43f4..1571b29684 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift @@ -10,13 +10,7 @@ import ChatChannelSubscriberInputPanelNode import ChatMessageSelectionInputPanelNode func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatInputPanelNode?, currentSecondaryPanel: ChatInputPanelNode?, textInputPanelNode: ChatTextInputPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> (primary: ChatInputPanelNode?, secondary: ChatInputPanelNode?) { - var isPostSuggestions = false - if case let .customChatContents(customChatContents) = chatPresentationInterfaceState.subject, case .postSuggestions = customChatContents.kind { - isPostSuggestions = true - } - - if isPostSuggestions { - } else if let renderedPeer = chatPresentationInterfaceState.renderedPeer, renderedPeer.peer?.restrictionText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) != nil { + if let renderedPeer = chatPresentationInterfaceState.renderedPeer, renderedPeer.peer?.restrictionText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) != nil { return (nil, nil) } if chatPresentationInterfaceState.isNotAccessible { @@ -138,8 +132,7 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState } } - if isPostSuggestions { - } else if chatPresentationInterfaceState.peerIsBlocked, let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramUser, peer.botInfo == nil { + if chatPresentationInterfaceState.peerIsBlocked, let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramUser, peer.botInfo == nil { if let currentPanel = (currentPanel as? ChatUnblockInputPanelNode) ?? (currentSecondaryPanel as? ChatUnblockInputPanelNode) { currentPanel.interfaceInteraction = interfaceInteraction currentPanel.updateThemeAndStrings(theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings) @@ -154,9 +147,7 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState var displayInputTextPanel = false - if isPostSuggestions { - displayInputTextPanel = true - } else if let peer = chatPresentationInterfaceState.renderedPeer?.peer { + if let peer = chatPresentationInterfaceState.renderedPeer?.peer { if peer.id.isRepliesOrVerificationCodes { if let currentPanel = (currentPanel as? ChatChannelSubscriberInputPanelNode) ?? (currentSecondaryPanel as? ChatChannelSubscriberInputPanelNode) { return (currentPanel, nil) @@ -239,7 +230,21 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState } if channel.flags.contains(.isMonoforum) { - displayInputTextPanel = true + if channel.adminRights != nil, case .peer = chatPresentationInterfaceState.chatLocation { + if chatPresentationInterfaceState.interfaceState.replyMessageSubject == nil { + displayInputTextPanel = false + if let currentPanel = (currentPanel as? ChatRestrictedInputPanelNode) ?? (currentSecondaryPanel as? ChatRestrictedInputPanelNode) { + return (currentPanel, nil) + } else { + let panel = ChatRestrictedInputPanelNode() + panel.context = context + panel.interfaceInteraction = interfaceInteraction + return (panel, nil) + } + } + } else { + displayInputTextPanel = true + } } else if channel.flags.contains(.isForum) && isMember { var canManage = false if channel.flags.contains(.isCreator) { @@ -418,8 +423,6 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState displayInputTextPanel = false case .quickReplyMessageInput, .businessLinkSetup: displayInputTextPanel = true - case .postSuggestions: - displayInputTextPanel = true } if let chatHistoryState = chatPresentationInterfaceState.chatHistoryState, case .loaded(_, true) = chatHistoryState { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift index 5c40500cb1..57b6cd888b 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift @@ -59,7 +59,7 @@ func leftNavigationButtonForChatInterfaceState(_ presentationInterfaceState: Cha switch customChatContents.kind { case .hashTagSearch: break - case .quickReplyMessageInput, .businessLinkSetup, .postSuggestions: + case .quickReplyMessageInput, .businessLinkSetup: if let currentButton = currentButton, currentButton.action == .dismiss { return currentButton } else { @@ -149,8 +149,6 @@ func rightNavigationButtonForChatInterfaceState(context: AccountContext, present buttonItem.accessibilityLabel = strings.Common_Done return ChatNavigationButton(action: .edit, buttonItem: buttonItem) } - case .postSuggestions: - return chatInfoNavigationButton } } diff --git a/submodules/TelegramUI/Sources/ChatInterfaceTitlePanelNodes.swift b/submodules/TelegramUI/Sources/ChatInterfaceTitlePanelNodes.swift index 8664b715c8..518b8a1994 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceTitlePanelNodes.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceTitlePanelNodes.swift @@ -68,8 +68,6 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat panel.interfaceInteraction = interfaceInteraction return panel } - case .postSuggestions: - break } default: break @@ -167,19 +165,6 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat } } - if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isForumOrMonoForum { - let topicListDisplayMode = chatPresentationInterfaceState.topicListDisplayMode ?? .top - if case .top = topicListDisplayMode, let peerId = chatPresentationInterfaceState.chatLocation.peerId { - if let currentPanel = currentPanel as? ChatTopicListTitleAccessoryPanelNode { - return currentPanel - } else { - let panel = ChatTopicListTitleAccessoryPanelNode(context: context, peerId: peerId) - panel.interfaceInteraction = interfaceInteraction - return panel - } - } - } - if (selectedContext == nil || selectedContext! <= .pinnedMessage) { if displayActionsPanel { if let currentPanel = currentPanel as? ChatReportPeerTitlePanelNode { @@ -246,13 +231,30 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat return nil } +func titleTopicsPanelForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatTitleAccessoryPanelNode?, controllerInteraction: ChatControllerInteraction?, interfaceInteraction: ChatPanelInterfaceInteraction?, force: Bool) -> ChatTopicListTitleAccessoryPanelNode? { + if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isForumOrMonoForum, channel.adminRights != nil { + let topicListDisplayMode = chatPresentationInterfaceState.topicListDisplayMode ?? .top + if case .top = topicListDisplayMode, let peerId = chatPresentationInterfaceState.chatLocation.peerId { + if let currentPanel = currentPanel as? ChatTopicListTitleAccessoryPanelNode { + return currentPanel + } else { + let panel = ChatTopicListTitleAccessoryPanelNode(context: context, peerId: peerId) + panel.interfaceInteraction = interfaceInteraction + return panel + } + } + } + + return nil +} + func sidePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: AnyComponentWithIdentity?, controllerInteraction: ChatControllerInteraction?, interfaceInteraction: ChatPanelInterfaceInteraction?, force: Bool) -> AnyComponentWithIdentity? { guard let peerId = chatPresentationInterfaceState.chatLocation.peerId else { return nil } - if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isForumOrMonoForum { + if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isForumOrMonoForum, channel.adminRights != nil { let topicListDisplayMode = chatPresentationInterfaceState.topicListDisplayMode ?? .top if case .side = topicListDisplayMode { return AnyComponentWithIdentity( diff --git a/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift index aca5e3f05b..c704f1c010 100644 --- a/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift @@ -89,7 +89,9 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode { if let context = self.context { accountFreezeConfiguration = AccountFreezeConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) } - if let _ = accountFreezeConfiguration?.freezeUntilDate { + if let channel = interfaceState.renderedPeer?.chatMainPeer as? TelegramChannel, channel.isMonoForum { + self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelForumModeReplyText, font: Font.regular(15.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor) + } else if let _ = accountFreezeConfiguration?.freezeUntilDate { self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelFrozenAccount_Title, font: Font.semibold(15.0), textColor: interfaceState.theme.list.itemDestructiveColor) self.subtitleNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelFrozenAccount_Text, font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor) isUserInteractionEnabled = true @@ -128,8 +130,6 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode { displayCount = customChatContents.messageLimit ?? 20 case .businessLinkSetup: displayCount = 0 - case .postSuggestions: - displayCount = 0 } self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_QuickReplyMessageLimitReachedText(Int32(displayCount)), font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor) } diff --git a/submodules/TelegramUI/Sources/ChatTextInputActionButtonsNode.swift b/submodules/TelegramUI/Sources/ChatTextInputActionButtonsNode.swift index 816584b0c4..79d7e1d41b 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputActionButtonsNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputActionButtonsNode.swift @@ -290,13 +290,6 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessageAction } } starsAmount = amount - } else if case let .customChatContents(customChatContents) = interfaceState.subject { - switch customChatContents.kind { - case let .postSuggestions(postSuggestions): - starsAmount = postSuggestions.value - default: - break - } } if let amount = starsAmount { diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index e31573f32c..67d5485e5e 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -1567,8 +1567,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch break case .businessLinkSetup: displayMediaButton = false - case .postSuggestions: - break } } @@ -1955,10 +1953,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch } case .businessLinkSetup: placeholder = interfaceState.strings.Chat_Placeholder_BusinessLinkPreset - case let .postSuggestions(postSuggestions): - //TODO:localize - placeholder = "Suggest for # \(postSuggestions)" - placeholderHasStar = true } } @@ -1986,8 +1980,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch break case .businessLinkSetup: sendButtonHasApplyIcon = true - case .postSuggestions: - break } } } @@ -2515,8 +2507,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch showTitle = true } else if case let .customChatContents(customChatContents) = interfaceState.subject { switch customChatContents.kind { - case .postSuggestions: - showTitle = true default: break } @@ -3794,8 +3784,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch break case .businessLinkSetup: keepSendButtonEnabled = true - case .postSuggestions: - break } } } @@ -3916,8 +3904,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch break case .businessLinkSetup: hideMicButton = true - case .postSuggestions: - break } } } @@ -4023,8 +4009,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch break case .businessLinkSetup: sendButtonHasApplyIcon = true - case .postSuggestions: - break } } diff --git a/submodules/TelegramUI/Sources/ChatTopicListTitleAccessoryPanelNode.swift b/submodules/TelegramUI/Sources/ChatTopicListTitleAccessoryPanelNode.swift index 393f250524..bdd5503820 100644 --- a/submodules/TelegramUI/Sources/ChatTopicListTitleAccessoryPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTopicListTitleAccessoryPanelNode.swift @@ -321,7 +321,7 @@ final class ChatTopicListTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, C let iconSize = self.icon.update( transition: .immediate, component: AnyComponent(BundleIconComponent( - name: "Call/PanelIcon", + name: "Chat/Title Panels/SidebarIcon", tintColor: theme.rootController.navigationBar.secondaryTextColor, maxSize: nil, scaleFactor: 1.0 @@ -658,7 +658,7 @@ final class ChatTopicListTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, C let itemSpacing: CGFloat = 24.0 var contentSize = CGSize(width: 0.0, height: panelHeight) - contentSize.width += containerInsets.left + contentSize.width += containerInsets.left + 8.0 var validIds: [Item.Id] = [] var isFirst = true @@ -862,4 +862,22 @@ final class ChatTopicListTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, C } } } + + public func updateGlobalOffset(globalOffset: CGFloat, transition: ComponentTransition) { + if let tabItemView = self.tabItemView { + transition.setTransform(view: tabItemView, transform: CATransform3DMakeTranslation(0.0, -globalOffset, 0.0)) + } + } + + public func topicIndex(threadId: Int64?) -> Int? { + if let threadId { + if let value = self.items.firstIndex(where: { $0.id == .chatList(PeerId(threadId)) }) { + return value + 1 + } else { + return nil + } + } else { + return 0 + } + } } diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index c2a4eaa898..bda78d9ba0 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -300,7 +300,7 @@ func openResolvedUrlImpl( if let photoRepresentation = invite.photoRepresentation { photo.append(photoRepresentation) } - let channel = TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(0)), accessHash: .genericPublic(0), title: invite.title, username: nil, photo: photo, creationDate: 0, version: 0, participationStatus: .left, info: .broadcast(TelegramChannelBroadcastInfo(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: invite.nameColor, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil) + let channel = TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(0)), accessHash: .genericPublic(0), title: invite.title, username: nil, photo: photo, creationDate: 0, version: 0, participationStatus: .left, info: .broadcast(TelegramChannelBroadcastInfo(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: invite.nameColor, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil) let invoice = TelegramMediaInvoice(title: "", description: "", photo: nil, receiptMessageId: nil, currency: "XTR", totalAmount: subscriptionPricing.amount.value, startParam: "", extendedMedia: nil, subscriptionPeriod: nil, flags: [], version: 0) inputData.set(.single(BotCheckoutController.InputData( diff --git a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift index 7b485f6ed6..292d8ae989 100644 --- a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift +++ b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift @@ -193,6 +193,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu }, forceUpdateWarpContents: { }, playShakeAnimation: { }, displayQuickShare: { _, _ ,_ in + }, updateChatLocationThread: { _ in }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil)) self.dimNode = ASDisplayNode() diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index ba1599d62f..e9c49ce330 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -2388,6 +2388,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { }, forceUpdateWarpContents: { }, playShakeAnimation: { }, displayQuickShare: { _, _ ,_ in + }, updateChatLocationThread: { _ in }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: backgroundNode as? WallpaperBackgroundNode)) @@ -2408,7 +2409,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { } public func makeChatMessageDateHeaderItem(context: AccountContext, timestamp: Int32, theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, chatBubbleCorners: PresentationChatBubbleCorners, dateTimeFormat: PresentationDateTimeFormat, nameOrder: PresentationPersonNameOrder) -> ListViewItemHeader { - return ChatMessageDateHeader(timestamp: timestamp, scheduled: false, presentationData: ChatPresentationData(theme: ChatPresentationThemeData(theme: theme, wallpaper: wallpaper), fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameOrder, disableAnimations: false, largeEmoji: false, chatBubbleCorners: chatBubbleCorners, animatedEmojiScale: 1.0, isPreview: true), controllerInteraction: nil, context: context) + return ChatMessageDateHeader(timestamp: timestamp, separableThreadId: nil, scheduled: false, displayPeer: nil, presentationData: ChatPresentationData(theme: ChatPresentationThemeData(theme: theme, wallpaper: wallpaper), fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameOrder, disableAnimations: false, largeEmoji: false, chatBubbleCorners: chatBubbleCorners, animatedEmojiScale: 1.0, isPreview: true), controllerInteraction: nil, context: context) } public func makeChatMessageAvatarHeaderItem(context: AccountContext, timestamp: Int32, peer: Peer, message: Message, theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, chatBubbleCorners: PresentationChatBubbleCorners, dateTimeFormat: PresentationDateTimeFormat, nameOrder: PresentationPersonNameOrder) -> ListViewItemHeader { diff --git a/submodules/TgVoipWebrtc/BUILD b/submodules/TgVoipWebrtc/BUILD index 2b0e2106f8..0cf56d7598 100644 --- a/submodules/TgVoipWebrtc/BUILD +++ b/submodules/TgVoipWebrtc/BUILD @@ -24,7 +24,7 @@ sources = glob([ "tgcalls/tgcalls/**/*.cpp", "tgcalls/tgcalls/**/*.mm", "tgcalls/tgcalls/**/*.m", -], exclude = [ +], allow_empty=True, exclude = [ "tgcalls/tgcalls/legacy/**", "tgcalls/tgcalls/platform/tdesktop/**", "tgcalls/tgcalls/platform/android/**", @@ -60,7 +60,7 @@ sources = glob([ "tgcalls/tgcalls/platform/darwin/**/*.c", "tgcalls/tgcalls/third-party/**/*.cpp", "tgcalls/tgcalls/utils/**/*.cpp", -], exclude = [ +], allow_empty=True, exclude = [ "tgcalls/tgcalls/legacy/**", "tgcalls/tgcalls/platform/tdesktop/**", "tgcalls/tgcalls/platform/android/**", @@ -218,7 +218,7 @@ objc_library( srcs = glob([ "tests/*.m", "tests/*.mm", - ]), + ], allow_empty=True), deps = [ ":TgVoipWebrtc" ], diff --git a/submodules/Utils/LokiRng/BUILD b/submodules/Utils/LokiRng/BUILD index ac5a34a442..1141ebd653 100644 --- a/submodules/Utils/LokiRng/BUILD +++ b/submodules/Utils/LokiRng/BUILD @@ -8,7 +8,7 @@ objc_library( "Sources/**/*.mm", "Sources/**/*.h", "Sources/**/*.cpp", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/Utils/ShelfPack/BUILD b/submodules/Utils/ShelfPack/BUILD index bade2d97bd..92d0acbafe 100644 --- a/submodules/Utils/ShelfPack/BUILD +++ b/submodules/Utils/ShelfPack/BUILD @@ -8,7 +8,7 @@ objc_library( "Sources/**/*.mm", "Sources/**/*.h", "Sources/**/*.cpp", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/WatchBridge/Impl/BUILD b/submodules/WatchBridge/Impl/BUILD index 8127f989a9..764f26875a 100644 --- a/submodules/WatchBridge/Impl/BUILD +++ b/submodules/WatchBridge/Impl/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/WatchBridgeAudio/Impl/BUILD b/submodules/WatchBridgeAudio/Impl/BUILD index 8b1b386fb4..b1290acaa1 100644 --- a/submodules/WatchBridgeAudio/Impl/BUILD +++ b/submodules/WatchBridgeAudio/Impl/BUILD @@ -7,7 +7,7 @@ objc_library( "Sources/**/*.m", "Sources/**/*.mm", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/WatchCommon/Host/BUILD b/submodules/WatchCommon/Host/BUILD index 8d9c05aabf..043309a973 100644 --- a/submodules/WatchCommon/Host/BUILD +++ b/submodules/WatchCommon/Host/BUILD @@ -6,7 +6,7 @@ objc_library( srcs = glob([ "Sources/**/*.m", "Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "PublicHeaders/**/*.h", ]), diff --git a/submodules/WebPBinding/BUILD b/submodules/WebPBinding/BUILD index 171e072408..3b00918601 100644 --- a/submodules/WebPBinding/BUILD +++ b/submodules/WebPBinding/BUILD @@ -5,7 +5,6 @@ objc_library( module_name = "WebPBinding", srcs = glob([ "Sources/**/*.m", - "Sources/**/*.h", ]), hdrs = glob([ "PublicHeaders/**/*.h", diff --git a/submodules/WebUI/Sources/WebAppMessageChatPreviewItem.swift b/submodules/WebUI/Sources/WebAppMessageChatPreviewItem.swift index ae66455633..9f6133b1d6 100644 --- a/submodules/WebUI/Sources/WebAppMessageChatPreviewItem.swift +++ b/submodules/WebUI/Sources/WebAppMessageChatPreviewItem.swift @@ -296,8 +296,8 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode { header.updateNode(headerNode, previous: nil, next: nil) headerNode.item = header } - headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset) - headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, transition: .immediate) + headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset, transition: .immediate) + headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, distance: 0.0, transition: .immediate) } else { headerNode = header.node(synchronousLoad: true) if headerNode.item !== header { @@ -305,11 +305,11 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode { headerNode.item = header } headerNode.frame = headerFrame - headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset) + headerNode.updateLayoutInternal(size: headerFrame.size, leftInset: leftInset, rightInset: rightInset, transition: .immediate) strongSelf.itemHeaderNodes[id] = headerNode strongSelf.containerNode.addSubnode(headerNode) - headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, transition: .immediate) + headerNode.updateStickDistanceFactor(stickLocationDistanceFactor, distance: 0.0, transition: .immediate) } } } diff --git a/submodules/sqlcipher/BUILD b/submodules/sqlcipher/BUILD index 0df7412fc1..85e0a5f8c0 100644 --- a/submodules/sqlcipher/BUILD +++ b/submodules/sqlcipher/BUILD @@ -10,7 +10,7 @@ objc_library( srcs = glob([ "Sources/*.c", "Sources/*.h", - ], exclude = public_headers), + ], exclude = public_headers, allow_empty=True), hdrs = public_headers, includes = [ "PublicHeaders", diff --git a/third-party/boost_regex/BUILD b/third-party/boost_regex/BUILD index 6378492f2d..93b10a0232 100644 --- a/third-party/boost_regex/BUILD +++ b/third-party/boost_regex/BUILD @@ -8,10 +8,10 @@ objc_library( "Sources/**/*.cpp", "Sources/**/*.h", "Sources/**/*.hpp", - ]), + ], allow_empty=True), hdrs = glob([ "include/boost_regex/*.h", - ]), + ], allow_empty=True), includes = [ "include", ], diff --git a/third-party/libprisma/BUILD b/third-party/libprisma/BUILD index 7caecf7ac5..3ace0367e8 100644 --- a/third-party/libprisma/BUILD +++ b/third-party/libprisma/BUILD @@ -50,7 +50,7 @@ objc_library( "Sources/**/*.mm", "Sources/**/*.h", "Sources/**/*.hpp", - ]), + ], allow_empty=True), hdrs = glob([ "include/libprisma/*.h", ]), diff --git a/third-party/libyuv/BUILD b/third-party/libyuv/BUILD index 86428882d1..279d052531 100644 --- a/third-party/libyuv/BUILD +++ b/third-party/libyuv/BUILD @@ -118,7 +118,7 @@ objc_library( "LibYuvBinding/Sources/**/*.m", "LibYuvBinding/Sources/**/*.c", "LibYuvBinding/Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "LibYuvBinding/PublicHeaders/**/*.h", ]), diff --git a/third-party/openh264/BUILD b/third-party/openh264/BUILD index 9279609c80..3f7e8dc820 100644 --- a/third-party/openh264/BUILD +++ b/third-party/openh264/BUILD @@ -244,8 +244,8 @@ all_sources = arch_specific_sources + [ cc_library( name = "openh264", srcs = all_sources, - hdrs = glob([ - ]), + hdrs = [ + ], textual_hdrs = arch_specific_textual_hdrs, includes = [ ], diff --git a/third-party/recaptcha/BUILD b/third-party/recaptcha/BUILD index 50d806febc..bb626687a8 100644 --- a/third-party/recaptcha/BUILD +++ b/third-party/recaptcha/BUILD @@ -8,6 +8,8 @@ load( apple_static_xcframework_import( name = "RecaptchaEnterprise", xcframework_imports = glob(["RecaptchaEnterprise.xcframework/**"]), + features = [ + ], visibility = [ "//visibility:public", ], diff --git a/third-party/td/BUILD b/third-party/td/BUILD index a11c47625b..85a5e2d97d 100644 --- a/third-party/td/BUILD +++ b/third-party/td/BUILD @@ -128,7 +128,7 @@ objc_library( "TdBinding/Sources/**/*.m", "TdBinding/Sources/**/*.mm", "TdBinding/Sources/**/*.h", - ]), + ], allow_empty=True), hdrs = glob([ "TdBinding/Public/**/*.h", ]), diff --git a/versions.json b/versions.json index 040d815c36..ae9a377e5e 100644 --- a/versions.json +++ b/versions.json @@ -1,6 +1,6 @@ { "app": "11.11", - "xcode": "16.2", - "bazel": "7.3.1:981f82a470bad1349322b6f51c9c6ffa0aa291dab1014fac411543c12e661dff", + "xcode": "16.3", + "bazel": "8.2.1:22ff65b05869f6160e5157b1b425a14a62085d71d8baef571f462b8fe5a703a3", "macos": "15" }