This commit is contained in:
Isaac 2025-07-22 00:13:32 +02:00
parent 0817e0a943
commit cf3dbeee29
21 changed files with 703 additions and 287 deletions

11
MODULE.bazel.lock generated
View file

@ -312,7 +312,7 @@
},
"@@rules_xcodeproj+//xcodeproj:extensions.bzl%non_module_deps": {
"general": {
"bzlTransitiveDigest": "/r7IWMTdpceHqqiSh7G9bQLHvIkfqE/cesswbkTSJZw=",
"bzlTransitiveDigest": "6MYik+6MZUO7rOzaI0dUJYVD8dJrR1Q2rT+5vo1j73U=",
"usagesDigest": "jzxYhnOC9BE0dJ0biFLfxWXi/+R19uAAZkJ0p9CY0JI=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
@ -345,6 +345,15 @@
"url": "https://github.com/apple/swift-argument-parser/archive/refs/tags/1.2.3.tar.gz"
}
},
"com_github_tadija_aexml": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"build_file_content": "load(\"@build_bazel_rules_swift//swift:swift.bzl\", \"swift_library\")\n\nswift_library(\n name = \"AEXML\",\n srcs = glob([\"Sources/AEXML/**/*.swift\"]),\n visibility = [\"//visibility:public\"],\n)\n",
"sha256": "5a76c28e4fa9dcc1cbfb87a8518652628e990e522ecfbc98bdad17eabf4631d5",
"strip_prefix": "AEXML-4.6.1",
"url": "https://github.com/tadija/AEXML/archive/refs/tags/4.6.1.tar.gz"
}
},
"com_github_michaeleisel_jjliso8601dateformatter": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {

View file

@ -884,7 +884,7 @@ public protocol MediaEditorScreenResult {
public protocol TelegramRootControllerInterface: NavigationController {
@discardableResult
func openStoryCamera(customTarget: Stories.PendingTarget?, transitionIn: StoryCameraTransitionIn?, transitionedIn: @escaping () -> Void, transitionOut: @escaping (Stories.PendingTarget?, Bool) -> StoryCameraTransitionOut?) -> StoryCameraTransitionInCoordinator?
func proceedWithStoryUpload(target: Stories.PendingTarget, results: [MediaEditorScreenResult], existingMedia: EngineMedia?, forwardInfo: Stories.PendingForwardInfo?, externalState: MediaEditorTransitionOutExternalState, commit: @escaping (@escaping () -> Void) -> Void)
func proceedWithStoryUpload(target: Stories.PendingTarget, results: [MediaEditorScreenResult], existingMedia: EngineMedia?, forwardInfo: Stories.PendingForwardInfo?, folders: [Int64], externalState: MediaEditorTransitionOutExternalState, commit: @escaping (@escaping () -> Void) -> Void)
func getContactsController() -> ViewController?
func getChatsController() -> ViewController?

View file

@ -992,8 +992,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[872932635] = { return Api.StickerSetCovered.parse_stickerSetMultiCovered($0) }
dict[2008112412] = { return Api.StickerSetCovered.parse_stickerSetNoCovered($0) }
dict[1898850301] = { return Api.StoriesStealthMode.parse_storiesStealthMode($0) }
dict[-1826262950] = { return Api.StoryAlbum.parse_storyAlbum($0) }
dict[-1205411504] = { return Api.StoryFwdHeader.parse_storyFwdHeader($0) }
dict[2041735716] = { return Api.StoryItem.parse_storyItem($0) }
dict[-302947087] = { return Api.StoryItem.parse_storyItem($0) }
dict[1374088783] = { return Api.StoryItem.parse_storyItemDeleted($0) }
dict[-5388013] = { return Api.StoryItem.parse_storyItemSkipped($0) }
dict[1620104917] = { return Api.StoryReaction.parse_storyReaction($0) }
@ -1476,6 +1477,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[172975040] = { return Api.storage.FileType.parse_filePng($0) }
dict[-1432995067] = { return Api.storage.FileType.parse_fileUnknown($0) }
dict[276907596] = { return Api.storage.FileType.parse_fileWebp($0) }
dict[-1013417414] = { return Api.stories.Albums.parse_albums($0) }
dict[1448008427] = { return Api.stories.Albums.parse_albumsNotModified($0) }
dict[1862033025] = { return Api.stories.AllStories.parse_allStories($0) }
dict[291044926] = { return Api.stories.AllStories.parse_allStoriesNotModified($0) }
dict[-1014513586] = { return Api.stories.CanSendStoryCount.parse_canSendStoryCount($0) }
@ -2196,6 +2199,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.StoriesStealthMode:
_1.serialize(buffer, boxed)
case let _1 as Api.StoryAlbum:
_1.serialize(buffer, boxed)
case let _1 as Api.StoryFwdHeader:
_1.serialize(buffer, boxed)
case let _1 as Api.StoryItem:
@ -2614,6 +2619,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.storage.FileType:
_1.serialize(buffer, boxed)
case let _1 as Api.stories.Albums:
_1.serialize(buffer, boxed)
case let _1 as Api.stories.AllStories:
_1.serialize(buffer, boxed)
case let _1 as Api.stories.CanSendStoryCount:

View file

@ -324,6 +324,62 @@ public extension Api {
}
}
public extension Api {
enum StoryAlbum: TypeConstructorDescription {
case storyAlbum(flags: Int32, albumId: Int32, title: String, iconPhoto: Api.Photo?, iconVideo: Api.Document?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .storyAlbum(let flags, let albumId, let title, let iconPhoto, let iconVideo):
if boxed {
buffer.appendInt32(-1826262950)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(albumId, buffer: buffer, boxed: false)
serializeString(title, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {iconPhoto!.serialize(buffer, true)}
if Int(flags) & Int(1 << 1) != 0 {iconVideo!.serialize(buffer, true)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .storyAlbum(let flags, let albumId, let title, let iconPhoto, let iconVideo):
return ("storyAlbum", [("flags", flags as Any), ("albumId", albumId as Any), ("title", title as Any), ("iconPhoto", iconPhoto as Any), ("iconVideo", iconVideo as Any)])
}
}
public static func parse_storyAlbum(_ reader: BufferReader) -> StoryAlbum? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: String?
_3 = parseString(reader)
var _4: Api.Photo?
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.Photo
} }
var _5: Api.Document?
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
_5 = Api.parse(reader, signature: signature) as? Api.Document
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.StoryAlbum.storyAlbum(flags: _1!, albumId: _2!, title: _3!, iconPhoto: _4, iconVideo: _5)
}
else {
return nil
}
}
}
}
public extension Api {
enum StoryFwdHeader: TypeConstructorDescription {
case storyFwdHeader(flags: Int32, from: Api.Peer?, fromName: String?, storyId: Int32?)
@ -376,15 +432,15 @@ public extension Api {
}
public extension Api {
indirect enum StoryItem: TypeConstructorDescription {
case storyItem(flags: Int32, id: Int32, date: Int32, fromId: Api.Peer?, fwdFrom: Api.StoryFwdHeader?, expireDate: Int32, caption: String?, entities: [Api.MessageEntity]?, media: Api.MessageMedia, mediaAreas: [Api.MediaArea]?, privacy: [Api.PrivacyRule]?, views: Api.StoryViews?, sentReaction: Api.Reaction?)
case storyItem(flags: Int32, id: Int32, date: Int32, fromId: Api.Peer?, fwdFrom: Api.StoryFwdHeader?, expireDate: Int32, caption: String?, entities: [Api.MessageEntity]?, media: Api.MessageMedia, mediaAreas: [Api.MediaArea]?, privacy: [Api.PrivacyRule]?, views: Api.StoryViews?, sentReaction: Api.Reaction?, albums: [Int32]?)
case storyItemDeleted(id: Int32)
case storyItemSkipped(flags: Int32, id: Int32, date: Int32, expireDate: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .storyItem(let flags, let id, let date, let fromId, let fwdFrom, let expireDate, let caption, let entities, let media, let mediaAreas, let privacy, let views, let sentReaction):
case .storyItem(let flags, let id, let date, let fromId, let fwdFrom, let expireDate, let caption, let entities, let media, let mediaAreas, let privacy, let views, let sentReaction, let albums):
if boxed {
buffer.appendInt32(2041735716)
buffer.appendInt32(-302947087)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
@ -411,6 +467,11 @@ public extension Api {
}}
if Int(flags) & Int(1 << 3) != 0 {views!.serialize(buffer, true)}
if Int(flags) & Int(1 << 15) != 0 {sentReaction!.serialize(buffer, true)}
if Int(flags) & Int(1 << 19) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(albums!.count))
for item in albums! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
break
case .storyItemDeleted(let id):
if boxed {
@ -432,8 +493,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .storyItem(let flags, let id, let date, let fromId, let fwdFrom, let expireDate, let caption, let entities, let media, let mediaAreas, let privacy, let views, let sentReaction):
return ("storyItem", [("flags", flags as Any), ("id", id as Any), ("date", date as Any), ("fromId", fromId as Any), ("fwdFrom", fwdFrom as Any), ("expireDate", expireDate as Any), ("caption", caption as Any), ("entities", entities as Any), ("media", media as Any), ("mediaAreas", mediaAreas as Any), ("privacy", privacy as Any), ("views", views as Any), ("sentReaction", sentReaction as Any)])
case .storyItem(let flags, let id, let date, let fromId, let fwdFrom, let expireDate, let caption, let entities, let media, let mediaAreas, let privacy, let views, let sentReaction, let albums):
return ("storyItem", [("flags", flags as Any), ("id", id as Any), ("date", date as Any), ("fromId", fromId as Any), ("fwdFrom", fwdFrom as Any), ("expireDate", expireDate as Any), ("caption", caption as Any), ("entities", entities as Any), ("media", media as Any), ("mediaAreas", mediaAreas as Any), ("privacy", privacy as Any), ("views", views as Any), ("sentReaction", sentReaction as Any), ("albums", albums as Any)])
case .storyItemDeleted(let id):
return ("storyItemDeleted", [("id", id as Any)])
case .storyItemSkipped(let flags, let id, let date, let expireDate):
@ -484,6 +545,10 @@ public extension Api {
if Int(_1!) & Int(1 << 15) != 0 {if let signature = reader.readInt32() {
_13 = Api.parse(reader, signature: signature) as? Api.Reaction
} }
var _14: [Int32]?
if Int(_1!) & Int(1 << 19) != 0 {if let _ = reader.readInt32() {
_14 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
@ -497,8 +562,9 @@ public extension Api {
let _c11 = (Int(_1!) & Int(1 << 2) == 0) || _11 != nil
let _c12 = (Int(_1!) & Int(1 << 3) == 0) || _12 != nil
let _c13 = (Int(_1!) & Int(1 << 15) == 0) || _13 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 {
return Api.StoryItem.storyItem(flags: _1!, id: _2!, date: _3!, fromId: _4, fwdFrom: _5, expireDate: _6!, caption: _7, entities: _8, media: _9!, mediaAreas: _10, privacy: _11, views: _12, sentReaction: _13)
let _c14 = (Int(_1!) & Int(1 << 19) == 0) || _14 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 {
return Api.StoryItem.storyItem(flags: _1!, id: _2!, date: _3!, fromId: _4, fwdFrom: _5, expireDate: _6!, caption: _7, entities: _8, media: _9!, mediaAreas: _10, privacy: _11, views: _12, sentReaction: _13, albums: _14)
}
else {
return nil

View file

@ -482,6 +482,64 @@ public extension Api.storage {
}
}
public extension Api.stories {
enum Albums: TypeConstructorDescription {
case albums(hash: Int64, albums: [Api.StoryAlbum])
case albumsNotModified
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .albums(let hash, let albums):
if boxed {
buffer.appendInt32(-1013417414)
}
serializeInt64(hash, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(albums.count))
for item in albums {
item.serialize(buffer, true)
}
break
case .albumsNotModified:
if boxed {
buffer.appendInt32(1448008427)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .albums(let hash, let albums):
return ("albums", [("hash", hash as Any), ("albums", albums as Any)])
case .albumsNotModified:
return ("albumsNotModified", [])
}
}
public static func parse_albums(_ reader: BufferReader) -> Albums? {
var _1: Int64?
_1 = reader.readInt64()
var _2: [Api.StoryAlbum]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StoryAlbum.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.stories.Albums.albums(hash: _1!, albums: _2!)
}
else {
return nil
}
}
public static func parse_albumsNotModified(_ reader: BufferReader) -> Albums? {
return Api.stories.Albums.albumsNotModified
}
}
}
public extension Api.stories {
enum AllStories: TypeConstructorDescription {
case allStories(flags: Int32, count: Int32, state: String, peerStories: [Api.PeerStories], chats: [Api.Chat], users: [Api.User], stealthMode: Api.StoriesStealthMode)
@ -1428,55 +1486,3 @@ public extension Api.updates {
}
}
public extension Api.updates {
enum State: TypeConstructorDescription {
case state(pts: Int32, qts: Int32, date: Int32, seq: Int32, unreadCount: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .state(let pts, let qts, let date, let seq, let unreadCount):
if boxed {
buffer.appendInt32(-1519637954)
}
serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(qts, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
serializeInt32(seq, buffer: buffer, boxed: false)
serializeInt32(unreadCount, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .state(let pts, let qts, let date, let seq, let unreadCount):
return ("state", [("pts", pts as Any), ("qts", qts as Any), ("date", date as Any), ("seq", seq as Any), ("unreadCount", unreadCount as Any)])
}
}
public static func parse_state(_ reader: BufferReader) -> State? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
_4 = reader.readInt32()
var _5: Int32?
_5 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.updates.State.state(pts: _1!, qts: _2!, date: _3!, seq: _4!, unreadCount: _5!)
}
else {
return nil
}
}
}
}

View file

@ -1,3 +1,55 @@
public extension Api.updates {
enum State: TypeConstructorDescription {
case state(pts: Int32, qts: Int32, date: Int32, seq: Int32, unreadCount: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .state(let pts, let qts, let date, let seq, let unreadCount):
if boxed {
buffer.appendInt32(-1519637954)
}
serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(qts, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
serializeInt32(seq, buffer: buffer, boxed: false)
serializeInt32(unreadCount, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .state(let pts, let qts, let date, let seq, let unreadCount):
return ("state", [("pts", pts as Any), ("qts", qts as Any), ("date", date as Any), ("seq", seq as Any), ("unreadCount", unreadCount as Any)])
}
}
public static func parse_state(_ reader: BufferReader) -> State? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
_4 = reader.readInt32()
var _5: Int32?
_5 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.updates.State.state(pts: _1!, qts: _2!, date: _3!, seq: _4!, unreadCount: _5!)
}
else {
return nil
}
}
}
}
public extension Api.upload {
enum CdnFile: TypeConstructorDescription {
case cdnFile(bytes: Buffer)

View file

@ -11371,6 +11371,43 @@ public extension Api.functions.stories {
})
}
}
public extension Api.functions.stories {
static func createAlbum(peer: Api.InputPeer, title: String, stories: [Int32]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.StoryAlbum>) {
let buffer = Buffer()
buffer.appendInt32(-1553754395)
peer.serialize(buffer, true)
serializeString(title, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(stories.count))
for item in stories {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription(name: "stories.createAlbum", parameters: [("peer", String(describing: peer)), ("title", String(describing: title)), ("stories", String(describing: stories))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.StoryAlbum? in
let reader = BufferReader(buffer)
var result: Api.StoryAlbum?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.StoryAlbum
}
return result
})
}
}
public extension Api.functions.stories {
static func deleteAlbum(peer: Api.InputPeer, albumId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-1925949744)
peer.serialize(buffer, true)
serializeInt32(albumId, buffer: buffer, boxed: false)
return (FunctionDescription(name: "stories.deleteAlbum", parameters: [("peer", String(describing: peer)), ("albumId", String(describing: albumId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.stories {
static func deleteStories(peer: Api.InputPeer, id: [Int32]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Int32]>) {
let buffer = Buffer()
@ -11441,6 +11478,40 @@ public extension Api.functions.stories {
})
}
}
public extension Api.functions.stories {
static func getAlbumStories(peer: Api.InputPeer, albumId: Int32, offset: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.stories.Stories>) {
let buffer = Buffer()
buffer.appendInt32(-1400869535)
peer.serialize(buffer, true)
serializeInt32(albumId, buffer: buffer, boxed: false)
serializeInt32(offset, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription(name: "stories.getAlbumStories", parameters: [("peer", String(describing: peer)), ("albumId", String(describing: albumId)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stories.Stories? in
let reader = BufferReader(buffer)
var result: Api.stories.Stories?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.stories.Stories
}
return result
})
}
}
public extension Api.functions.stories {
static func getAlbums(peer: Api.InputPeer, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.stories.Albums>) {
let buffer = Buffer()
buffer.appendInt32(632548039)
peer.serialize(buffer, true)
serializeInt64(hash, buffer: buffer, boxed: false)
return (FunctionDescription(name: "stories.getAlbums", parameters: [("peer", String(describing: peer)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stories.Albums? in
let reader = BufferReader(buffer)
var result: Api.stories.Albums?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.stories.Albums
}
return result
})
}
}
public extension Api.functions.stories {
static func getAllReadPeerStories() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
@ -11671,6 +11742,26 @@ public extension Api.functions.stories {
})
}
}
public extension Api.functions.stories {
static func reorderAlbums(peer: Api.InputPeer, order: [Int32]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-2060059687)
peer.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(order.count))
for item in order {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription(name: "stories.reorderAlbums", parameters: [("peer", String(describing: peer)), ("order", String(describing: order))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.stories {
static func report(peer: Api.InputPeer, id: [Int32], option: Buffer, message: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ReportResult>) {
let buffer = Buffer()
@ -11732,9 +11823,9 @@ public extension Api.functions.stories {
}
}
public extension Api.functions.stories {
static func sendStory(flags: Int32, peer: Api.InputPeer, media: Api.InputMedia, mediaAreas: [Api.MediaArea]?, caption: String?, entities: [Api.MessageEntity]?, privacyRules: [Api.InputPrivacyRule], randomId: Int64, period: Int32?, fwdFromId: Api.InputPeer?, fwdFromStory: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
static func sendStory(flags: Int32, peer: Api.InputPeer, media: Api.InputMedia, mediaAreas: [Api.MediaArea]?, caption: String?, entities: [Api.MessageEntity]?, privacyRules: [Api.InputPrivacyRule], randomId: Int64, period: Int32?, fwdFromId: Api.InputPeer?, fwdFromStory: Int32?, albums: [Int32]?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(-454661813)
buffer.appendInt32(1937752812)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
media.serialize(buffer, true)
@ -11758,7 +11849,12 @@ public extension Api.functions.stories {
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(period!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 6) != 0 {fwdFromId!.serialize(buffer, true)}
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(fwdFromStory!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "stories.sendStory", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("media", String(describing: media)), ("mediaAreas", String(describing: mediaAreas)), ("caption", String(describing: caption)), ("entities", String(describing: entities)), ("privacyRules", String(describing: privacyRules)), ("randomId", String(describing: randomId)), ("period", String(describing: period)), ("fwdFromId", String(describing: fwdFromId)), ("fwdFromStory", String(describing: fwdFromStory))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
if Int(flags) & Int(1 << 8) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(albums!.count))
for item in albums! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
return (FunctionDescription(name: "stories.sendStory", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("media", String(describing: media)), ("mediaAreas", String(describing: mediaAreas)), ("caption", String(describing: caption)), ("entities", String(describing: entities)), ("privacyRules", String(describing: privacyRules)), ("randomId", String(describing: randomId)), ("period", String(describing: period)), ("fwdFromId", String(describing: fwdFromId)), ("fwdFromStory", String(describing: fwdFromStory)), ("albums", String(describing: albums))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
@ -11840,6 +11936,39 @@ public extension Api.functions.stories {
})
}
}
public extension Api.functions.stories {
static func updateAlbum(flags: Int32, peer: Api.InputPeer, albumId: Int32, title: String?, deleteStories: [Int32]?, addStories: [Int32]?, order: [Int32]?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.StoryAlbum>) {
let buffer = Buffer()
buffer.appendInt32(1582455222)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(albumId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(deleteStories!.count))
for item in deleteStories! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
if Int(flags) & Int(1 << 2) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(addStories!.count))
for item in addStories! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(order!.count))
for item in order! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
return (FunctionDescription(name: "stories.updateAlbum", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("albumId", String(describing: albumId)), ("title", String(describing: title)), ("deleteStories", String(describing: deleteStories)), ("addStories", String(describing: addStories)), ("order", String(describing: order))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.StoryAlbum? in
let reader = BufferReader(buffer)
var result: Api.StoryAlbum?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.StoryAlbum
}
return result
})
}
}
public extension Api.functions.updates {
static func getChannelDifference(flags: Int32, channel: Api.InputChannel, filter: Api.ChannelMessagesFilter, pts: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.updates.ChannelDifference>) {
let buffer = Buffer()

View file

@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
return 210
return 211
}
public func parseMessage(_ data: Data!) -> Any! {

View file

@ -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

View file

@ -988,7 +988,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 +1017,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 +1065,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 +1143,7 @@ func _internal_uploadStoryImpl(
privacy: EngineStoryPrivacy,
isForwardingDisabled: Bool,
period: Int,
folders: [Int64],
randomId: Int64,
forwardInfo: Stories.PendingForwardInfo?
) -> Signal<StoryUploadResult, NoError> {
@ -1224,6 +1227,10 @@ func _internal_uploadStoryImpl(
fwdFromStory = forwardInfo.storyId
}
if !folders.isEmpty {
flags |= 1 << 8
}
return network.request(Api.functions.stories.sendStory(
flags: flags,
peer: inputPeer,
@ -1235,7 +1242,8 @@ func _internal_uploadStoryImpl(
randomId: randomId,
period: Int32(period),
fwdFromId: fwdFromId,
fwdFromStory: fwdFromStory
fwdFromStory: fwdFromStory,
albums: folders.isEmpty ? nil : folders.map(Int32.init(clamping:))
))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
@ -1259,7 +1267,7 @@ func _internal_uploadStoryImpl(
for update in updates.allUpdates {
if case let .updateStory(_, story) = update {
switch story {
case let .storyItem(_, idValue, _, fromId, _, _, _, _, media, _, _, _, _):
case let .storyItem(_, idValue, _, fromId, _, _, _, _, media, _, _, _, _, _):
if let parsedStory = Stories.StoredItem(apiStoryItem: story, peerId: toPeerId, transaction: transaction) {
var items = transaction.getStoryItems(peerId: toPeerId)
var updatedItems: [Stories.Item] = []
@ -1648,7 +1656,7 @@ func _internal_editStory(account: Account, peerId: PeerId, id: Int32, media: Eng
for update in updates.allUpdates {
if case let .updateStory(_, story) = update {
switch story {
case let .storyItem(_, _, _, _, _, _, _, _, media, _, _, _, _):
case let .storyItem(_, _, _, _, _, _, _, _, media, _, _, _, _, _):
let parsedMedia = textMediaAndExpirationTimerFromApiMedia(media, account.peerId).media
if let parsedMedia = parsedMedia, let originalMedia = originalMedia {
applyMediaResourceChanges(from: originalMedia, to: parsedMedia, postbox: account.postbox, force: false, skipPreviews: updatingCoverTime)
@ -2009,7 +2017,7 @@ func _internal_updatePinnedToTopStories(account: Account, peerId: PeerId, ids: [
extension Api.StoryItem {
var id: Int32 {
switch self {
case let .storyItem(_, id, _, _, _, _, _, _, _, _, _, _, _):
case let .storyItem(_, id, _, _, _, _, _, _, _, _, _, _, _, _):
return id
case let .storyItemDeleted(id):
return id
@ -2072,7 +2080,9 @@ 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):
let _ = albums
let parsedMedia = textMediaAndExpirationTimerFromApiMedia(media, peerId).media
if let parsedMedia = parsedMedia {
var parsedPrivacy: Stories.Item.Privacy?

View file

@ -679,6 +679,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)
@ -768,7 +770,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 +830,73 @@ public final class PeerStoryListContext: StoryListContext {
let accountPeerId = account.peerId
let isArchived = self.isArchived
let folderId = self.folderId
let folders = self.stateValue.availableFolders
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)))
let 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
}
|> `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))
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 {
@ -985,20 +957,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(self.queue)).start(next: { [weak self] storyItems, totalCount, peerReference, folderItems, hasMore in
guard let self else {
return
}
@ -1022,6 +1012,8 @@ public final class PeerStoryListContext: StoryListContext {
updatedState.items.append(item)
}
updatedState.availableFolders = folderItems
if updatedState.peerReference == nil {
updatedState.peerReference = peerReference
}
@ -1376,55 +1368,93 @@ 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, 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: []))
|> 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)
}
} |> 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 reorderFolders(ids: [Int64]) -> Disposable {
var state = self.stateValue
var folders: [State.Folder] = []
for id in ids {
@ -1440,24 +1470,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)
@ -1528,26 +1585,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 +1639,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 +1717,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 +1766,92 @@ public final class PeerStoryListContext: StoryListContext {
}
}
public func addFolder(title: String, completion: @escaping (Int64) -> Void) {
public func addFolder(title: String, completion: @escaping (Int64?) -> Void) -> Disposable {
let disposable = MetaDisposable()
self.impl.with { impl in
completion(impl.addFolder(title: title))
disposable.set(impl.addFolder(title: title, 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 reorderFolders(ids: [Int64]) -> Disposable {
let disposable = MetaDisposable()
self.impl.with { impl in
impl.reorderFolders(ids: ids)
disposable.set(impl.reorderFolders(ids: ids))
}
return disposable
}
public func addToFolder(id: Int64, items: [EngineStoryItem]) {
public func addToFolder(id: Int64, items: [EngineStoryItem]) -> Disposable {
let disposable = MetaDisposable()
self.impl.with { impl in
impl.addToFolder(id: id, items: items)
disposable.set(impl.addToFolder(id: id, items: items))
}
return disposable
}
public func removeFromFolder(id: Int64, itemIds: [Int32]) {
public func removeFromFolder(id: Int64, itemIds: [Int32]) -> Disposable {
let disposable = MetaDisposable()
self.impl.with { impl in
impl.removeFromFolder(id: id, itemIds: itemIds)
disposable.set(impl.removeFromFolder(id: id, itemIds: itemIds))
}
return disposable
}
public func reorderItemsInFolder(itemIds: [Int32]) {
public func reorderItemsInFolder(itemIds: [Int32]) -> Disposable {
let disposable = MetaDisposable()
self.impl.with { impl in
impl.reorderItemsInFolder(itemIds: itemIds)
disposable.set(impl.reorderItemsInFolder(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 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> {

View file

@ -1367,8 +1367,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> {

View file

@ -163,7 +163,7 @@ public extension MediaEditorScreenImpl {
} else {
existingMedia = storyItem.media
}
rootController.proceedWithStoryUpload(target: target, results: [result as! MediaEditorScreenResult], existingMedia: existingMedia, forwardInfo: forwardInfo, externalState: externalState, commit: commit)
rootController.proceedWithStoryUpload(target: target, results: [result as! MediaEditorScreenResult], existingMedia: existingMedia, forwardInfo: forwardInfo, folders: [], externalState: externalState, commit: commit)
}
})
} else {

View file

@ -10258,7 +10258,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
viewControllers = viewControllers.filter { !($0 is AttachmentController)}
rootController.setViewControllers(viewControllers, animated: false)
rootController.proceedWithStoryUpload(target: target, results: [result], existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit)
rootController.proceedWithStoryUpload(target: target, results: [result], existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit)
}
},
cancelled: {}

View file

@ -2481,7 +2481,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
}
if let listSource = self.listSource as? PeerStoryListContext {
listSource.removeFromFolder(id: folder.id, itemIds: [item.id])
let _ = listSource.removeFromFolder(id: folder.id, itemIds: [item.id])
}
f(.dismissWithoutContent)
@ -2575,7 +2575,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
c?.dismiss(completion: {})
if let listSource = self.listSource as? PeerStoryListContext {
listSource.addToFolder(id: folderPreview.folder.id, items: [item])
let _ = listSource.addToFolder(id: folderPreview.folder.id, items: [item])
}
})))
}
@ -4900,13 +4900,13 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
}
if let value {
if let listSource = self.listSource as? PeerStoryListContext {
listSource.addFolder(title: value, completion: { [weak self] id in
let _ = listSource.addFolder(title: value, completion: { [weak self] id in
Queue.mainQueue().async {
guard let self, let listSource = self.listSource as? PeerStoryListContext else {
guard let self, let id, let listSource = self.listSource as? PeerStoryListContext else {
return
}
if !addItems.isEmpty {
listSource.addToFolder(id: id, items: addItems)
let _ = listSource.addToFolder(id: id, items: addItems)
}
self.setStoryFolder(id: id, assumeEmpty: addItems.isEmpty)
}
@ -4931,7 +4931,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
return
}
if let listSource = self.listSource as? PeerStoryListContext {
listSource.addToFolder(id: folder.id, items: items)
let _ = listSource.addToFolder(id: folder.id, items: items)
}
})
controller.navigationPresentation = .modal
@ -4958,7 +4958,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
self.removedStoryFolders.insert(id)
if let listContext = self.listSource as? PeerStoryListContext {
listContext.removeFolder(id: id)
let _ = listContext.removeFolder(id: id)
}
if let (size, topInset, sideInset, bottomInset, deviceMetrics, visibleHeight, isScrollingLockedAtTop, expandProgress, navigationHeight, presentationData) = self.currentParams {
@ -5111,7 +5111,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
if !isReordering && !self.currentStoryFolders.isEmpty && self.canManageStories {
if let listSource = self.listSource as? PeerStoryListContext {
listSource.reorderFolders(ids: self.currentStoryFolders.map(\.id))
let _ = listSource.reorderFolders(ids: self.currentStoryFolders.map(\.id))
}
}
@ -5132,7 +5132,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
} else if case let .peer(id, _, _) = self.scope, id == self.context.account.peerId, let items = self.items {
if let _ = self.currentStoryFolder {
if let listSource = self.listSource as? PeerStoryListContext {
listSource.reorderItemsInFolder(itemIds: reorderedIds.map { $0.id })
let _ = listSource.reorderItemsInFolder(itemIds: reorderedIds.map { $0.id })
}
} else {
var updatedPinnedIds: [Int32] = []

View file

@ -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)
})
}
}
)

View file

@ -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, 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])
}
}
},

View file

@ -992,7 +992,7 @@ func openResolvedUrlImpl(
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
rootController.popToRoot(animated: false)
rootController.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit)
rootController.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit)
}
})
if let navigationController {

View file

@ -3821,7 +3821,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
externalState.storyTarget = target
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
rootController.proceedWithStoryUpload(target: target, results: [result], existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit)
rootController.proceedWithStoryUpload(target: target, results: [result], existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit)
}
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: targetPeerId))

View file

@ -471,7 +471,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
if let customTarget, case .botPreview = customTarget {
externalState.storyTarget = customTarget
self.proceedWithStoryUpload(target: customTarget, results: results, existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit)
self.proceedWithStoryUpload(target: customTarget, results: results, existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit)
dismissCameraImpl?()
return
@ -504,7 +504,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, folders: [], externalState: externalState, commit: commit)
dismissCameraImpl?()
})
@ -568,7 +568,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
})
}
public func proceedWithStoryUpload(target: Stories.PendingTarget, results: [MediaEditorScreenResult], existingMedia: EngineMedia?, forwardInfo: Stories.PendingForwardInfo?, externalState: MediaEditorTransitionOutExternalState, commit: @escaping (@escaping () -> Void) -> Void) {
public func proceedWithStoryUpload(target: Stories.PendingTarget, results: [MediaEditorScreenResult], existingMedia: EngineMedia?, forwardInfo: Stories.PendingForwardInfo?, folders: [Int64], externalState: MediaEditorTransitionOutExternalState, commit: @escaping (@escaping () -> Void) -> Void) {
guard let results = results as? [MediaEditorScreenImpl.Result] else {
return
}
@ -753,6 +753,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

View file

@ -1494,7 +1494,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
externalState.storyTarget = target
if let rootController = self.context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
rootController.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit)
rootController.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit)
}
})
if let navigationController = self.controller?.getNavigationController() {