Merge branch 'story-folders'
# Conflicts: # submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift
This commit is contained in:
commit
b20652120e
35 changed files with 1731 additions and 445 deletions
|
|
@ -1,6 +1,6 @@
|
|||
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_features", version = "1.30.0")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.7.1")
|
||||
bazel_dep(name = "platforms", version = "0.0.11")
|
||||
|
||||
|
|
|
|||
24
MODULE.bazel.lock
generated
24
MODULE.bazel.lock
generated
|
|
@ -20,9 +20,9 @@
|
|||
"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.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.30.0/source.json": "b07e17f067fe4f69f90b03b36ef1e08fe0d1f3cac254c1241a1818773e3423bc",
|
||||
"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",
|
||||
|
|
@ -81,12 +81,12 @@
|
|||
"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_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.1.1/source.json": "d61627377bd7dd1da4652063e368d9366fc9a73920bfa396798ad92172cf645c",
|
||||
"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",
|
||||
|
|
@ -100,8 +100,8 @@
|
|||
"https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
|
||||
"https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
|
||||
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.11.0/MODULE.bazel": "c3d280bc5ff1038dcb3bacb95d3f6b83da8dd27bba57820ec89ea4085da767ad",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.11.0/source.json": "302b52a39259a85aa06ca3addb9787864ca3e03b432a5f964ea68244397e7544",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.12.0/MODULE.bazel": "8e6590b961f2defdfc2811c089c75716cb2f06c8a4edeb9a8d85eaa64ee2a761",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.12.0/source.json": "cbd5d55d9d38d4008a7d00bee5b5a5a4b6031fcd4a56515c9accbcd42c7be2ba",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939",
|
||||
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
|
||||
|
|
@ -151,15 +151,15 @@
|
|||
"https://bcr.bazel.build/modules/xcodeproj/8.27.3/MODULE.bazel": "49276599207dae3df1e4336c2067505323dfb0606b53ef63e144087d1226e0eb",
|
||||
"https://bcr.bazel.build/modules/xcodeproj/8.27.3/source.json": "bbbb718187dcbdfbb3a9a0ec7d49446cdf48c67657cafd79b5cf33aa8918f608",
|
||||
"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.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca",
|
||||
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806",
|
||||
"https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198"
|
||||
},
|
||||
"selectedYankedVersions": {},
|
||||
"moduleExtensions": {
|
||||
"@@apple_support+//crosstool:setup.bzl%apple_cc_configure_extension": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "IK7QnlhcNBu2jc4wZoGZeDTu3keF2LldFiFUINRcKvo=",
|
||||
"bzlTransitiveDigest": "RjubjYIojbv0PxTpnoknalV9QzT9asbV7elDuN7m2A4=",
|
||||
"usagesDigest": "lfcV4HxPD+NLaRIT/v7BtSGFgE7c9xrWU7jDiwBAxzo=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
|
|
@ -190,7 +190,7 @@
|
|||
},
|
||||
"@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "sFhcgPbDQehmbD1EOXzX4H1q/CD5df8zwG4kp4jbvr8=",
|
||||
"bzlTransitiveDigest": "hUTp2w+RUVdL7ma5esCXZJAFnX7vLbVfLd7FwnQI6bU=",
|
||||
"usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
|
|
@ -290,7 +290,7 @@
|
|||
},
|
||||
"@@rules_xcodeproj+//xcodeproj:extensions.bzl%internal": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "+kmqZtEKFY8zgqpV6mrwdQkTJqGUZhL8b3ZMsxrqSyc=",
|
||||
"bzlTransitiveDigest": "6MYik+6MZUO7rOzaI0dUJYVD8dJrR1Q2rT+5vo1j73U=",
|
||||
"usagesDigest": "fvsnMonVwKDYnBfww4bXuYie3WU0d9VSqT2gePSdQco=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
|
|
@ -312,7 +312,7 @@
|
|||
},
|
||||
"@@rules_xcodeproj+//xcodeproj:extensions.bzl%non_module_deps": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "+kmqZtEKFY8zgqpV6mrwdQkTJqGUZhL8b3ZMsxrqSyc=",
|
||||
"bzlTransitiveDigest": "6MYik+6MZUO7rOzaI0dUJYVD8dJrR1Q2rT+5vo1j73U=",
|
||||
"usagesDigest": "jzxYhnOC9BE0dJ0biFLfxWXi/+R19uAAZkJ0p9CY0JI=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ def locate_bazel(base_path, cache_host_or_path, cache_dir):
|
|||
if test_sha256 == versions.bazel_version_sha256:
|
||||
shutil.copyfile(temp_output_file.name, bazel_path)
|
||||
elif resolved_cache_path is not None:
|
||||
(cache_cas_id, cache_cas_name) = cache_cas_name(versions.bazel_version_sha256)
|
||||
cached_path = '{}/cas/{}/{}'.format(resolved_cache_path, cache_cas_id, cache_cas_name)
|
||||
(cache_cas_id, cache_cas_name_value) = cache_cas_name(versions.bazel_version_sha256)
|
||||
cached_path = '{}/cas/{}/{}'.format(resolved_cache_path, cache_cas_id, cache_cas_name_value)
|
||||
if os.path.isfile(cached_path):
|
||||
shutil.copyfile(cached_path, bazel_path)
|
||||
|
||||
|
|
@ -137,8 +137,8 @@ def locate_bazel(base_path, cache_host_or_path, cache_dir):
|
|||
)
|
||||
], check_result=False)
|
||||
elif resolved_cache_path is not None:
|
||||
(cache_cas_id, cache_cas_name) = cache_cas_name(versions.bazel_version_sha256)
|
||||
cached_path = '{}/cas/{}/{}'.format(resolved_cache_path, cache_cas_id, cache_cas_name)
|
||||
(cache_cas_id, cache_cas_name_value) = cache_cas_name(versions.bazel_version_sha256)
|
||||
cached_path = '{}/cas/{}/{}'.format(resolved_cache_path, cache_cas_id, cache_cas_name_value)
|
||||
os.makedirs(os.path.dirname(cached_path), exist_ok=True)
|
||||
shutil.copyfile(bazel_path, cached_path)
|
||||
|
||||
|
|
|
|||
|
|
@ -330,6 +330,7 @@ public enum ResolvedUrl {
|
|||
case messageLink(link: TelegramResolvedMessageLink?)
|
||||
case stars
|
||||
case shareStory(Int64)
|
||||
case storyFolder(peerId: PeerId, id: Int64)
|
||||
}
|
||||
|
||||
public enum ResolveUrlResult {
|
||||
|
|
@ -667,6 +668,7 @@ public enum PeerInfoControllerMode {
|
|||
case myProfileGifts
|
||||
case groupsInCommon
|
||||
case monoforum(EnginePeer.Id)
|
||||
case storyAlbum(id: Int64)
|
||||
}
|
||||
|
||||
public enum ContactListActionItemInlineIconPosition {
|
||||
|
|
|
|||
|
|
@ -650,7 +650,8 @@ final class HashtagSearchControllerNode: ASDisplayNode, ASGestureRecognizerDeleg
|
|||
}
|
||||
return self.controller?.navigationController as? NavigationController
|
||||
},
|
||||
listContext: storySearchContext
|
||||
listContext: storySearchContext,
|
||||
initialStoryFolderId: nil
|
||||
)
|
||||
self.storySearchPaneNode = storySearchPaneNode
|
||||
if let storySearchView = self.storySearchComponentView?.view {
|
||||
|
|
|
|||
|
|
@ -1462,7 +1462,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration,
|
|||
|
||||
#if DEBUG
|
||||
//debugSaveState(basePath: basePath + "/db", name: "previous2")
|
||||
//debugRestoreState(basePath: basePath + "/db", name: "previous2")
|
||||
debugRestoreState(basePath: basePath + "/db", name: "previous2")
|
||||
#endif
|
||||
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
|
|
|||
|
|
@ -1550,7 +1550,7 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
|
|||
context: context,
|
||||
initialPrivacy: EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: state.peers),
|
||||
stateContext: stateContext,
|
||||
completion: { _, privacy ,_, _, _, _ in
|
||||
completion: { _, privacy ,_, _, _, _, _ in
|
||||
updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.peers = privacy.additionallyIncludePeers
|
||||
|
|
@ -1589,7 +1589,7 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
|
|||
context: context,
|
||||
initialPrivacy: EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: state.peers),
|
||||
stateContext: stateContext,
|
||||
completion: { _, privacy ,_, _, _, _ in
|
||||
completion: { _, privacy ,_, _, _, _, _ in
|
||||
updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.channels = privacy.additionallyIncludePeers
|
||||
|
|
|
|||
|
|
@ -5115,7 +5115,8 @@ func replayFinalState(
|
|||
isMy: item.isMy,
|
||||
myReaction: updatedReaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
))
|
||||
if let entry = CodableEntry(updatedItem) {
|
||||
updatedPeerEntries[index] = StoryItemsTableEntry(value: entry, id: item.id, expirationTimestamp: item.expirationTimestamp, isCloseFriends: item.isCloseFriends)
|
||||
|
|
@ -5149,7 +5150,8 @@ func replayFinalState(
|
|||
isMy: item.isMy,
|
||||
myReaction: MessageReaction.Reaction(apiReaction: reaction),
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
))
|
||||
if let entry = CodableEntry(updatedItem) {
|
||||
transaction.setStory(id: StoryId(peerId: peerId, id: id), value: entry)
|
||||
|
|
|
|||
|
|
@ -350,7 +350,8 @@ private final class StoryStatsPublicForwardsContextImpl {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
resultForwards.append(.story(EnginePeer(peer), mappedItem))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -559,7 +559,8 @@ public final class EngineStoryViewListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
),
|
||||
storyStats: transaction.getPeerStoryStats(peerId: peer.id)
|
||||
)))
|
||||
|
|
@ -599,7 +600,8 @@ public final class EngineStoryViewListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
))
|
||||
if let entry = CodableEntry(updatedItem) {
|
||||
transaction.setStory(id: StoryId(peerId: account.peerId, id: storyId), value: entry)
|
||||
|
|
@ -639,7 +641,8 @@ public final class EngineStoryViewListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
))
|
||||
if let entry = CodableEntry(updatedItem) {
|
||||
currentItems[i] = StoryItemsTableEntry(value: entry, id: updatedItem.id, expirationTimestamp: updatedItem.expirationTimestamp, isCloseFriends: updatedItem.isCloseFriends)
|
||||
|
|
@ -756,7 +759,8 @@ public final class EngineStoryViewListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
),
|
||||
storyStats: transaction.getPeerStoryStats(peerId: peer.id)
|
||||
)))
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ public extension Stories {
|
|||
case randomId
|
||||
case forwardInfo
|
||||
case uploadInfo
|
||||
case folders
|
||||
}
|
||||
|
||||
public let target: PendingTarget
|
||||
|
|
@ -114,6 +115,7 @@ public extension Stories {
|
|||
public let period: Int32
|
||||
public let randomId: Int64
|
||||
public let forwardInfo: PendingForwardInfo?
|
||||
public let folders: [Int64]
|
||||
public let uploadInfo: StoryUploadInfo?
|
||||
|
||||
public init(
|
||||
|
|
@ -131,6 +133,7 @@ public extension Stories {
|
|||
period: Int32,
|
||||
randomId: Int64,
|
||||
forwardInfo: PendingForwardInfo?,
|
||||
folders: [Int64],
|
||||
uploadInfo: StoryUploadInfo?
|
||||
) {
|
||||
self.target = target
|
||||
|
|
@ -147,6 +150,7 @@ public extension Stories {
|
|||
self.period = period
|
||||
self.randomId = randomId
|
||||
self.forwardInfo = forwardInfo
|
||||
self.folders = folders
|
||||
self.uploadInfo = uploadInfo
|
||||
}
|
||||
|
||||
|
|
@ -176,6 +180,8 @@ public extension Stories {
|
|||
|
||||
self.forwardInfo = try container.decodeIfPresent(PendingForwardInfo.self, forKey: .forwardInfo)
|
||||
|
||||
self.folders = try container.decodeIfPresent([Int64].self, forKey: .folders) ?? []
|
||||
|
||||
self.uploadInfo = try container.decodeIfPresent(StoryUploadInfo.self, forKey: .uploadInfo)
|
||||
}
|
||||
|
||||
|
|
@ -205,6 +211,7 @@ public extension Stories {
|
|||
try container.encode(self.period, forKey: .period)
|
||||
try container.encode(self.randomId, forKey: .randomId)
|
||||
try container.encodeIfPresent(self.forwardInfo, forKey: .forwardInfo)
|
||||
try container.encode(self.folders, forKey: .folders)
|
||||
try container.encodeIfPresent(self.uploadInfo, forKey: .uploadInfo)
|
||||
}
|
||||
|
||||
|
|
@ -245,6 +252,9 @@ public extension Stories {
|
|||
if lhs.forwardInfo != rhs.forwardInfo {
|
||||
return false
|
||||
}
|
||||
if lhs.folders != rhs.folders {
|
||||
return false
|
||||
}
|
||||
if lhs.uploadInfo != rhs.uploadInfo {
|
||||
return false
|
||||
}
|
||||
|
|
@ -473,7 +483,7 @@ final class PendingStoryManager {
|
|||
let partTotalProgress = 1.0 / Float(uploadInfo.total)
|
||||
pendingItemContext.progress = Float(uploadInfo.index) * partTotalProgress
|
||||
}
|
||||
pendingItemContext.disposable = (_internal_uploadStoryImpl(postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, stateManager: self.stateManager, messageMediaPreuploadManager: self.messageMediaPreuploadManager, revalidationContext: self.revalidationContext, auxiliaryMethods: self.auxiliaryMethods, toPeerId: toPeerId, stableId: stableId, media: firstItem.media, mediaAreas: firstItem.mediaAreas, text: firstItem.text, entities: firstItem.entities, embeddedStickers: firstItem.embeddedStickers, pin: firstItem.pin, privacy: firstItem.privacy, isForwardingDisabled: firstItem.isForwardingDisabled, period: Int(firstItem.period), randomId: firstItem.randomId, forwardInfo: firstItem.forwardInfo)
|
||||
pendingItemContext.disposable = (_internal_uploadStoryImpl(postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, stateManager: self.stateManager, messageMediaPreuploadManager: self.messageMediaPreuploadManager, revalidationContext: self.revalidationContext, auxiliaryMethods: self.auxiliaryMethods, toPeerId: toPeerId, stableId: stableId, media: firstItem.media, mediaAreas: firstItem.mediaAreas, text: firstItem.text, entities: firstItem.entities, embeddedStickers: firstItem.embeddedStickers, pin: firstItem.pin, privacy: firstItem.privacy, isForwardingDisabled: firstItem.isForwardingDisabled, period: Int(firstItem.period), folders: firstItem.folders, randomId: firstItem.randomId, forwardInfo: firstItem.forwardInfo)
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] event in
|
||||
guard let `self` = self else {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ public enum Stories {
|
|||
case myReaction
|
||||
case forwardInfo
|
||||
case authorId
|
||||
case folderIds
|
||||
}
|
||||
|
||||
public let id: Int32
|
||||
|
|
@ -287,6 +288,7 @@ public enum Stories {
|
|||
public let myReaction: MessageReaction.Reaction?
|
||||
public let forwardInfo: ForwardInfo?
|
||||
public let authorId: PeerId?
|
||||
public let folderIds: [Int64]?
|
||||
|
||||
public init(
|
||||
id: Int32,
|
||||
|
|
@ -310,7 +312,8 @@ public enum Stories {
|
|||
isMy: Bool,
|
||||
myReaction: MessageReaction.Reaction?,
|
||||
forwardInfo: ForwardInfo?,
|
||||
authorId: PeerId?
|
||||
authorId: PeerId?,
|
||||
folderIds: [Int64]?
|
||||
) {
|
||||
self.id = id
|
||||
self.timestamp = timestamp
|
||||
|
|
@ -334,6 +337,7 @@ public enum Stories {
|
|||
self.myReaction = myReaction
|
||||
self.forwardInfo = forwardInfo
|
||||
self.authorId = authorId
|
||||
self.folderIds = folderIds
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
|
|
@ -381,6 +385,7 @@ public enum Stories {
|
|||
self.myReaction = try container.decodeIfPresent(MessageReaction.Reaction.self, forKey: .myReaction)
|
||||
self.forwardInfo = try container.decodeIfPresent(ForwardInfo.self, forKey: .forwardInfo)
|
||||
self.authorId = try container.decodeIfPresent(Int64.self, forKey: .authorId).flatMap { PeerId($0) }
|
||||
self.folderIds = try container.decodeIfPresent([Int64].self, forKey: .folderIds)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
|
|
@ -422,6 +427,7 @@ public enum Stories {
|
|||
try container.encodeIfPresent(self.myReaction, forKey: .myReaction)
|
||||
try container.encodeIfPresent(self.forwardInfo, forKey: .forwardInfo)
|
||||
try container.encodeIfPresent(self.authorId?.toInt64(), forKey: .authorId)
|
||||
try container.encodeIfPresent(self.folderIds, forKey: .folderIds)
|
||||
}
|
||||
|
||||
public static func ==(lhs: Item, rhs: Item) -> Bool {
|
||||
|
|
@ -497,6 +503,9 @@ public enum Stories {
|
|||
if lhs.authorId != rhs.authorId {
|
||||
return false
|
||||
}
|
||||
if lhs.folderIds != rhs.folderIds {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -988,7 +997,7 @@ public struct StoryUploadInfo: Codable, Equatable {
|
|||
}
|
||||
}
|
||||
|
||||
func _internal_uploadStory(account: Account, target: Stories.PendingTarget, media: EngineStoryInputMedia, mediaAreas: [MediaArea], text: String, entities: [MessageTextEntity], pin: Bool, privacy: EngineStoryPrivacy, isForwardingDisabled: Bool, period: Int, randomId: Int64, forwardInfo: Stories.PendingForwardInfo?, uploadInfo: StoryUploadInfo? = nil) -> Signal<Int32, NoError> {
|
||||
func _internal_uploadStory(account: Account, target: Stories.PendingTarget, media: EngineStoryInputMedia, mediaAreas: [MediaArea], text: String, entities: [MessageTextEntity], pin: Bool, privacy: EngineStoryPrivacy, isForwardingDisabled: Bool, period: Int, randomId: Int64, forwardInfo: Stories.PendingForwardInfo?, folders: [Int64], uploadInfo: StoryUploadInfo? = nil) -> Signal<Int32, NoError> {
|
||||
let inputMedia = prepareUploadStoryContent(account: account, media: media)
|
||||
|
||||
return (account.postbox.transaction { transaction in
|
||||
|
|
@ -1017,6 +1026,7 @@ func _internal_uploadStory(account: Account, target: Stories.PendingTarget, medi
|
|||
period: Int32(period),
|
||||
randomId: randomId,
|
||||
forwardInfo: forwardInfo,
|
||||
folders: folders,
|
||||
uploadInfo: uploadInfo
|
||||
))
|
||||
transaction.setLocalStoryState(state: CodableEntry(currentState))
|
||||
|
|
@ -1064,6 +1074,7 @@ func _internal_cancelStoryUpload(account: Account, stableId: Int32) {
|
|||
period: currentState.items[i].period,
|
||||
randomId: currentState.items[i].randomId,
|
||||
forwardInfo: currentState.items[i].forwardInfo,
|
||||
folders: currentState.items[i].folders,
|
||||
uploadInfo: StoryUploadInfo(
|
||||
groupingId: groupingId,
|
||||
index: newIndex,
|
||||
|
|
@ -1141,6 +1152,7 @@ func _internal_uploadStoryImpl(
|
|||
privacy: EngineStoryPrivacy,
|
||||
isForwardingDisabled: Bool,
|
||||
period: Int,
|
||||
folders: [Int64],
|
||||
randomId: Int64,
|
||||
forwardInfo: Stories.PendingForwardInfo?
|
||||
) -> Signal<StoryUploadResult, NoError> {
|
||||
|
|
@ -1224,6 +1236,10 @@ func _internal_uploadStoryImpl(
|
|||
fwdFromStory = forwardInfo.storyId
|
||||
}
|
||||
|
||||
if !folders.isEmpty {
|
||||
flags |= 1 << 8
|
||||
}
|
||||
|
||||
return network.request(Api.functions.stories.sendStory(
|
||||
flags: flags,
|
||||
peer: inputPeer,
|
||||
|
|
@ -1236,7 +1252,7 @@ func _internal_uploadStoryImpl(
|
|||
period: Int32(period),
|
||||
fwdFromId: fwdFromId,
|
||||
fwdFromStory: fwdFromStory,
|
||||
albums: nil
|
||||
albums: folders.isEmpty ? nil : folders.map(Int32.init(clamping:))
|
||||
))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
|
|
@ -1287,7 +1303,8 @@ func _internal_uploadStoryImpl(
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: fromId?.peerId
|
||||
authorId: fromId?.peerId,
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
if let entry = CodableEntry(Stories.StoredItem.item(updatedItem)) {
|
||||
items.append(StoryItemsTableEntry(value: entry, id: item.id, expirationTimestamp: updatedItem.expirationTimestamp, isCloseFriends: updatedItem.isCloseFriends))
|
||||
|
|
@ -1695,7 +1712,8 @@ func _internal_editStoryPrivacy(account: Account, id: Int32, privacy: EngineStor
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
if let entry = CodableEntry(Stories.StoredItem.item(updatedItem)) {
|
||||
transaction.setStory(id: storyId, value: entry)
|
||||
|
|
@ -1727,7 +1745,8 @@ func _internal_editStoryPrivacy(account: Account, id: Int32, privacy: EngineStor
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
if let entry = CodableEntry(Stories.StoredItem.item(updatedItem)) {
|
||||
items[index] = StoryItemsTableEntry(value: entry, id: item.id, expirationTimestamp: updatedItem.expirationTimestamp, isCloseFriends: updatedItem.isCloseFriends)
|
||||
|
|
@ -1923,7 +1942,8 @@ func _internal_updateStoriesArePinned(account: Account, peerId: PeerId, ids: [In
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
if let entry = CodableEntry(Stories.StoredItem.item(updatedItem)) {
|
||||
items[index] = StoryItemsTableEntry(value: entry, id: item.id, expirationTimestamp: updatedItem.expirationTimestamp, isCloseFriends: updatedItem.isCloseFriends)
|
||||
|
|
@ -1954,7 +1974,8 @@ func _internal_updateStoriesArePinned(account: Account, peerId: PeerId, ids: [In
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
updatedItems.append(updatedItem)
|
||||
}
|
||||
|
|
@ -2073,7 +2094,12 @@ extension Stories.Item.ForwardInfo {
|
|||
extension Stories.StoredItem {
|
||||
init?(apiStoryItem: Api.StoryItem, existingItem: Stories.Item? = nil, peerId: PeerId, transaction: Transaction) {
|
||||
switch apiStoryItem {
|
||||
case let .storyItem(flags, id, date, fromId, forwardFrom, expireDate, caption, entities, media, mediaAreas, privacy, views, sentReaction, _):
|
||||
case let .storyItem(flags, id, date, fromId, forwardFrom, expireDate, caption, entities, media, mediaAreas, privacy, views, sentReaction, albums):
|
||||
var folderIds: [Int64]?
|
||||
if let albums {
|
||||
folderIds = albums.map(Int64.init)
|
||||
}
|
||||
|
||||
let parsedMedia = textMediaAndExpirationTimerFromApiMedia(media, peerId).media
|
||||
if let parsedMedia = parsedMedia {
|
||||
var parsedPrivacy: Stories.Item.Privacy?
|
||||
|
|
@ -2185,7 +2211,8 @@ extension Stories.StoredItem {
|
|||
isMy: mergedIsMy,
|
||||
myReaction: mergedMyReaction,
|
||||
forwardInfo: mergedForwardInfo,
|
||||
authorId: fromId?.peerId
|
||||
authorId: fromId?.peerId,
|
||||
folderIds: folderIds
|
||||
)
|
||||
self = .item(item)
|
||||
} else {
|
||||
|
|
@ -2262,7 +2289,8 @@ func _internal_getStoryById(accountPeerId: PeerId, postbox: Postbox, network: Ne
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2739,7 +2767,8 @@ func _internal_setStoryReaction(account: Account, peerId: EnginePeer.Id, id: Int
|
|||
isMy: item.isMy,
|
||||
myReaction: reaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
))
|
||||
updatedItemValue = updatedItem
|
||||
if let entry = CodableEntry(updatedItem) {
|
||||
|
|
@ -2773,7 +2802,8 @@ func _internal_setStoryReaction(account: Account, peerId: EnginePeer.Id, id: Int
|
|||
isMy: item.isMy,
|
||||
myReaction: reaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
))
|
||||
updatedItemValue = updatedItem
|
||||
if let entry = CodableEntry(updatedItem) {
|
||||
|
|
|
|||
|
|
@ -86,8 +86,9 @@ public final class EngineStoryItem: Equatable {
|
|||
public let myReaction: MessageReaction.Reaction?
|
||||
public let forwardInfo: ForwardInfo?
|
||||
public let author: EnginePeer?
|
||||
public let folderIds: [Int64]?
|
||||
|
||||
public init(id: Int32, timestamp: Int32, expirationTimestamp: Int32, media: EngineMedia, alternativeMediaList: [EngineMedia], mediaAreas: [MediaArea], text: String, entities: [MessageTextEntity], views: Views?, privacy: EngineStoryPrivacy?, isPinned: Bool, isExpired: Bool, isPublic: Bool, isPending: Bool, isCloseFriends: Bool, isContacts: Bool, isSelectedContacts: Bool, isForwardingDisabled: Bool, isEdited: Bool, isMy: Bool, myReaction: MessageReaction.Reaction?, forwardInfo: ForwardInfo?, author: EnginePeer?) {
|
||||
public init(id: Int32, timestamp: Int32, expirationTimestamp: Int32, media: EngineMedia, alternativeMediaList: [EngineMedia], mediaAreas: [MediaArea], text: String, entities: [MessageTextEntity], views: Views?, privacy: EngineStoryPrivacy?, isPinned: Bool, isExpired: Bool, isPublic: Bool, isPending: Bool, isCloseFriends: Bool, isContacts: Bool, isSelectedContacts: Bool, isForwardingDisabled: Bool, isEdited: Bool, isMy: Bool, myReaction: MessageReaction.Reaction?, forwardInfo: ForwardInfo?, author: EnginePeer?, folderIds: [Int64]?) {
|
||||
self.id = id
|
||||
self.timestamp = timestamp
|
||||
self.expirationTimestamp = expirationTimestamp
|
||||
|
|
@ -111,6 +112,7 @@ public final class EngineStoryItem: Equatable {
|
|||
self.myReaction = myReaction
|
||||
self.forwardInfo = forwardInfo
|
||||
self.author = author
|
||||
self.folderIds = folderIds
|
||||
}
|
||||
|
||||
public static func ==(lhs: EngineStoryItem, rhs: EngineStoryItem) -> Bool {
|
||||
|
|
@ -183,6 +185,9 @@ public final class EngineStoryItem: Equatable {
|
|||
if lhs.author != rhs.author {
|
||||
return false
|
||||
}
|
||||
if lhs.folderIds != rhs.folderIds {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -237,7 +242,8 @@ public extension EngineStoryItem {
|
|||
|
||||
myReaction: self.myReaction,
|
||||
forwardInfo: self.forwardInfo?.storedForwardInfo,
|
||||
authorId: self.author?.id
|
||||
authorId: self.author?.id,
|
||||
folderIds: self.folderIds
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -679,6 +685,8 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
return (nil, [], [], 0, [:], [], false)
|
||||
}
|
||||
|
||||
let mainFolders: [State.Folder] = cachedMain.folders
|
||||
|
||||
let cached: CachedPeerStoryListHead
|
||||
if let folderId {
|
||||
let key = ValueBoxKey(length: 8 + 1 + 8)
|
||||
|
|
@ -733,7 +741,8 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
items.append(State.Item(
|
||||
id: StoryId(peerId: peerId, id: mappedItem.id),
|
||||
|
|
@ -768,7 +777,7 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
|
||||
let peerReference = transaction.getPeer(peerId).flatMap(PeerReference.init)
|
||||
|
||||
return (peerReference, items, cached.pinnedIds, Int(cached.totalCount), allEntityFiles, cached.folders, true)
|
||||
return (peerReference, items, cached.pinnedIds, Int(cached.totalCount), allEntityFiles, mainFolders, true)
|
||||
}
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] peerReference, items, pinnedIds, totalCount, allEntityFiles, folders, hasCache in
|
||||
guard let self else {
|
||||
|
|
@ -828,103 +837,81 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
let accountPeerId = account.peerId
|
||||
let isArchived = self.isArchived
|
||||
let folderId = self.folderId
|
||||
let folders = self.stateValue.availableFolders
|
||||
let queue = self.queue
|
||||
self.requestDisposable = (self.account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<([State.Item], Int, PeerReference?, Bool), NoError> in
|
||||
guard let inputPeer = inputPeer else {
|
||||
return .single(([], 0, nil, false))
|
||||
|> mapToSignal { inputPeer -> Signal<([State.Item], Int, PeerReference?, [State.Folder], Bool), NoError> in
|
||||
guard let inputPeer else {
|
||||
return .single(([], 0, nil, [], false))
|
||||
}
|
||||
|
||||
let signal: Signal<Api.stories.Stories, MTRpcError>
|
||||
if isArchived {
|
||||
signal = account.network.request(Api.functions.stories.getStoriesArchive(peer: inputPeer, offsetId: Int32(loadMoreToken), limit: Int32(limit)))
|
||||
var signal: Signal<Api.stories.Stories?, MTRpcError>
|
||||
var additionalFolders: Signal<Api.stories.Albums?, MTRpcError> = .single(nil)
|
||||
if let folderId {
|
||||
signal = account.network.request(Api.functions.stories.getAlbumStories(peer: inputPeer, albumId: Int32(clamping: folderId), offset: Int32(loadMoreToken), limit: Int32(limit))) |> map(Optional.init)
|
||||
} else {
|
||||
signal = account.network.request(Api.functions.stories.getPinnedStories(peer: inputPeer, offsetId: Int32(loadMoreToken), limit: Int32(limit)))
|
||||
if isArchived {
|
||||
signal = account.network.request(Api.functions.stories.getStoriesArchive(peer: inputPeer, offsetId: Int32(loadMoreToken), limit: Int32(limit))) |> map(Optional.init)
|
||||
} else {
|
||||
signal = account.network.request(Api.functions.stories.getPinnedStories(peer: inputPeer, offsetId: Int32(loadMoreToken), limit: Int32(limit))) |> map(Optional.init)
|
||||
additionalFolders = account.network.request(Api.functions.stories.getAlbums(peer: inputPeer, hash: 0))
|
||||
|> map(Optional.init)
|
||||
}
|
||||
}
|
||||
return signal
|
||||
|> map { result -> Api.stories.Stories? in
|
||||
return result
|
||||
|
||||
#if DEBUG
|
||||
if folderId != nil {
|
||||
signal = signal |> delay(2.0, queue: queue)
|
||||
}
|
||||
|> `catch` { _ -> Signal<Api.stories.Stories?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<([State.Item], Int, PeerReference?, Bool), NoError> in
|
||||
guard let result = result else {
|
||||
return .single(([], 0, nil, false))
|
||||
#endif
|
||||
|
||||
return combineLatest(
|
||||
signal
|
||||
|> `catch` { _ -> Signal<Api.stories.Stories?, NoError> in
|
||||
return .single(nil)
|
||||
},
|
||||
additionalFolders
|
||||
|> `catch` { _ -> Signal<Api.stories.Albums?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
)
|
||||
|> mapToSignal { result, updatedFolders -> Signal<([State.Item], Int, PeerReference?, [State.Folder], Bool), NoError> in
|
||||
guard let result else {
|
||||
return .single(([], 0, nil, [], false))
|
||||
}
|
||||
|
||||
return account.postbox.transaction { transaction -> ([State.Item], Int, PeerReference?, Bool) in
|
||||
return account.postbox.transaction { transaction -> ([State.Item], Int, PeerReference?, [State.Folder], Bool) in
|
||||
var storyItems: [State.Item] = []
|
||||
var totalCount: Int = 0
|
||||
var hasMore: Bool = false
|
||||
var folderItems: [State.Folder] = []
|
||||
|
||||
if let folderId {
|
||||
let key = ValueBoxKey(length: 8 + 1 + 8)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: isArchived ? 1 : 0)
|
||||
key.setInt64(8 + 1, value: folderId)
|
||||
|
||||
var updatedItems: [Stories.StoredItem] = []
|
||||
if let currentEntry = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key))?.get(CachedPeerStoryListHead.self) {
|
||||
updatedItems = currentEntry.items
|
||||
}
|
||||
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: updatedItems, pinnedIds: [], totalCount: Int32(updatedItems.count), folders: [])) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
|
||||
for item in updatedItems {
|
||||
if case let .item(item) = item, let media = item.media {
|
||||
let mappedItem = EngineStoryItem(
|
||||
id: item.id,
|
||||
timestamp: item.timestamp,
|
||||
expirationTimestamp: item.expirationTimestamp,
|
||||
media: EngineMedia(media),
|
||||
alternativeMediaList: item.alternativeMediaList.map(EngineMedia.init),
|
||||
mediaAreas: item.mediaAreas,
|
||||
text: item.text,
|
||||
entities: item.entities,
|
||||
views: item.views.flatMap { views in
|
||||
return EngineStoryItem.Views(
|
||||
seenCount: views.seenCount,
|
||||
reactedCount: views.reactedCount,
|
||||
forwardCount: views.forwardCount,
|
||||
seenPeers: views.seenPeerIds.compactMap { id -> EnginePeer? in
|
||||
return transaction.getPeer(id).flatMap(EnginePeer.init)
|
||||
},
|
||||
reactions: views.reactions,
|
||||
hasList: views.hasList
|
||||
)
|
||||
},
|
||||
privacy: item.privacy.flatMap(EngineStoryPrivacy.init),
|
||||
isPinned: item.isPinned,
|
||||
isExpired: item.isExpired,
|
||||
isPublic: item.isPublic,
|
||||
isPending: false,
|
||||
isCloseFriends: item.isCloseFriends,
|
||||
isContacts: item.isContacts,
|
||||
isSelectedContacts: item.isSelectedContacts,
|
||||
isForwardingDisabled: item.isForwardingDisabled,
|
||||
isEdited: item.isEdited,
|
||||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
)
|
||||
storyItems.append(State.Item(
|
||||
id: StoryId(peerId: peerId, id: mappedItem.id),
|
||||
storyItem: mappedItem,
|
||||
peer: nil
|
||||
))
|
||||
if let updatedFolders {
|
||||
switch updatedFolders {
|
||||
case let .albums(_, albums):
|
||||
for album in albums {
|
||||
switch album {
|
||||
case let .storyAlbum(_, albumId, title, iconPhoto, iconVideo):
|
||||
let _ = iconPhoto
|
||||
let _ = iconVideo
|
||||
folderItems.append(State.Folder(
|
||||
id: Int64(albumId),
|
||||
title: title
|
||||
))
|
||||
}
|
||||
}
|
||||
case .albumsNotModified:
|
||||
break
|
||||
}
|
||||
} else {
|
||||
let key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: 0)
|
||||
|
||||
totalCount = storyItems.count
|
||||
hasMore = false
|
||||
|
||||
return (storyItems, totalCount, transaction.getPeer(peerId).flatMap(PeerReference.init), hasMore)
|
||||
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key))?.get(CachedPeerStoryListHead.self) {
|
||||
folderItems = cached.folders
|
||||
}
|
||||
}
|
||||
|
||||
switch result {
|
||||
|
|
@ -973,7 +960,8 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
storyItems.append(State.Item(
|
||||
id: StoryId(peerId: peerId, id: mappedItem.id),
|
||||
|
|
@ -985,20 +973,38 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
}
|
||||
|
||||
if loadMoreToken == 0 {
|
||||
let key: ValueBoxKey
|
||||
if let folderId {
|
||||
key = ValueBoxKey(length: 8 + 1 + 8)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: isArchived ? 1 : 0)
|
||||
key.setInt64(8 + 1, value: folderId)
|
||||
} else {
|
||||
key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: isArchived ? 1 : 0)
|
||||
}
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: storyItems.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: pinnedIds, totalCount: count, folders: folderId == nil ? folderItems : [])) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
} else if folderId == nil && updatedFolders != nil {
|
||||
let key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: isArchived ? 1 : 0)
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: storyItems.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: pinnedIds, totalCount: count, folders: folders)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
key.setInt8(8, value: 0)
|
||||
|
||||
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key))?.get(CachedPeerStoryListHead.self) {
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: cached.items, pinnedIds: cached.pinnedIds, totalCount: cached.totalCount, folders: folderItems)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (storyItems, totalCount, transaction.getPeer(peerId).flatMap(PeerReference.init), hasMore)
|
||||
return (storyItems, totalCount, transaction.getPeer(peerId).flatMap(PeerReference.init), folderItems, hasMore)
|
||||
}
|
||||
}
|
||||
}
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] storyItems, totalCount, peerReference, hasMore in
|
||||
|> deliverOn(queue)).start(next: { [weak self] storyItems, totalCount, peerReference, folderItems, hasMore in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -1022,6 +1028,8 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
updatedState.items.append(item)
|
||||
}
|
||||
|
||||
updatedState.availableFolders = folderItems
|
||||
|
||||
if updatedState.peerReference == nil {
|
||||
updatedState.peerReference = peerReference
|
||||
}
|
||||
|
|
@ -1147,7 +1155,8 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, peers: peers) },
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
), peer: nil)
|
||||
finalUpdatedState = updatedState
|
||||
}
|
||||
|
|
@ -1196,7 +1205,8 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, peers: peers) },
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
), peer: nil)
|
||||
finalUpdatedState = updatedState
|
||||
} else {
|
||||
|
|
@ -1247,7 +1257,8 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, peers: peers) },
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
), peer: nil))
|
||||
updatedState.items.sort(by: { lhs, rhs in
|
||||
let lhsPinned = updatedState.pinnedIds.firstIndex(of: lhs.storyItem.id)
|
||||
|
|
@ -1304,7 +1315,8 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, peers: peers) },
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
), peer: nil))
|
||||
updatedState.items.sort(by: { lhs, rhs in
|
||||
let lhsPinned = updatedState.pinnedIds.firstIndex(of: lhs.storyItem.id)
|
||||
|
|
@ -1376,55 +1388,143 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
})
|
||||
}
|
||||
|
||||
func addFolder(title: String) -> Int64 {
|
||||
let id = Int64.random(in: Int64.min ... Int64.max)
|
||||
|
||||
var state = self.stateValue
|
||||
state.availableFolders.append(StoryListContextState.Folder(id: id, title: title))
|
||||
self.stateValue = state
|
||||
|
||||
func addFolder(title: String, items: [EngineStoryItem], completion: @escaping (Int64?) -> Void) -> Disposable {
|
||||
let peerId = self.peerId
|
||||
let isArchived = self.isArchived
|
||||
let items = state.items
|
||||
let pinnedIds = state.pinnedIds
|
||||
let totalCount = state.totalCount
|
||||
let folders = state.availableFolders
|
||||
let _ = (self.account.postbox.transaction { transaction -> Void in
|
||||
let key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: isArchived ? 1 : 0)
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: items.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: pinnedIds, totalCount: Int32(totalCount), folders: folders)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
return (self.account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<Api.StoryAlbum?, NoError> in
|
||||
guard let inputPeer else {
|
||||
return .single(nil)
|
||||
}
|
||||
}).start()
|
||||
|
||||
return id
|
||||
return self.account.network.request(Api.functions.stories.createAlbum(
|
||||
peer: inputPeer, title: title, stories: items.map(\.id)))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.StoryAlbum?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] result in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if let result {
|
||||
switch result {
|
||||
case let .storyAlbum(_, albumId, _, _, _):
|
||||
var state = self.stateValue
|
||||
state.availableFolders.insert(StoryListContextState.Folder(id: Int64(albumId), title: title), at: 0)
|
||||
self.stateValue = state
|
||||
|
||||
let peerId = self.peerId
|
||||
let isArchived = self.isArchived
|
||||
let items = state.items
|
||||
let pinnedIds = state.pinnedIds
|
||||
let totalCount = state.totalCount
|
||||
let folders = state.availableFolders
|
||||
let _ = (self.account.postbox.transaction { transaction -> Void in
|
||||
let key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: isArchived ? 1 : 0)
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: items.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: pinnedIds, totalCount: Int32(totalCount), folders: folders)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
|
||||
let mappedItems = items.map { item in
|
||||
return item.storyItem.asStoryItem()
|
||||
}
|
||||
|
||||
let folderKey = ValueBoxKey(length: 8 + 1 + 8)
|
||||
folderKey.setInt64(0, value: peerId.toInt64())
|
||||
folderKey.setInt8(8, value: 0)
|
||||
folderKey.setInt64(8 + 1, value: Int64(albumId))
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: mappedItems.prefix(100).map { .item($0) }, pinnedIds: [], totalCount: Int32(mappedItems.count), folders: [])) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: folderKey), entry: entry)
|
||||
}
|
||||
} |> deliverOn(self.queue)).start(completed: {
|
||||
completion(Int64(albumId))
|
||||
})
|
||||
}
|
||||
} else {
|
||||
completion(nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func removeFolder(id: Int64) {
|
||||
func removeFolder(id: Int64) -> Disposable {
|
||||
var state = self.stateValue
|
||||
if let index = state.availableFolders.firstIndex(where: { $0.id == id }) {
|
||||
state.availableFolders.remove(at: index)
|
||||
}
|
||||
self.stateValue = state
|
||||
|
||||
let account = self.account
|
||||
let peerId = self.peerId
|
||||
let isArchived = self.isArchived
|
||||
let items = state.items
|
||||
let pinnedIds = state.pinnedIds
|
||||
let totalCount = state.totalCount
|
||||
let folders = state.availableFolders
|
||||
let _ = (self.account.postbox.transaction { transaction -> Void in
|
||||
return (account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
let key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: isArchived ? 1 : 0)
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: items.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: pinnedIds, totalCount: Int32(totalCount), folders: folders)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|
||||
guard let inputPeer else {
|
||||
return .complete()
|
||||
}
|
||||
return account.network.request(Api.functions.stories.deleteAlbum(peer: inputPeer, albumId: Int32(clamping: id)))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> ignoreValues
|
||||
}).start()
|
||||
}
|
||||
|
||||
func reorderFolders(ids: [Int64]) {
|
||||
func renameFolder(id: Int64, title: String) -> Disposable {
|
||||
var state = self.stateValue
|
||||
if let index = state.availableFolders.firstIndex(where: { $0.id == id }) {
|
||||
state.availableFolders[index] = State.Folder(id: state.availableFolders[index].id, title: title)
|
||||
}
|
||||
self.stateValue = state
|
||||
let updatedFolders = state.availableFolders
|
||||
|
||||
let account = self.account
|
||||
let peerId = self.peerId
|
||||
return (account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
let key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: 0)
|
||||
|
||||
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key))?.get(CachedPeerStoryListHead.self) {
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: cached.items, pinnedIds: cached.pinnedIds, totalCount: cached.totalCount, folders: updatedFolders)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
}
|
||||
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|
||||
guard let inputPeer else {
|
||||
return .complete()
|
||||
}
|
||||
var flags: Int32 = 0
|
||||
flags |= 1 << 0
|
||||
return account.network.request(Api.functions.stories.updateAlbum(flags: flags, peer: inputPeer, albumId: Int32(clamping: id), title: title, deleteStories: nil, addStories: nil, order: nil))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.StoryAlbum?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> ignoreValues
|
||||
}).start()
|
||||
}
|
||||
|
||||
func reorderFolders(ids: [Int64]) -> Disposable {
|
||||
var state = self.stateValue
|
||||
var folders: [State.Folder] = []
|
||||
for id in ids {
|
||||
|
|
@ -1440,24 +1540,51 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
state.availableFolders = folders
|
||||
self.stateValue = state
|
||||
|
||||
let account = self.account
|
||||
let peerId = self.peerId
|
||||
let isArchived = self.isArchived
|
||||
let items = state.items
|
||||
let pinnedIds = state.pinnedIds
|
||||
let totalCount = state.totalCount
|
||||
let _ = (self.account.postbox.transaction { transaction -> Void in
|
||||
return (account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
let key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: isArchived ? 1 : 0)
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: items.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: pinnedIds, totalCount: Int32(totalCount), folders: folders)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|
||||
guard let inputPeer else {
|
||||
return .complete()
|
||||
}
|
||||
return account.network.request(Api.functions.stories.reorderAlbums(peer: inputPeer, order: ids.map(Int32.init(clamping:))))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> ignoreValues
|
||||
}).start()
|
||||
}
|
||||
|
||||
func addToFolder(id: Int64, items: [EngineStoryItem]) {
|
||||
func addToFolder(id: Int64, items: [EngineStoryItem]) -> Disposable {
|
||||
if self.folderId == id {
|
||||
var state = self.stateValue
|
||||
for item in items {
|
||||
state.items.removeAll(where: { $0.id.id == item.id })
|
||||
state.items.insert(StoryListContextState.Item(
|
||||
id: StoryId(peerId: self.peerId, id: item.id),
|
||||
storyItem: item,
|
||||
peer: nil
|
||||
), at: 0)
|
||||
}
|
||||
state.totalCount = state.items.count
|
||||
self.stateValue = state
|
||||
}
|
||||
|
||||
let account = self.account
|
||||
let peerId = self.peerId
|
||||
let _ = (self.account.postbox.transaction { transaction -> Void in
|
||||
return (account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
let key = ValueBoxKey(length: 8 + 1 + 8)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: 0)
|
||||
|
|
@ -1518,7 +1645,8 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
return .unknown(name: name, isModified: isModified)
|
||||
}
|
||||
},
|
||||
authorId: item.author?.id
|
||||
authorId: item.author?.id,
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
if !updatedItems.contains(where: { $0.id == mappedItem.id }) {
|
||||
updatedItems.insert(mappedItem, at: 0)
|
||||
|
|
@ -1528,26 +1656,35 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
if let entry = CodableEntry(CachedPeerStoryListHead(items: updatedItems.map { .item($0) }, pinnedIds: [], totalCount: Int32(updatedItems.count), folders: [])) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|
||||
guard let inputPeer else {
|
||||
return .complete()
|
||||
}
|
||||
var flags: Int32 = 0
|
||||
flags |= 1 << 2
|
||||
return account.network.request(Api.functions.stories.updateAlbum(flags: flags, peer: inputPeer, albumId: Int32(clamping: id), title: nil, deleteStories: nil, addStories: items.map(\.id), order: nil))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.StoryAlbum?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> ignoreValues
|
||||
}).start()
|
||||
|
||||
}
|
||||
|
||||
func removeFromFolder(id: Int64, itemIds: [Int32]) -> Disposable {
|
||||
if self.folderId == id {
|
||||
var state = self.stateValue
|
||||
for item in items {
|
||||
state.items.removeAll(where: { $0.id.id == item.id })
|
||||
state.items.insert(StoryListContextState.Item(
|
||||
id: StoryId(peerId: self.peerId, id: item.id),
|
||||
storyItem: item,
|
||||
peer: nil
|
||||
), at: 0)
|
||||
}
|
||||
state.items.removeAll(where: { itemIds.contains($0.id.id) })
|
||||
state.totalCount = state.items.count
|
||||
self.stateValue = state
|
||||
}
|
||||
}
|
||||
|
||||
func removeFromFolder(id: Int64, itemIds: [Int32]) {
|
||||
|
||||
let account = self.account
|
||||
let peerId = self.peerId
|
||||
let _ = (self.account.postbox.transaction { transaction -> Void in
|
||||
return (account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
let key = ValueBoxKey(length: 8 + 1 + 8)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: 0)
|
||||
|
|
@ -1573,23 +1710,52 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
if let entry = CodableEntry(CachedPeerStoryListHead(items: updatedItems.map { .item($0) }, pinnedIds: [], totalCount: Int32(updatedItems.count), folders: [])) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|
||||
guard let inputPeer else {
|
||||
return .complete()
|
||||
}
|
||||
var flags: Int32 = 0
|
||||
flags |= 1 << 1
|
||||
return account.network.request(Api.functions.stories.updateAlbum(flags: flags, peer: inputPeer, albumId: Int32(clamping: id), title: nil, deleteStories: itemIds, addStories: nil, order: nil))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.StoryAlbum?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> ignoreValues
|
||||
}).start()
|
||||
}
|
||||
|
||||
func reorderItemsInFolder(itemIds: [Int32]) -> Disposable {
|
||||
guard let id = self.folderId else {
|
||||
return EmptyDisposable
|
||||
}
|
||||
|
||||
if self.folderId == id {
|
||||
var state = self.stateValue
|
||||
state.items.removeAll(where: { itemIds.contains($0.id.id) })
|
||||
state.totalCount = state.items.count
|
||||
|
||||
let previousItems = state.items
|
||||
var updatedItems: [State.Item] = []
|
||||
for itemId in itemIds {
|
||||
if let index = previousItems.firstIndex(where: { $0.id.id == itemId }) {
|
||||
updatedItems.append(previousItems[index])
|
||||
}
|
||||
}
|
||||
for item in previousItems {
|
||||
if !updatedItems.contains(where: { $0.id == item.id }) {
|
||||
updatedItems.append(item)
|
||||
}
|
||||
}
|
||||
|
||||
state.items = updatedItems
|
||||
self.stateValue = state
|
||||
}
|
||||
}
|
||||
|
||||
func reorderItemsInFolder(itemIds: [Int32]) {
|
||||
guard let id = self.folderId else {
|
||||
return
|
||||
}
|
||||
|
||||
let account = self.account
|
||||
let peerId = self.peerId
|
||||
let _ = (self.account.postbox.transaction { transaction -> Void in
|
||||
return (account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
let key = ValueBoxKey(length: 8 + 1 + 8)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: 0)
|
||||
|
|
@ -1622,27 +1788,22 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
if let entry = CodableEntry(CachedPeerStoryListHead(items: updatedItems.map { .item($0) }, pinnedIds: [], totalCount: Int32(updatedItems.count), folders: [])) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
}).start()
|
||||
|
||||
if self.folderId == id {
|
||||
var state = self.stateValue
|
||||
|
||||
let previousItems = state.items
|
||||
var updatedItems: [State.Item] = []
|
||||
for itemId in itemIds {
|
||||
if let index = previousItems.firstIndex(where: { $0.id.id == itemId }) {
|
||||
updatedItems.append(previousItems[index])
|
||||
}
|
||||
}
|
||||
for item in previousItems {
|
||||
if !updatedItems.contains(where: { $0.id == item.id }) {
|
||||
updatedItems.append(item)
|
||||
}
|
||||
}
|
||||
|
||||
state.items = updatedItems
|
||||
self.stateValue = state
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|
||||
guard let inputPeer else {
|
||||
return .complete()
|
||||
}
|
||||
var flags: Int32 = 0
|
||||
flags |= 1 << 3
|
||||
return account.network.request(Api.functions.stories.updateAlbum(flags: flags, peer: inputPeer, albumId: Int32(clamping: id), title: nil, deleteStories: nil, addStories: nil, order: itemIds))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.StoryAlbum?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> ignoreValues
|
||||
}).start()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1676,61 +1837,100 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
}
|
||||
}
|
||||
|
||||
public func addFolder(title: String, completion: @escaping (Int64) -> Void) {
|
||||
public func addFolder(title: String, items: [EngineStoryItem], completion: @escaping (Int64?) -> Void) -> Disposable {
|
||||
let disposable = MetaDisposable()
|
||||
self.impl.with { impl in
|
||||
completion(impl.addFolder(title: title))
|
||||
disposable.set(impl.addFolder(title: title, items: items, completion: completion))
|
||||
}
|
||||
return disposable
|
||||
}
|
||||
|
||||
public func removeFolder(id: Int64) {
|
||||
public func removeFolder(id: Int64) -> Disposable {
|
||||
let disposable = MetaDisposable()
|
||||
self.impl.with { impl in
|
||||
impl.removeFolder(id: id)
|
||||
disposable.set(impl.removeFolder(id: id))
|
||||
}
|
||||
return disposable
|
||||
}
|
||||
|
||||
public func reorderFolders(ids: [Int64]) {
|
||||
public func renameFolder(id: Int64, title: String) -> Disposable {
|
||||
let disposable = MetaDisposable()
|
||||
self.impl.with { impl in
|
||||
impl.reorderFolders(ids: ids)
|
||||
disposable.set(impl.renameFolder(id: id, title: title))
|
||||
}
|
||||
return disposable
|
||||
}
|
||||
|
||||
public func addToFolder(id: Int64, items: [EngineStoryItem]) {
|
||||
public func reorderFolders(ids: [Int64]) -> Disposable {
|
||||
let disposable = MetaDisposable()
|
||||
self.impl.with { impl in
|
||||
impl.addToFolder(id: id, items: items)
|
||||
disposable.set(impl.reorderFolders(ids: ids))
|
||||
}
|
||||
return disposable
|
||||
}
|
||||
|
||||
public func removeFromFolder(id: Int64, itemIds: [Int32]) {
|
||||
public func addToFolder(id: Int64, items: [EngineStoryItem]) -> Disposable {
|
||||
let disposable = MetaDisposable()
|
||||
self.impl.with { impl in
|
||||
impl.removeFromFolder(id: id, itemIds: itemIds)
|
||||
disposable.set(impl.addToFolder(id: id, items: items))
|
||||
}
|
||||
return disposable
|
||||
}
|
||||
|
||||
public func reorderItemsInFolder(itemIds: [Int32]) {
|
||||
public func removeFromFolder(id: Int64, itemIds: [Int32]) -> Disposable {
|
||||
let disposable = MetaDisposable()
|
||||
self.impl.with { impl in
|
||||
impl.reorderItemsInFolder(itemIds: itemIds)
|
||||
disposable.set(impl.removeFromFolder(id: id, itemIds: itemIds))
|
||||
}
|
||||
return disposable
|
||||
}
|
||||
|
||||
public static func addFolderExternal(account: Account, peerId: PeerId, title: String) -> Int64 {
|
||||
let id = Int64.random(in: Int64.min ... Int64.max)
|
||||
|
||||
let _ = (account.postbox.transaction { transaction -> Void in
|
||||
let key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: 0)
|
||||
|
||||
|
||||
let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key))?.get(CachedPeerStoryListHead.self)
|
||||
var folders = cached?.folders ?? []
|
||||
folders.append(StoryListContextState.Folder(id: id, title: title))
|
||||
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: cached?.items ?? [], pinnedIds: cached?.pinnedIds ?? [], totalCount: cached?.totalCount ?? 0, folders: folders)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
public func reorderItemsInFolder(itemIds: [Int32]) -> Disposable {
|
||||
let disposable = MetaDisposable()
|
||||
self.impl.with { impl in
|
||||
disposable.set(impl.reorderItemsInFolder(itemIds: itemIds))
|
||||
}
|
||||
return disposable
|
||||
}
|
||||
|
||||
public static func addFolderExternal(account: Account, peerId: PeerId, title: String, completion: @escaping (Int64?) -> Void) -> Disposable {
|
||||
return (account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<Api.StoryAlbum?, NoError> in
|
||||
guard let inputPeer else {
|
||||
return .single(nil)
|
||||
}
|
||||
}).start()
|
||||
|
||||
return id
|
||||
return account.network.request(Api.functions.stories.createAlbum(
|
||||
peer: inputPeer, title: title, stories: []))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.StoryAlbum?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
}).start(next: { result in
|
||||
if let result {
|
||||
switch result {
|
||||
case let .storyAlbum(_, albumId, _, _, _):
|
||||
let _ = (account.postbox.transaction { transaction -> Void in
|
||||
let key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
key.setInt8(8, value: 0)
|
||||
|
||||
let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key))?.get(CachedPeerStoryListHead.self)
|
||||
var folders = cached?.folders ?? []
|
||||
folders.append(StoryListContextState.Folder(id: Int64(albumId), title: title))
|
||||
|
||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: cached?.items ?? [], pinnedIds: cached?.pinnedIds ?? [], totalCount: cached?.totalCount ?? 0, folders: folders)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||
}
|
||||
}).start(completed: {
|
||||
completion(Int64(albumId))
|
||||
})
|
||||
}
|
||||
} else {
|
||||
completion(nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public static func folderPreviews(peerId: EnginePeer.Id, account: Account) -> Signal<(peer: PeerReference, [(folder: StoryListContext.State.Folder, item: EngineStoryItem?)]), NoError> {
|
||||
|
|
@ -1789,7 +1989,8 @@ public final class PeerStoryListContext: StoryListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1971,7 +2172,8 @@ public final class SearchStoryListContext: StoryListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
storyItems.append(State.Item(
|
||||
id: StoryId(peerId: peer.peerId, id: mappedItem.id),
|
||||
|
|
@ -1988,7 +2190,7 @@ public final class SearchStoryListContext: StoryListContext {
|
|||
}
|
||||
}
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] storyItems, totalCount, nextOffset in
|
||||
guard let `self` = self else {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -2120,7 +2322,8 @@ public final class SearchStoryListContext: StoryListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, peers: peers) },
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
),
|
||||
peer: currentItem.peer
|
||||
)
|
||||
|
|
@ -2181,7 +2384,8 @@ public final class SearchStoryListContext: StoryListContext {
|
|||
isMy: item.storyItem.isMy,
|
||||
myReaction: reaction,
|
||||
forwardInfo: item.storyItem.forwardInfo,
|
||||
author: item.storyItem.author
|
||||
author: item.storyItem.author,
|
||||
folderIds: item.storyItem.folderIds
|
||||
),
|
||||
peer: item.peer
|
||||
)
|
||||
|
|
@ -2310,7 +2514,8 @@ public final class PeerExpiringStoryListContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
items.append(.item(mappedItem))
|
||||
}
|
||||
|
|
@ -2756,7 +2961,8 @@ public final class BotPreviewStoryListContext: StoryListContext {
|
|||
isMy: false,
|
||||
myReaction: nil,
|
||||
forwardInfo: nil,
|
||||
author: nil
|
||||
author: nil,
|
||||
folderIds: nil
|
||||
),
|
||||
peer: nil
|
||||
))
|
||||
|
|
@ -2805,7 +3011,8 @@ public final class BotPreviewStoryListContext: StoryListContext {
|
|||
isMy: false,
|
||||
myReaction: nil,
|
||||
forwardInfo: nil,
|
||||
author: nil
|
||||
author: nil,
|
||||
folderIds: nil
|
||||
),
|
||||
peer: nil
|
||||
))
|
||||
|
|
@ -2917,7 +3124,8 @@ public final class BotPreviewStoryListContext: StoryListContext {
|
|||
isMy: false,
|
||||
myReaction: nil,
|
||||
forwardInfo: nil,
|
||||
author: nil
|
||||
author: nil,
|
||||
folderIds: nil
|
||||
),
|
||||
peer: nil
|
||||
))
|
||||
|
|
@ -2994,7 +3202,8 @@ public final class BotPreviewStoryListContext: StoryListContext {
|
|||
isMy: false,
|
||||
myReaction: nil,
|
||||
forwardInfo: nil,
|
||||
author: nil
|
||||
author: nil,
|
||||
folderIds: nil
|
||||
),
|
||||
peer: nil
|
||||
))
|
||||
|
|
@ -3057,7 +3266,8 @@ public final class BotPreviewStoryListContext: StoryListContext {
|
|||
isMy: false,
|
||||
myReaction: nil,
|
||||
forwardInfo: nil,
|
||||
author: nil
|
||||
author: nil,
|
||||
folderIds: nil
|
||||
),
|
||||
peer: nil
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1353,7 +1353,8 @@ public extension TelegramEngine {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo,
|
||||
authorId: item.authorId
|
||||
authorId: item.authorId,
|
||||
folderIds: item.folderIds
|
||||
))
|
||||
if let entry = CodableEntry(updatedItem) {
|
||||
currentItems[i] = StoryItemsTableEntry(value: entry, id: updatedItem.id, expirationTimestamp: updatedItem.expirationTimestamp, isCloseFriends: updatedItem.isCloseFriends)
|
||||
|
|
@ -1367,8 +1368,8 @@ public extension TelegramEngine {
|
|||
}
|
||||
}
|
||||
|
||||
public func uploadStory(target: Stories.PendingTarget, media: EngineStoryInputMedia, mediaAreas: [MediaArea], text: String, entities: [MessageTextEntity], pin: Bool, privacy: EngineStoryPrivacy, isForwardingDisabled: Bool, period: Int, randomId: Int64, forwardInfo: Stories.PendingForwardInfo?, uploadInfo: StoryUploadInfo? = nil) -> Signal<Int32, NoError> {
|
||||
return _internal_uploadStory(account: self.account, target: target, media: media, mediaAreas: mediaAreas, text: text, entities: entities, pin: pin, privacy: privacy, isForwardingDisabled: isForwardingDisabled, period: period, randomId: randomId, forwardInfo: forwardInfo, uploadInfo: uploadInfo)
|
||||
public func uploadStory(target: Stories.PendingTarget, media: EngineStoryInputMedia, mediaAreas: [MediaArea], text: String, entities: [MessageTextEntity], pin: Bool, privacy: EngineStoryPrivacy, isForwardingDisabled: Bool, period: Int, randomId: Int64, forwardInfo: Stories.PendingForwardInfo?, folders: [Int64], uploadInfo: StoryUploadInfo? = nil) -> Signal<Int32, NoError> {
|
||||
return _internal_uploadStory(account: self.account, target: target, media: media, mediaAreas: mediaAreas, text: text, entities: entities, pin: pin, privacy: privacy, isForwardingDisabled: isForwardingDisabled, period: period, randomId: randomId, forwardInfo: forwardInfo, folders: folders, uploadInfo: uploadInfo)
|
||||
}
|
||||
|
||||
public func allStoriesUploadEvents() -> Signal<(Int32, Int32), NoError> {
|
||||
|
|
|
|||
|
|
@ -1456,6 +1456,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||
break
|
||||
case .shareStory:
|
||||
break
|
||||
case .storyFolder:
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ public struct MediaEditorResultPrivacy: Codable, Equatable {
|
|||
case timeout
|
||||
case disableForwarding
|
||||
case archive
|
||||
case folderIds
|
||||
}
|
||||
|
||||
public let sendAsPeerId: EnginePeer.Id?
|
||||
|
|
@ -22,19 +23,22 @@ public struct MediaEditorResultPrivacy: Codable, Equatable {
|
|||
public let timeout: Int
|
||||
public let isForwardingDisabled: Bool
|
||||
public let pin: Bool
|
||||
public let folderIds: [Int64]
|
||||
|
||||
public init(
|
||||
sendAsPeerId: EnginePeer.Id?,
|
||||
privacy: EngineStoryPrivacy,
|
||||
timeout: Int,
|
||||
isForwardingDisabled: Bool,
|
||||
pin: Bool
|
||||
pin: Bool,
|
||||
folderIds: [Int64]
|
||||
) {
|
||||
self.sendAsPeerId = sendAsPeerId
|
||||
self.privacy = privacy
|
||||
self.timeout = timeout
|
||||
self.isForwardingDisabled = isForwardingDisabled
|
||||
self.pin = pin
|
||||
self.folderIds = folderIds
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
|
|
@ -45,6 +49,7 @@ public struct MediaEditorResultPrivacy: Codable, Equatable {
|
|||
self.timeout = Int(try container.decode(Int32.self, forKey: .timeout))
|
||||
self.isForwardingDisabled = try container.decodeIfPresent(Bool.self, forKey: .disableForwarding) ?? false
|
||||
self.pin = try container.decode(Bool.self, forKey: .archive)
|
||||
self.folderIds = try container.decodeIfPresent([Int64].self, forKey: .folderIds) ?? []
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
|
|
@ -55,6 +60,7 @@ public struct MediaEditorResultPrivacy: Codable, Equatable {
|
|||
try container.encode(Int32(self.timeout), forKey: .timeout)
|
||||
try container.encode(self.isForwardingDisabled, forKey: .disableForwarding)
|
||||
try container.encode(self.pin, forKey: .archive)
|
||||
try container.encode(self.folderIds, forKey: .folderIds)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2915,7 +2915,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []),
|
||||
timeout: 86400,
|
||||
isForwardingDisabled: false,
|
||||
pin: true
|
||||
pin: true,
|
||||
folderIds: []
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -6641,7 +6642,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
self.mediaAreas = []
|
||||
self.caption = NSAttributedString()
|
||||
self.coverTimestamp = nil
|
||||
self.options = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false)
|
||||
self.options = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false, folderIds: [])
|
||||
self.stickers = []
|
||||
self.randomId = 0
|
||||
}
|
||||
|
|
@ -6651,7 +6652,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
mediaAreas: [MediaArea] = [],
|
||||
caption: NSAttributedString = NSAttributedString(),
|
||||
coverTimestamp: Double? = nil,
|
||||
options: MediaEditorResultPrivacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false),
|
||||
options: MediaEditorResultPrivacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false, folderIds: []),
|
||||
stickers: [TelegramMediaFile] = [],
|
||||
randomId: Int64 = 0
|
||||
) {
|
||||
|
|
@ -6760,7 +6761,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
privacy: initialPrivacy,
|
||||
timeout: 86400,
|
||||
isForwardingDisabled: false,
|
||||
pin: false
|
||||
pin: false,
|
||||
folderIds: []
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -6771,9 +6773,9 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
).start(next: { [weak self] state, peer in
|
||||
if let self, var privacy = state?.privacy {
|
||||
if case let .user(user) = peer, !user.isPremium && privacy.timeout != 86400 {
|
||||
privacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: privacy.privacy, timeout: 86400, isForwardingDisabled: privacy.isForwardingDisabled, pin: privacy.pin)
|
||||
privacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: privacy.privacy, timeout: 86400, isForwardingDisabled: privacy.isForwardingDisabled, pin: privacy.pin, folderIds: privacy.folderIds)
|
||||
} else {
|
||||
privacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: privacy.privacy, timeout: privacy.timeout, isForwardingDisabled: privacy.isForwardingDisabled, pin: privacy.pin)
|
||||
privacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: privacy.privacy, timeout: privacy.timeout, isForwardingDisabled: privacy.isForwardingDisabled, pin: privacy.pin, folderIds: privacy.folderIds)
|
||||
}
|
||||
self.state.privacy = privacy
|
||||
}
|
||||
|
|
@ -6980,7 +6982,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
mentions: mentions,
|
||||
coverImage: coverImage,
|
||||
stateContext: stateContext,
|
||||
completion: { [weak self] sendAsPeerId, privacy, allowScreenshots, pin, _, completed in
|
||||
completion: { [weak self] sendAsPeerId, privacy, allowScreenshots, pin, _, folders, completed in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -6989,13 +6991,14 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
privacy: privacy,
|
||||
timeout: timeout,
|
||||
isForwardingDisabled: !allowScreenshots,
|
||||
pin: pin
|
||||
pin: pin,
|
||||
folderIds: folders
|
||||
)
|
||||
if completed {
|
||||
completion()
|
||||
}
|
||||
},
|
||||
editCategory: { [weak self] privacy, allowScreenshots, pin in
|
||||
editCategory: { [weak self] privacy, allowScreenshots, pin, folders in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -7008,11 +7011,12 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
privacy: privacy,
|
||||
timeout: timeout,
|
||||
isForwardingDisabled: !allowScreenshots,
|
||||
pin: pin
|
||||
pin: pin,
|
||||
folderIds: folders
|
||||
), completion: completion)
|
||||
})
|
||||
},
|
||||
editBlockedPeers: { [weak self] privacy, allowScreenshots, pin in
|
||||
editBlockedPeers: { [weak self] privacy, allowScreenshots, pin, folders in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -7025,7 +7029,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
privacy: privacy,
|
||||
timeout: timeout,
|
||||
isForwardingDisabled: !allowScreenshots,
|
||||
pin: pin
|
||||
pin: pin,
|
||||
folderIds: folders
|
||||
), completion: completion)
|
||||
})
|
||||
},
|
||||
|
|
@ -7078,7 +7083,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
allowScreenshots: !isForwardingDisabled,
|
||||
pin: pin,
|
||||
stateContext: stateContext,
|
||||
completion: { [weak self] _, result, isForwardingDisabled, pin, peers, completed in
|
||||
completion: { [weak self] _, result, isForwardingDisabled, pin, peers, folders, completed in
|
||||
guard let self, completed else {
|
||||
return
|
||||
}
|
||||
|
|
@ -7093,8 +7098,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
completion(result)
|
||||
}
|
||||
},
|
||||
editCategory: { _, _, _ in },
|
||||
editBlockedPeers: { _, _, _ in }
|
||||
editCategory: { _, _, _, _ in },
|
||||
editBlockedPeers: { _, _, _, _ in }
|
||||
)
|
||||
controller.customModalStyleOverlayTransitionFactorUpdated = { [weak self, weak controller] transition in
|
||||
if let self, let controller {
|
||||
|
|
@ -7175,7 +7180,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
privacy: self.state.privacy.privacy,
|
||||
timeout: timeout ?? 86400,
|
||||
isForwardingDisabled: self.state.privacy.isForwardingDisabled,
|
||||
pin: self.state.privacy.pin
|
||||
pin: self.state.privacy.pin,
|
||||
folderIds: self.state.privacy.folderIds
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -7672,7 +7678,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
mediaAreas: [],
|
||||
caption: NSAttributedString(),
|
||||
coverTimestamp: nil,
|
||||
options: MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false),
|
||||
options: MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false, folderIds: []),
|
||||
stickers: [],
|
||||
randomId: 0
|
||||
)], { [weak self] finished in
|
||||
|
|
|
|||
|
|
@ -527,6 +527,7 @@ private final class PeerInfoPendingPane {
|
|||
chatLocation: ChatLocation,
|
||||
chatLocationContextHolder: Atomic<ChatLocationContextHolder?>,
|
||||
sharedMediaFromForumTopic: (EnginePeer.Id, Int64)?,
|
||||
initialStoryFolderId: Int64?,
|
||||
key: PeerInfoPaneKey,
|
||||
hasBecomeReady: @escaping (PeerInfoPaneKey) -> Void,
|
||||
parentController: ViewController?,
|
||||
|
|
@ -609,7 +610,7 @@ private final class PeerInfoPendingPane {
|
|||
listContext = data.storyListContext
|
||||
}
|
||||
|
||||
let visualPaneNode = PeerInfoStoryPaneNode(context: context, scope: scope, captureProtected: captureProtected, isProfileEmbedded: true, canManageStories: canManage, navigationController: chatControllerInteraction.navigationController, listContext: listContext)
|
||||
let visualPaneNode = PeerInfoStoryPaneNode(context: context, scope: scope, captureProtected: captureProtected, isProfileEmbedded: true, canManageStories: canManage, navigationController: chatControllerInteraction.navigationController, listContext: listContext, initialStoryFolderId: initialStoryFolderId)
|
||||
paneNode = visualPaneNode
|
||||
visualPaneNode.openCurrentDate = {
|
||||
openMediaCalendar()
|
||||
|
|
@ -728,6 +729,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
|||
private var currentPanes: [PeerInfoPaneKey: PeerInfoPaneWrapper] = [:]
|
||||
private var pendingPanes: [PeerInfoPaneKey: PeerInfoPendingPane] = [:]
|
||||
private var shouldFadeIn = false
|
||||
private var initialStoryFolderId: Int64?
|
||||
|
||||
private var transitionFraction: CGFloat = 0.0
|
||||
|
||||
|
|
@ -753,7 +755,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
|||
|
||||
private let initialPaneKey: PeerInfoPaneKey?
|
||||
|
||||
init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: PeerId, chatLocation: ChatLocation, sharedMediaFromForumTopic: (EnginePeer.Id, Int64)?, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, isMediaOnly: Bool, initialPaneKey: PeerInfoPaneKey?) {
|
||||
init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: PeerId, chatLocation: ChatLocation, sharedMediaFromForumTopic: (EnginePeer.Id, Int64)?, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, isMediaOnly: Bool, initialPaneKey: PeerInfoPaneKey?, initialStoryFolderId: Int64?) {
|
||||
self.context = context
|
||||
self.updatedPresentationData = updatedPresentationData
|
||||
self.peerId = peerId
|
||||
|
|
@ -762,6 +764,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
|||
self.sharedMediaFromForumTopic = sharedMediaFromForumTopic
|
||||
self.isMediaOnly = isMediaOnly
|
||||
self.initialPaneKey = initialPaneKey
|
||||
self.initialStoryFolderId = initialStoryFolderId
|
||||
|
||||
self.additionalBackgroundNode = ASDisplayNode()
|
||||
|
||||
|
|
@ -1088,7 +1091,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
|||
}
|
||||
}
|
||||
}
|
||||
if let pendingSwitchToPaneKey = self.pendingSwitchToPaneKey {
|
||||
if let pendingSwitchToPaneKey = self.pendingSwitchToPaneKey, availablePanes.contains(pendingSwitchToPaneKey) {
|
||||
if self.currentPanes[pendingSwitchToPaneKey] == nil && self.pendingPanes[pendingSwitchToPaneKey] == nil {
|
||||
if !requiredPendingKeys.contains(pendingSwitchToPaneKey) {
|
||||
requiredPendingKeys.append(pendingSwitchToPaneKey)
|
||||
|
|
@ -1099,6 +1102,13 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
|||
for key in requiredPendingKeys {
|
||||
if self.pendingPanes[key] == nil, let data {
|
||||
var leftScope = false
|
||||
var initialStoryFolderId: Int64?
|
||||
if case .stories = key {
|
||||
if let initialStoryFolderIdValue = self.initialStoryFolderId {
|
||||
self.initialStoryFolderId = nil
|
||||
initialStoryFolderId = initialStoryFolderIdValue
|
||||
}
|
||||
}
|
||||
let pane = PeerInfoPendingPane(
|
||||
context: self.context,
|
||||
updatedPresentationData: self.updatedPresentationData,
|
||||
|
|
@ -1117,6 +1127,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
|||
chatLocation: self.chatLocation,
|
||||
chatLocationContextHolder: self.chatLocationContextHolder,
|
||||
sharedMediaFromForumTopic: self.sharedMediaFromForumTopic,
|
||||
initialStoryFolderId: initialStoryFolderId,
|
||||
key: key,
|
||||
hasBecomeReady: { [weak self] key in
|
||||
let apply: () -> Void = {
|
||||
|
|
@ -1352,7 +1363,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
|||
|
||||
var removeKeys: [PeerInfoPaneKey] = []
|
||||
for (key, paneNode) in self.pendingPanes {
|
||||
if !availablePanes.contains(key) {
|
||||
if !availablePanes.contains(key) && self.pendingSwitchToPaneKey != key {
|
||||
removeKeys.append(key)
|
||||
paneNode.pane.node.removeFromSupernode()
|
||||
}
|
||||
|
|
@ -1363,7 +1374,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
|||
removeKeys.removeAll()
|
||||
|
||||
for (key, paneNode) in self.currentPanes {
|
||||
if !availablePanes.contains(key) {
|
||||
if !availablePanes.contains(key) && self.pendingSwitchToPaneKey != key {
|
||||
removeKeys.append(key)
|
||||
paneNode.node.removeFromSupernode()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2907,6 +2907,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
private let callMessages: [Message]
|
||||
private let chatLocation: ChatLocation
|
||||
private let chatLocationContextHolder: Atomic<ChatLocationContextHolder?>
|
||||
private let switchToStoryFolder: Int64?
|
||||
private let sharedMediaFromForumTopic: (EnginePeer.Id, Int64)?
|
||||
|
||||
let isSettings: Bool
|
||||
|
|
@ -3031,7 +3032,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
}
|
||||
private var didSetReady = false
|
||||
|
||||
init(controller: PeerInfoScreenImpl, context: AccountContext, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool, isMyProfile: Bool, hintGroupInCommon: PeerId?, requestsContext: PeerInvitationImportersContext?, profileGiftsContext: ProfileGiftsContext?, starsContext: StarsContext?, tonContext: StarsContext?, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, initialPaneKey: PeerInfoPaneKey?, sharedMediaFromForumTopic: (EnginePeer.Id, Int64)?) {
|
||||
init(controller: PeerInfoScreenImpl, context: AccountContext, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool, isMyProfile: Bool, hintGroupInCommon: PeerId?, requestsContext: PeerInvitationImportersContext?, profileGiftsContext: ProfileGiftsContext?, starsContext: StarsContext?, tonContext: StarsContext?, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, switchToStoryFolder: Int64?, initialPaneKey: PeerInfoPaneKey?, sharedMediaFromForumTopic: (EnginePeer.Id, Int64)?) {
|
||||
self.controller = controller
|
||||
self.context = context
|
||||
self.peerId = peerId
|
||||
|
|
@ -3047,6 +3048,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
self.chatLocationContextHolder = chatLocationContextHolder
|
||||
self.isMediaOnly = context.account.peerId == peerId && !isSettings && !isMyProfile
|
||||
self.initialExpandPanes = initialPaneKey != nil
|
||||
self.switchToStoryFolder = switchToStoryFolder
|
||||
self.sharedMediaFromForumTopic = sharedMediaFromForumTopic
|
||||
|
||||
self.scrollNode = ASScrollNode()
|
||||
|
|
@ -3058,7 +3060,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
forumTopicThreadId = message.threadId
|
||||
}
|
||||
self.headerNode = PeerInfoHeaderNode(context: context, controller: controller, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, isMediaOnly: self.isMediaOnly, isSettings: isSettings, isMyProfile: isMyProfile, forumTopicThreadId: forumTopicThreadId, chatLocation: self.chatLocation)
|
||||
self.paneContainerNode = PeerInfoPaneContainerNode(context: context, updatedPresentationData: controller.updatedPresentationData, peerId: peerId, chatLocation: chatLocation, sharedMediaFromForumTopic: sharedMediaFromForumTopic, chatLocationContextHolder: chatLocationContextHolder, isMediaOnly: self.isMediaOnly, initialPaneKey: initialPaneKey)
|
||||
self.paneContainerNode = PeerInfoPaneContainerNode(context: context, updatedPresentationData: controller.updatedPresentationData, peerId: peerId, chatLocation: chatLocation, sharedMediaFromForumTopic: sharedMediaFromForumTopic, chatLocationContextHolder: chatLocationContextHolder, isMediaOnly: self.isMediaOnly, initialPaneKey: initialPaneKey, initialStoryFolderId: switchToStoryFolder)
|
||||
|
||||
super.init()
|
||||
|
||||
|
|
@ -5393,7 +5395,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .spring)
|
||||
|
||||
self.headerNode.updateIsAvatarExpanded(false, transition: transition)
|
||||
self.updateNavigationExpansionPresentation(isExpanded: false, animated: true)
|
||||
self.updateNavigationExpansionPresentation(isExpanded: false, animated: animated)
|
||||
|
||||
if let (layout, navigationHeight) = self.validLayout {
|
||||
self.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: transition, additive: true)
|
||||
|
|
@ -5404,7 +5406,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
let contentOffset = self.scrollNode.view.contentOffset
|
||||
let paneAreaExpansionFinalPoint: CGFloat = self.paneContainerNode.frame.minY - navigationHeight
|
||||
if contentOffset.y < paneAreaExpansionFinalPoint - CGFloat.ulpOfOne {
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring)
|
||||
let transition: ContainedViewLayoutTransition = animated ? .animated(duration: 0.4, curve: .spring) : .immediate
|
||||
|
||||
self.ignoreScrolling = true
|
||||
transition.updateBounds(node: self.scrollNode, bounds: CGRect(origin: CGPoint(x: 0.0, y: paneAreaExpansionFinalPoint), size: self.scrollNode.bounds.size))
|
||||
|
|
@ -11712,7 +11714,23 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
}
|
||||
})))
|
||||
|
||||
/*if pane.canReorder() {
|
||||
if let _ = pane.currentStoryFolder {
|
||||
items.append(.action(ContextMenuActionItem(text: "Share", icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak pane] _, a in
|
||||
if ignoreNextActions {
|
||||
return
|
||||
}
|
||||
ignoreNextActions = true
|
||||
a(.default)
|
||||
|
||||
if let pane {
|
||||
pane.shareCurrentFolder()
|
||||
}
|
||||
})))
|
||||
}
|
||||
|
||||
if pane.canReorder() {
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.BotPreviews_MenuReorder, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ReorderItems"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak pane] _, a in
|
||||
|
|
@ -11744,7 +11762,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
pane.presentDeleteCurrentStoryFolder()
|
||||
}
|
||||
})))
|
||||
}*/
|
||||
}
|
||||
|
||||
if let language = pane.currentBotPreviewLanguage {
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.BotPreviews_MenuDeleteLanguage(language.name).string, textColor: .destructive, icon: { theme in
|
||||
|
|
@ -13084,6 +13102,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||
private let switchToRecommendedChannels: Bool
|
||||
private let switchToGifts: Bool
|
||||
private let switchToGroupsInCommon: Bool
|
||||
private let switchToStoryFolder: Int64?
|
||||
private let sharedMediaFromForumTopic: (EnginePeer.Id, Int64)?
|
||||
let chatLocation: ChatLocation
|
||||
private let chatLocationContextHolder = Atomic<ChatLocationContextHolder?>(value: nil)
|
||||
|
|
@ -13159,7 +13178,8 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||
sharedMediaFromForumTopic: (EnginePeer.Id, Int64)? = nil,
|
||||
switchToRecommendedChannels: Bool = false,
|
||||
switchToGifts: Bool = false,
|
||||
switchToGroupsInCommon: Bool = false
|
||||
switchToGroupsInCommon: Bool = false,
|
||||
switchToStoryFolder: Int64? = nil
|
||||
) {
|
||||
self.context = context
|
||||
self.updatedPresentationData = updatedPresentationData
|
||||
|
|
@ -13177,6 +13197,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||
self.switchToRecommendedChannels = switchToRecommendedChannels
|
||||
self.switchToGifts = switchToGifts
|
||||
self.switchToGroupsInCommon = switchToGroupsInCommon
|
||||
self.switchToStoryFolder = switchToStoryFolder
|
||||
self.sharedMediaFromForumTopic = sharedMediaFromForumTopic
|
||||
|
||||
if let forumTopicThread = forumTopicThread {
|
||||
|
|
@ -13542,8 +13563,10 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||
initialPaneKey = .gifts
|
||||
} else if self.switchToGroupsInCommon {
|
||||
initialPaneKey = .groupsInCommon
|
||||
} else if self.switchToStoryFolder != nil {
|
||||
initialPaneKey = .stories
|
||||
}
|
||||
self.displayNode = PeerInfoScreenNode(controller: self, context: self.context, peerId: self.peerId, avatarInitiallyExpanded: self.avatarInitiallyExpanded, isOpenedFromChat: self.isOpenedFromChat, nearbyPeerDistance: self.nearbyPeerDistance, reactionSourceMessageId: self.reactionSourceMessageId, callMessages: self.callMessages, isSettings: self.isSettings, isMyProfile: self.isMyProfile, hintGroupInCommon: self.hintGroupInCommon, requestsContext: self.requestsContext, profileGiftsContext: self.profileGiftsContext, starsContext: self.starsContext, tonContext: self.tonContext, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, initialPaneKey: initialPaneKey, sharedMediaFromForumTopic: self.sharedMediaFromForumTopic)
|
||||
self.displayNode = PeerInfoScreenNode(controller: self, context: self.context, peerId: self.peerId, avatarInitiallyExpanded: self.avatarInitiallyExpanded, isOpenedFromChat: self.isOpenedFromChat, nearbyPeerDistance: self.nearbyPeerDistance, reactionSourceMessageId: self.reactionSourceMessageId, callMessages: self.callMessages, isSettings: self.isSettings, isMyProfile: self.isMyProfile, hintGroupInCommon: self.hintGroupInCommon, requestsContext: self.requestsContext, profileGiftsContext: self.profileGiftsContext, starsContext: self.starsContext, tonContext: self.tonContext, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, switchToStoryFolder: self.switchToStoryFolder, initialPaneKey: initialPaneKey, sharedMediaFromForumTopic: self.sharedMediaFromForumTopic)
|
||||
self.controllerNode.accountsAndPeers.set(self.accountsAndPeers.get() |> map { $0.1 })
|
||||
self.controllerNode.activeSessionsContextAndCount.set(self.activeSessionsContextAndCount.get())
|
||||
self.cachedDataPromise.set(self.controllerNode.cachedDataPromise.get())
|
||||
|
|
|
|||
|
|
@ -488,7 +488,8 @@ final class PeerInfoStoryGridScreenComponent: Component {
|
|||
}
|
||||
return self.environment?.controller()?.navigationController as? NavigationController
|
||||
},
|
||||
listContext: nil
|
||||
listContext: nil,
|
||||
initialStoryFolderId: nil
|
||||
)
|
||||
paneNode.isEmptyUpdated = { [weak self] _ in
|
||||
guard let self else {
|
||||
|
|
|
|||
|
|
@ -117,7 +117,8 @@ final class StorySearchGridScreenComponent: Component {
|
|||
}
|
||||
return self.environment?.controller()?.navigationController as? NavigationController
|
||||
},
|
||||
listContext: component.listContext
|
||||
listContext: component.listContext,
|
||||
initialStoryFolderId: nil
|
||||
)
|
||||
paneNode.parentController = environment.controller()
|
||||
paneNode.isEmptyUpdated = { [weak self] _ in
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -44,9 +44,9 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
let categoryItems: [CategoryItem]
|
||||
let optionItems: [OptionItem]
|
||||
let coverItem: CoverItem?
|
||||
let completion: (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], Bool) -> Void
|
||||
let editCategory: (EngineStoryPrivacy, Bool, Bool) -> Void
|
||||
let editBlockedPeers: (EngineStoryPrivacy, Bool, Bool) -> Void
|
||||
let completion: (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], [Int64], Bool) -> Void
|
||||
let editCategory: (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void
|
||||
let editBlockedPeers: (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void
|
||||
let editCover: () -> Void
|
||||
let peerCompletion: (EnginePeer.Id) -> Void
|
||||
|
||||
|
|
@ -62,9 +62,9 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
categoryItems: [CategoryItem],
|
||||
optionItems: [OptionItem],
|
||||
coverItem: CoverItem?,
|
||||
completion: @escaping (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], Bool) -> Void,
|
||||
editCategory: @escaping (EngineStoryPrivacy, Bool, Bool) -> Void,
|
||||
editBlockedPeers: @escaping (EngineStoryPrivacy, Bool, Bool) -> Void,
|
||||
completion: @escaping (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], [Int64], Bool) -> Void,
|
||||
editCategory: @escaping (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void,
|
||||
editBlockedPeers: @escaping (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void,
|
||||
editCover: @escaping () -> Void,
|
||||
peerCompletion: @escaping (EnginePeer.Id) -> Void
|
||||
) {
|
||||
|
|
@ -833,9 +833,9 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
context: component.context,
|
||||
initialPrivacy: EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: []),
|
||||
stateContext: stateContext,
|
||||
completion: { _, _, _, _, _, _ in },
|
||||
editCategory: { _, _, _ in },
|
||||
editBlockedPeers: { _, _, _ in },
|
||||
completion: { _, _, _, _, _, _, _ in },
|
||||
editCategory: { _, _, _, _ in },
|
||||
editBlockedPeers: { _, _, _, _ in },
|
||||
peerCompletion: { [weak self] peerId in
|
||||
guard let self else {
|
||||
return
|
||||
|
|
@ -896,7 +896,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: "New Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Folder"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { [weak self] c, f in
|
||||
items.append(.action(ContextMenuActionItem(text: "New Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddFolder"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { [weak self] c, f in
|
||||
guard let self else {
|
||||
f(.default)
|
||||
return
|
||||
|
|
@ -1005,12 +1005,17 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
return
|
||||
}
|
||||
if let value, !value.isEmpty {
|
||||
let id = PeerStoryListContext.addFolderExternal(account: component.context.account, peerId: component.context.account.peerId, title: value)
|
||||
self.shareToFolders.append(StoryListContext.State.Folder(
|
||||
id: id,
|
||||
title: value
|
||||
))
|
||||
self.state?.updated(transition: .immediate)
|
||||
let _ = PeerStoryListContext.addFolderExternal(account: component.context.account, peerId: component.context.account.peerId, title: value, completion: { [weak self] id in
|
||||
guard let self, let id else {
|
||||
return
|
||||
}
|
||||
|
||||
self.shareToFolders.append(StoryListContext.State.Folder(
|
||||
id: id,
|
||||
title: value
|
||||
))
|
||||
self.state?.updated(transition: .immediate)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -1416,7 +1421,8 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
component.editCategory(
|
||||
EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: []),
|
||||
self.selectedOptions.contains(.screenshot),
|
||||
self.selectedOptions.contains(.pin)
|
||||
self.selectedOptions.contains(.pin),
|
||||
self.shareToFolders.map(\.id)
|
||||
)
|
||||
controller.dismissAllTooltips()
|
||||
controller.dismiss()
|
||||
|
|
@ -1424,7 +1430,8 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
component.editCategory(
|
||||
EngineStoryPrivacy(base: .closeFriends, additionallyIncludePeers: []),
|
||||
self.selectedOptions.contains(.screenshot),
|
||||
self.selectedOptions.contains(.pin)
|
||||
self.selectedOptions.contains(.pin),
|
||||
self.shareToFolders.map(\.id)
|
||||
)
|
||||
controller.dismissAllTooltips()
|
||||
controller.dismiss()
|
||||
|
|
@ -1452,7 +1459,8 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
component.editCategory(
|
||||
EngineStoryPrivacy(base: base, additionallyIncludePeers: selectedPeers),
|
||||
self.selectedOptions.contains(.screenshot),
|
||||
self.selectedOptions.contains(.pin)
|
||||
self.selectedOptions.contains(.pin),
|
||||
self.shareToFolders.map(\.id)
|
||||
)
|
||||
controller.dismissAllTooltips()
|
||||
controller.dismiss()
|
||||
|
|
@ -1540,7 +1548,8 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
component.editBlockedPeers(
|
||||
EngineStoryPrivacy(base: base, additionallyIncludePeers: self.selectedPeers),
|
||||
self.selectedOptions.contains(.screenshot),
|
||||
self.selectedOptions.contains(.pin)
|
||||
self.selectedOptions.contains(.pin),
|
||||
self.shareToFolders.map(\.id)
|
||||
)
|
||||
controller.dismissAllTooltips()
|
||||
controller.dismiss()
|
||||
|
|
@ -2262,6 +2271,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
self.selectedOptions.contains(.screenshot),
|
||||
self.selectedOptions.contains(.pin),
|
||||
self.component?.stateContext.stateValue?.peers.filter { self.selectedPeers.contains($0.id) } ?? [],
|
||||
self.shareToFolders.map(\.id),
|
||||
false
|
||||
)
|
||||
controller.requestDismiss()
|
||||
|
|
@ -3014,6 +3024,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
self.selectedOptions.contains(.screenshot),
|
||||
self.selectedOptions.contains(.pin),
|
||||
peers.values.compactMap { $0 },
|
||||
self.shareToFolders.map(\.id),
|
||||
true
|
||||
)
|
||||
|
||||
|
|
@ -3265,9 +3276,9 @@ public class ShareWithPeersScreen: ViewControllerComponentContainer {
|
|||
mentions: [String] = [],
|
||||
coverImage: UIImage? = nil,
|
||||
stateContext: StateContext,
|
||||
completion: @escaping (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], Bool) -> Void,
|
||||
editCategory: @escaping (EngineStoryPrivacy, Bool, Bool) -> Void = { _, _, _ in },
|
||||
editBlockedPeers: @escaping (EngineStoryPrivacy, Bool, Bool) -> Void = { _, _, _ in },
|
||||
completion: @escaping (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], [Int64], Bool) -> Void,
|
||||
editCategory: @escaping (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void = { _, _, _, _ in },
|
||||
editBlockedPeers: @escaping (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void = { _, _, _, _ in },
|
||||
editCover: @escaping () -> Void = { },
|
||||
peerCompletion: @escaping (EnginePeer.Id) -> Void = { _ in }
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -318,7 +318,8 @@ public final class StoryContentContextImpl: StoryContentContext {
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: forwardInfo,
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
}
|
||||
var totalCount = peerStoryItemsView.items.count
|
||||
|
|
@ -355,7 +356,8 @@ public final class StoryContentContextImpl: StoryContentContext {
|
|||
isMy: true,
|
||||
myReaction: nil,
|
||||
forwardInfo: pendingForwardsInfo[item.randomId],
|
||||
author: nil
|
||||
author: nil,
|
||||
folderIds: item.folders
|
||||
))
|
||||
totalCount += 1
|
||||
}
|
||||
|
|
@ -1354,7 +1356,8 @@ public final class SingleStoryContentContextImpl: StoryContentContext {
|
|||
isMy: itemValue.isMy,
|
||||
myReaction: itemValue.myReaction,
|
||||
forwardInfo: forwardInfo,
|
||||
author: itemValue.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
||||
author: itemValue.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) },
|
||||
folderIds: itemValue.folderIds
|
||||
)
|
||||
|
||||
let mainItem = StoryContentItem(
|
||||
|
|
@ -2292,7 +2295,8 @@ private func getCachedStory(storyId: StoryId, transaction: Transaction) -> Engin
|
|||
isMy: item.isMy,
|
||||
myReaction: item.myReaction,
|
||||
forwardInfo: item.forwardInfo.flatMap { EngineStoryItem.ForwardInfo($0, transaction: transaction) },
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) }
|
||||
author: item.authorId.flatMap { transaction.getPeer($0).flatMap(EnginePeer.init) },
|
||||
folderIds: item.folderIds
|
||||
)
|
||||
} else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -1695,13 +1695,13 @@ private final class StoryContainerScreenComponent: Component {
|
|||
|
||||
if let content = component.content as? PeerStoryListContentContextImpl {
|
||||
if let listSource = content.listContext as? PeerStoryListContext {
|
||||
listSource.addFolder(title: title, completion: { [weak listSource] id in
|
||||
let _ = listSource.addFolder(title: title, items: [], completion: { [weak listSource] id in
|
||||
Queue.mainQueue().async {
|
||||
guard let listSource else {
|
||||
guard let listSource, let id else {
|
||||
return
|
||||
}
|
||||
if !items.isEmpty {
|
||||
listSource.addToFolder(id: id, items: items)
|
||||
let _ = listSource.addToFolder(id: id, items: items)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -1717,7 +1717,7 @@ private final class StoryContainerScreenComponent: Component {
|
|||
}
|
||||
if let content = component.content as? PeerStoryListContentContextImpl {
|
||||
if let listSource = content.listContext as? PeerStoryListContext {
|
||||
listSource.addToFolder(id: folderId, items: [slice.item.storyItem])
|
||||
let _ = listSource.addToFolder(id: folderId, items: [slice.item.storyItem])
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5090,7 +5090,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||
context: context,
|
||||
initialPrivacy: privacy,
|
||||
stateContext: stateContext,
|
||||
completion: { [weak self] _, privacy, _, _, _, completed in
|
||||
completion: { [weak self] _, privacy, _, _, _, _, completed in
|
||||
guard let self, let component = self.component, completed else {
|
||||
return
|
||||
}
|
||||
|
|
@ -5107,7 +5107,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||
self.rewindCurrentItem()
|
||||
self.updateIsProgressPaused()
|
||||
},
|
||||
editCategory: { [weak self] privacy, _, _ in
|
||||
editCategory: { [weak self] privacy, _, _, _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -5118,7 +5118,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||
self.openItemPrivacySettings(updatedPrivacy: privacy)
|
||||
})
|
||||
},
|
||||
editBlockedPeers: { [weak self] privacy, _, _ in
|
||||
editBlockedPeers: { [weak self] privacy, _, _, _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -5171,7 +5171,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||
context: context,
|
||||
initialPrivacy: privacy,
|
||||
stateContext: stateContext,
|
||||
completion: { [weak self] _, result, _, _, peers, completed in
|
||||
completion: { [weak self] _, result, _, _, peers, _, completed in
|
||||
guard completed else {
|
||||
return
|
||||
}
|
||||
|
|
@ -5188,8 +5188,8 @@ public final class StoryItemSetContainerComponent: Component {
|
|||
completion(result)
|
||||
}
|
||||
},
|
||||
editCategory: { _, _, _ in },
|
||||
editBlockedPeers: { _, _, _ in }
|
||||
editCategory: { _, _, _, _ in },
|
||||
editBlockedPeers: { _, _, _, _ in }
|
||||
)
|
||||
controller.dismissed = { [weak self] in
|
||||
if let self {
|
||||
|
|
@ -6110,7 +6110,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||
var items: [ContextMenuItem] = []
|
||||
|
||||
//TODO:localize
|
||||
items.append(.action(ContextMenuActionItem(text: "Add to Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Folder"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in
|
||||
items.append(.action(ContextMenuActionItem(text: "Add to Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddToFolder"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in
|
||||
guard let self, let c else {
|
||||
f(.default)
|
||||
return
|
||||
|
|
@ -6131,7 +6131,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||
})))
|
||||
items.append(.separator)
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: "New Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Folder"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { [weak self] c, f in
|
||||
items.append(.action(ContextMenuActionItem(text: "New Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddFolder"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { [weak self] c, f in
|
||||
guard let self else {
|
||||
f(.default)
|
||||
return
|
||||
|
|
|
|||
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddFolder.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddFolder.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "addfolder_24.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddFolder.imageset/addfolder_24.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddFolder.imageset/addfolder_24.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddToFolder.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddToFolder.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "folder1_24.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddToFolder.imageset/folder1_24.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddToFolder.imageset/folder1_24.pdf
vendored
Normal file
Binary file not shown.
|
|
@ -1498,5 +1498,26 @@ func openResolvedUrlImpl(
|
|||
} else {
|
||||
present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.BusinessLink_ErrorExpired, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||
}
|
||||
case let .storyFolder(peerId, id):
|
||||
Task { @MainActor [weak navigationController] in
|
||||
guard let peer = await context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||
).get() else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let controller = context.sharedContext.makePeerInfoController(
|
||||
context: context,
|
||||
updatedPresentationData: updatedPresentationData,
|
||||
peer: peer._asPeer(),
|
||||
mode: .storyAlbum(id: id),
|
||||
avatarInitiallyExpanded: false,
|
||||
fromChat: false,
|
||||
requestsContext: nil
|
||||
) else {
|
||||
return
|
||||
}
|
||||
navigationController?.pushViewController(controller)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3964,6 +3964,7 @@ private func peerInfoControllerImpl(context: AccountContext, updatedPresentation
|
|||
var isMyProfile = false
|
||||
var switchToGifts = false
|
||||
var switchToGroupsInCommon = false
|
||||
var switchToStoryFolder: Int64?
|
||||
|
||||
switch mode {
|
||||
case let .nearbyPeer(distance):
|
||||
|
|
@ -3989,10 +3990,12 @@ private func peerInfoControllerImpl(context: AccountContext, updatedPresentation
|
|||
switchToGroupsInCommon = true
|
||||
case let .monoforum(peerId):
|
||||
sharedMediaFromForumTopic = (peerId, peer.id.toInt64())
|
||||
case let .storyAlbum(id):
|
||||
switchToStoryFolder = id
|
||||
default:
|
||||
break
|
||||
}
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nearbyPeerDistance, reactionSourceMessageId: reactionSourceMessageId, callMessages: callMessages, isMyProfile: isMyProfile, hintGroupInCommon: hintGroupInCommon, forumTopicThread: forumTopicThread, sharedMediaFromForumTopic: sharedMediaFromForumTopic, switchToGifts: switchToGifts, switchToGroupsInCommon: switchToGroupsInCommon)
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nearbyPeerDistance, reactionSourceMessageId: reactionSourceMessageId, callMessages: callMessages, isMyProfile: isMyProfile, hintGroupInCommon: hintGroupInCommon, forumTopicThread: forumTopicThread, sharedMediaFromForumTopic: sharedMediaFromForumTopic, switchToGifts: switchToGifts, switchToGroupsInCommon: switchToGroupsInCommon, switchToStoryFolder: switchToStoryFolder)
|
||||
} else if peer is TelegramSecretChat {
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: [])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
|
|||
externalState.isPeerArchived = channel.storiesHidden ?? false
|
||||
}
|
||||
|
||||
self.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit)
|
||||
self.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit)
|
||||
|
||||
dismissCameraImpl?()
|
||||
})
|
||||
|
|
@ -565,6 +565,8 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
|
|||
case .botPreview:
|
||||
targetPeerId = nil
|
||||
}
|
||||
|
||||
let folders: [Int64] = results.first?.options.folderIds ?? []
|
||||
|
||||
if let rootTabController = self.rootTabController {
|
||||
if let index = rootTabController.controllers.firstIndex(where: { $0 is ChatListController}) {
|
||||
|
|
@ -736,6 +738,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
|
|||
period: result.options.timeout,
|
||||
randomId: result.randomId,
|
||||
forwardInfo: forwardInfo,
|
||||
folders: folders,
|
||||
uploadInfo: results.count > 1 ? StoryUploadInfo(groupingId: groupingId, index: index, total: Int32(results.count)) : nil
|
||||
)
|
||||
|> deliverOnMainQueue).startStandalone(next: { stableId in
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ public enum ParsedInternalPeerUrlParameter {
|
|||
case text(String)
|
||||
case profile
|
||||
case referrer(String)
|
||||
case storyFolder(Int64)
|
||||
}
|
||||
|
||||
public enum ParsedInternalUrl {
|
||||
|
|
@ -345,6 +346,8 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, context: Accou
|
|||
}
|
||||
} else if queryItem.name == "ref", let referrer = queryItem.value {
|
||||
return .peer(.name(peerName), .referrer(referrer))
|
||||
} else if queryItem.name == "stories", let value = queryItem.value, let folderId = Int64(value) {
|
||||
return .peer(.name(peerName), .storyFolder(folderId))
|
||||
}
|
||||
} else if ["voicechat", "videochat", "livestream"].contains(queryItem.name) {
|
||||
return .peer(.name(peerName), .voiceChat(nil))
|
||||
|
|
@ -401,6 +404,8 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, context: Accou
|
|||
return .peer(.name(peerName), .appStart("", queryItem.value, mode))
|
||||
} else if queryItem.name == "ref", let referrer = queryItem.value {
|
||||
return .peer(.name(peerName), .referrer(referrer))
|
||||
} else if queryItem.name == "stories", let value = queryItem.value, let folderId = Int64(value) {
|
||||
return .peer(.name(peerName), .storyFolder(folderId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -939,6 +944,8 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
|
|||
)
|
||||
case .referrer:
|
||||
return .single(.result(.peer(peer._asPeer(), .chat(textInputState: nil, subject: nil, peekData: nil))))
|
||||
case let .storyFolder(folderId):
|
||||
return .single(.result(.storyFolder(peerId: peer.id, id: folderId)))
|
||||
}
|
||||
} else {
|
||||
return .single(.result(.peer(peer._asPeer(), .chat(textInputState: nil, subject: nil, peekData: nil))))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"app": "11.13.4",
|
||||
"xcode": "16.2",
|
||||
"bazel": "8.2.1:22ff65b05869f6160e5157b1b425a14a62085d71d8baef571f462b8fe5a703a3",
|
||||
"bazel": "8.3.1:0cac3a67dc5429c68272dc6944104952e9e4cf84b29d126a5ff3fbaa59045217",
|
||||
"macos": "15"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue