mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
[WIP] Stories
This commit is contained in:
@@ -63,7 +63,15 @@ public enum RequestWebViewError {
|
||||
private func keepWebViewSignal(network: Network, stateManager: AccountStateManager, flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, queryId: Int64, replyToMessageId: MessageId?, threadId: Int64?, sendAs: Api.InputPeer?) -> Signal<Never, KeepWebViewError> {
|
||||
let signal = Signal<Never, KeepWebViewError> { subscriber in
|
||||
let poll = Signal<Never, KeepWebViewError> { subscriber in
|
||||
let signal: Signal<Never, KeepWebViewError> = network.request(Api.functions.messages.prolongWebView(flags: flags, peer: peer, bot: bot, queryId: queryId, replyToMsgId: replyToMessageId?.id, topMsgId: threadId.flatMap(Int32.init(clamping:)), sendAs: sendAs))
|
||||
var replyTo: Api.InputReplyTo?
|
||||
if let replyToMessageId = replyToMessageId {
|
||||
var replyFlags: Int32 = 0
|
||||
if threadId != nil {
|
||||
replyFlags |= 1 << 0
|
||||
}
|
||||
replyTo = .inputReplyToMessage(flags: replyFlags, replyToMsgId: replyToMessageId.id, topMsgId: threadId.flatMap(Int32.init(clamping:)))
|
||||
}
|
||||
let signal: Signal<Never, KeepWebViewError> = network.request(Api.functions.messages.prolongWebView(flags: flags, peer: peer, bot: bot, queryId: queryId, replyTo: replyTo, sendAs: sendAs))
|
||||
|> mapError { _ -> KeepWebViewError in
|
||||
return .generic
|
||||
}
|
||||
@@ -120,22 +128,25 @@ func _internal_requestWebView(postbox: Postbox, network: Network, stateManager:
|
||||
if let _ = serializedThemeParams {
|
||||
flags |= (1 << 2)
|
||||
}
|
||||
var replyToMsgId: Int32?
|
||||
if let replyToMessageId = replyToMessageId {
|
||||
flags |= (1 << 0)
|
||||
replyToMsgId = replyToMessageId.id
|
||||
}
|
||||
if let _ = payload {
|
||||
flags |= (1 << 3)
|
||||
}
|
||||
if fromMenu {
|
||||
flags |= (1 << 4)
|
||||
}
|
||||
if threadId != nil {
|
||||
flags |= (1 << 9)
|
||||
|
||||
var replyTo: Api.InputReplyTo?
|
||||
if let replyToMessageId = replyToMessageId {
|
||||
flags |= (1 << 0)
|
||||
|
||||
var replyFlags: Int32 = 0
|
||||
if threadId != nil {
|
||||
replyFlags |= 1 << 0
|
||||
}
|
||||
replyTo = .inputReplyToMessage(flags: replyFlags, replyToMsgId: replyToMessageId.id, topMsgId: threadId.flatMap(Int32.init(clamping:)))
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.requestWebView(flags: flags, peer: inputPeer, bot: inputBot, url: url, startParam: payload, themeParams: serializedThemeParams, platform: botWebViewPlatform, replyToMsgId: replyToMsgId, topMsgId: threadId.flatMap(Int32.init(clamping:)), sendAs: nil))
|
||||
return network.request(Api.functions.messages.requestWebView(flags: flags, peer: inputPeer, bot: inputBot, url: url, startParam: payload, themeParams: serializedThemeParams, platform: botWebViewPlatform, replyTo: replyTo, sendAs: nil))
|
||||
|> mapError { _ -> RequestWebViewError in
|
||||
return .generic
|
||||
}
|
||||
|
||||
@@ -704,8 +704,12 @@ extension Api.StoryItem {
|
||||
extension Stories.Item.Views {
|
||||
init(apiViews: Api.StoryViews) {
|
||||
switch apiViews {
|
||||
case let .storyViews(recentViewers, viewsCount):
|
||||
self.init(seenCount: Int(viewsCount), seenPeerIds: recentViewers.map { PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value($0)) })
|
||||
case let .storyViews(_, viewsCount, recentViewers):
|
||||
var seenPeerIds: [PeerId] = []
|
||||
if let recentViewers = recentViewers {
|
||||
seenPeerIds = recentViewers.map { PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value($0)) }
|
||||
}
|
||||
self.init(seenCount: Int(viewsCount), seenPeerIds: seenPeerIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -769,69 +773,42 @@ extension Stories.StoredItem {
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_parseApiStoryItem(transaction: Transaction, peerId: PeerId, apiStory: Api.StoryItem) -> StoryListContext.Item? {
|
||||
switch apiStory {
|
||||
case let .storyItem(flags, id, date, caption, entities, media, privacy, views):
|
||||
let _ = flags
|
||||
let (parsedMedia, _, _, _) = textMediaAndExpirationTimerFromApiMedia(media, peerId)
|
||||
if let parsedMedia = parsedMedia {
|
||||
var parsedPrivacy: EngineStoryPrivacy?
|
||||
if let privacy = privacy {
|
||||
var base: EngineStoryPrivacy.Base = .everyone
|
||||
var additionalPeerIds: [EnginePeer.Id] = []
|
||||
for rule in privacy {
|
||||
switch rule {
|
||||
case .privacyValueAllowAll:
|
||||
base = .everyone
|
||||
case .privacyValueAllowContacts:
|
||||
base = .contacts
|
||||
case .privacyValueAllowCloseFriends:
|
||||
base = .closeFriends
|
||||
case let .privacyValueAllowUsers(users):
|
||||
for id in users {
|
||||
additionalPeerIds.append(EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(id)))
|
||||
}
|
||||
case let .privacyValueAllowChatParticipants(chats):
|
||||
for id in chats {
|
||||
if let peer = transaction.getPeer(EnginePeer.Id(namespace: Namespaces.Peer.CloudGroup, id: EnginePeer.Id.Id._internalFromInt64Value(id))) {
|
||||
additionalPeerIds.append(peer.id)
|
||||
} else if let peer = transaction.getPeer(EnginePeer.Id(namespace: Namespaces.Peer.CloudChannel, id: EnginePeer.Id.Id._internalFromInt64Value(id))) {
|
||||
additionalPeerIds.append(peer.id)
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
parsedPrivacy = EngineStoryPrivacy(base: base, additionallyIncludePeers: additionalPeerIds)
|
||||
}
|
||||
|
||||
let item = StoryListContext.Item(
|
||||
id: id,
|
||||
timestamp: date,
|
||||
media: EngineMedia(parsedMedia),
|
||||
text: caption ?? "",
|
||||
entities: entities.flatMap { entities in return messageTextEntitiesFromApiEntities(entities) } ?? [],
|
||||
views: views.flatMap { _internal_parseApiStoryViews(transaction: transaction, views: $0) },
|
||||
privacy: parsedPrivacy
|
||||
)
|
||||
return item
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case .storyItemSkipped:
|
||||
return nil
|
||||
case .storyItemDeleted:
|
||||
return nil
|
||||
func _internal_getStoriesById(accountPeerId: PeerId, postbox: Postbox, network: Network, peer: PeerReference, ids: [Int32]) -> Signal<[Stories.StoredItem], NoError> {
|
||||
guard let inputUser = peer.inputUser else {
|
||||
return .single([])
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_parseApiStoryViews(transaction: Transaction, views: Api.StoryViews) -> StoryListContext.Views {
|
||||
switch views {
|
||||
case let .storyViews(recentViewers, viewsCount):
|
||||
return StoryListContext.Views(seenCount: Int(viewsCount), seenPeers: recentViewers.compactMap { id -> EnginePeer? in
|
||||
return transaction.getPeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id))).flatMap(EnginePeer.init)
|
||||
})
|
||||
|
||||
return network.request(Api.functions.stories.getStoriesByID(userId: inputUser, id: ids))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.stories.Stories?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<[Stories.StoredItem], NoError> in
|
||||
guard let result = result else {
|
||||
return .single([])
|
||||
}
|
||||
return postbox.transaction { transaction -> [Stories.StoredItem] in
|
||||
switch result {
|
||||
case let .stories(_, stories, users):
|
||||
var peers: [Peer] = []
|
||||
var peerPresences: [PeerId: Api.User] = [:]
|
||||
|
||||
for user in users {
|
||||
let telegramUser = TelegramUser(user: user)
|
||||
peers.append(telegramUser)
|
||||
peerPresences[telegramUser.id] = user
|
||||
}
|
||||
|
||||
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
})
|
||||
updatePeerPresences(transaction: transaction, accountPeerId: accountPeerId, peerPresences: peerPresences)
|
||||
|
||||
return stories.compactMap { apiStoryItem -> Stories.StoredItem? in
|
||||
return Stories.StoredItem(apiStoryItem: apiStoryItem, peerId: peer.id, transaction: transaction)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -879,42 +856,6 @@ func _internal_getStoriesById(accountPeerId: PeerId, postbox: Postbox, network:
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_getStoryById(accountPeerId: PeerId, postbox: Postbox, network: Network, peer: PeerReference, id: Int32) -> Signal<StoryListContext.Item?, NoError> {
|
||||
guard let inputUser = peer.inputUser else {
|
||||
return .single(nil)
|
||||
}
|
||||
return network.request(Api.functions.stories.getStoriesByID(userId: inputUser, id: [id]))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.stories.Stories?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<StoryListContext.Item?, NoError> in
|
||||
guard let result = result else {
|
||||
return .single(nil)
|
||||
}
|
||||
return postbox.transaction { transaction -> StoryListContext.Item? in
|
||||
switch result {
|
||||
case let .stories(_, stories, users):
|
||||
var peers: [Peer] = []
|
||||
var peerPresences: [PeerId: Api.User] = [:]
|
||||
|
||||
for user in users {
|
||||
let telegramUser = TelegramUser(user: user)
|
||||
peers.append(telegramUser)
|
||||
peerPresences[telegramUser.id] = user
|
||||
}
|
||||
|
||||
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
})
|
||||
updatePeerPresences(transaction: transaction, accountPeerId: accountPeerId, peerPresences: peerPresences)
|
||||
|
||||
return stories.first.flatMap { _internal_parseApiStoryItem(transaction: transaction, peerId: peer.id, apiStory: $0) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final class StoryViewList {
|
||||
public final class Item {
|
||||
public let peer: EnginePeer
|
||||
@@ -978,18 +919,18 @@ func _internal_getStoryViewList(account: Account, id: Int32, offsetTimestamp: In
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_getStoryViews(account: Account, ids: [Int32]) -> Signal<[Int32: StoryListContext.Views], NoError> {
|
||||
func _internal_getStoryViews(account: Account, ids: [Int32]) -> Signal<[Int32: Stories.Item.Views], NoError> {
|
||||
return account.network.request(Api.functions.stories.getStoriesViews(id: ids))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.stories.StoryViews?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<[Int32: StoryListContext.Views], NoError> in
|
||||
|> mapToSignal { result -> Signal<[Int32: Stories.Item.Views], NoError> in
|
||||
guard let result = result else {
|
||||
return .single([:])
|
||||
}
|
||||
return account.postbox.transaction { transaction -> [Int32: StoryListContext.Views] in
|
||||
var parsedViews: [Int32: StoryListContext.Views] = [:]
|
||||
return account.postbox.transaction { transaction -> [Int32: Stories.Item.Views] in
|
||||
var parsedViews: [Int32: Stories.Item.Views] = [:]
|
||||
switch result {
|
||||
case let .storyViews(views, users):
|
||||
var peers: [Peer] = []
|
||||
@@ -1008,7 +949,7 @@ func _internal_getStoryViews(account: Account, ids: [Int32]) -> Signal<[Int32: S
|
||||
|
||||
for i in 0 ..< views.count {
|
||||
if i < ids.count {
|
||||
parsedViews[ids[i]] = _internal_parseApiStoryViews(transaction: transaction, views: views[i])
|
||||
parsedViews[ids[i]] = Stories.Item.Views(apiViews: views[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -774,7 +774,7 @@ public extension TelegramEngine {
|
||||
let resource = MediaResourceReference.media(media: .story(peer: peerReference, id: item.id, media: file), resource: file.resource)
|
||||
resultResources[EngineMediaResource.Id(resource.resource.id)] = StoryPreloadInfo(
|
||||
resource: resource,
|
||||
size: nil,
|
||||
size: file.preloadSize,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
@@ -788,10 +788,6 @@ public extension TelegramEngine {
|
||||
}
|
||||
}
|
||||
|
||||
public func peerStoryFocusContext(id: EnginePeer.Id, focusItemId: Int32?) -> PeerStoryFocusContext {
|
||||
return PeerStoryFocusContext(account: self.account, peerId: id, focusItemId: focusItemId)
|
||||
}
|
||||
|
||||
public func refreshStories(peerId: EnginePeer.Id, ids: [Int32]) -> Signal<Never, NoError> {
|
||||
return _internal_getStoriesById(accountPeerId: self.account.peerId, postbox: self.account.postbox, network: self.account.network, peerId: peerId, ids: ids)
|
||||
|> mapToSignal { result -> Signal<Never, NoError> in
|
||||
@@ -812,10 +808,6 @@ public extension TelegramEngine {
|
||||
}
|
||||
}
|
||||
|
||||
public func peerStories(id: EnginePeer.Id) -> StoryListContext {
|
||||
return StoryListContext(account: self.account, scope: .peer(id))
|
||||
}
|
||||
|
||||
public func uploadStory(media: EngineStoryInputMedia, text: String, entities: [MessageTextEntity], privacy: EngineStoryPrivacy) -> Signal<Never, NoError> {
|
||||
return _internal_uploadStory(account: self.account, media: media, text: text, entities: entities, privacy: privacy)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user