mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-08 19:10:53 +00:00
Improve preload
This commit is contained in:
parent
d6434fa17f
commit
471eb18ba1
@ -187,7 +187,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
private var storyProgressDisposable: Disposable?
|
||||
private var storySubscriptionsDisposable: Disposable?
|
||||
private var preloadStorySubscriptionsDisposable: Disposable?
|
||||
private var preloadStoryResourceDisposables: [MediaResourceId: Disposable] = [:]
|
||||
private var preloadStoryResourceDisposables: [MediaId: Disposable] = [:]
|
||||
|
||||
private var fullScreenEffectView: RippleEffectView?
|
||||
|
||||
@ -1821,23 +1821,17 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
resources.removeAll()
|
||||
}
|
||||
|
||||
var validIds: [MediaResourceId] = []
|
||||
var validIds: [MediaId] = []
|
||||
for (_, info) in resources.sorted(by: { $0.value.priority < $1.value.priority }) {
|
||||
let resource = info.resource
|
||||
validIds.append(resource.resource.id)
|
||||
if self.preloadStoryResourceDisposables[resource.resource.id] == nil {
|
||||
var fetchRange: (Range<Int64>, MediaBoxFetchPriority)?
|
||||
if let size = info.size {
|
||||
fetchRange = (0 ..< Int64(size), .default)
|
||||
if let mediaId = info.media.id {
|
||||
validIds.append(mediaId)
|
||||
if self.preloadStoryResourceDisposables[mediaId] == nil {
|
||||
self.preloadStoryResourceDisposables[mediaId] = preloadStoryMedia(context: self.context, peer: info.peer, storyId: info.storyId, media: info.media).start()
|
||||
}
|
||||
#if DEBUG
|
||||
fetchRange = nil
|
||||
#endif
|
||||
self.preloadStoryResourceDisposables[resource.resource.id] = fetchedMediaResource(mediaBox: self.context.account.postbox.mediaBox, userLocation: .other, userContentType: .other, reference: resource, range: fetchRange).start()
|
||||
}
|
||||
}
|
||||
|
||||
var removeIds: [MediaResourceId] = []
|
||||
var removeIds: [MediaId] = []
|
||||
for (id, disposable) in self.preloadStoryResourceDisposables {
|
||||
if !validIds.contains(id) {
|
||||
removeIds.append(id)
|
||||
|
@ -14,17 +14,20 @@ public final class StoryPreloadInfo {
|
||||
case next(position: Int)
|
||||
}
|
||||
|
||||
public let resource: MediaResourceReference
|
||||
public let size: Int32?
|
||||
public let peer: PeerReference
|
||||
public let storyId: Int32
|
||||
public let media: EngineMedia
|
||||
public let priority: Priority
|
||||
|
||||
public init(
|
||||
resource: MediaResourceReference,
|
||||
size: Int32?,
|
||||
peer: PeerReference,
|
||||
storyId: Int32,
|
||||
media: EngineMedia,
|
||||
priority: Priority
|
||||
) {
|
||||
self.resource = resource
|
||||
self.size = size
|
||||
self.peer = peer
|
||||
self.storyId = storyId
|
||||
self.media = media
|
||||
self.priority = priority
|
||||
}
|
||||
}
|
||||
@ -822,7 +825,7 @@ public extension TelegramEngine {
|
||||
}
|
||||
}
|
||||
|
||||
public func preloadStorySubscriptions(isHidden: Bool) -> Signal<[EngineMediaResource.Id: StoryPreloadInfo], NoError> {
|
||||
public func preloadStorySubscriptions(isHidden: Bool) -> Signal<[EngineMedia.Id: StoryPreloadInfo], NoError> {
|
||||
let basicPeerKey = PostboxViewKey.basicPeer(self.account.peerId)
|
||||
let subscriptionsKey: PostboxStorySubscriptionsKey = isHidden ? .hidden : .filtered
|
||||
let storySubscriptionsKey = PostboxViewKey.storySubscriptions(key: subscriptionsKey)
|
||||
@ -831,7 +834,7 @@ public extension TelegramEngine {
|
||||
storySubscriptionsKey,
|
||||
PostboxViewKey.storiesState(key: .subscriptions(subscriptionsKey))
|
||||
])
|
||||
|> mapToSignal { views -> Signal<[EngineMediaResource.Id: StoryPreloadInfo], NoError> in
|
||||
|> mapToSignal { views -> Signal<[EngineMedia.Id: StoryPreloadInfo], NoError> in
|
||||
guard let basicPeerView = views.views[basicPeerKey] as? BasicPeerView, let accountPeer = basicPeerView.peer else {
|
||||
return .single([:])
|
||||
}
|
||||
@ -854,7 +857,7 @@ public extension TelegramEngine {
|
||||
})
|
||||
|
||||
return self.account.postbox.combinedView(keys: additionalDataKeys)
|
||||
|> map { views -> [EngineMediaResource.Id: StoryPreloadInfo] in
|
||||
|> map { views -> [EngineMedia.Id: StoryPreloadInfo] in
|
||||
let _ = accountPeer
|
||||
let _ = storiesStateView
|
||||
|
||||
@ -893,42 +896,23 @@ public extension TelegramEngine {
|
||||
})
|
||||
|
||||
var nextPriority: Int = 0
|
||||
var resultResources: [EngineMediaResource.Id: StoryPreloadInfo] = [:]
|
||||
var resultResources: [EngineMedia.Id: StoryPreloadInfo] = [:]
|
||||
|
||||
for itemAndPeer in sortedItems.prefix(10) {
|
||||
guard let peerReference = PeerReference(itemAndPeer.peer) else {
|
||||
continue
|
||||
}
|
||||
guard let media = itemAndPeer.item.media else {
|
||||
guard let media = itemAndPeer.item.media, let mediaId = media.id else {
|
||||
continue
|
||||
}
|
||||
if let image = media as? TelegramMediaImage, let resource = image.representations.last?.resource {
|
||||
let resource = MediaResourceReference.media(media: .story(peer: peerReference, id: itemAndPeer.item.id, media: media), resource: resource)
|
||||
resultResources[EngineMediaResource.Id(resource.resource.id)] = StoryPreloadInfo(
|
||||
resource: resource,
|
||||
size: nil,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
if let preview = file.previewRepresentations.last {
|
||||
let resource = MediaResourceReference.media(media: .story(peer: peerReference, id: itemAndPeer.item.id, media: file), resource: preview.resource)
|
||||
resultResources[EngineMediaResource.Id(resource.resource.id)] = StoryPreloadInfo(
|
||||
resource: resource,
|
||||
size: nil,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
}
|
||||
|
||||
let resource = MediaResourceReference.media(media: .story(peer: peerReference, id: itemAndPeer.item.id, media: file), resource: file.resource)
|
||||
resultResources[EngineMediaResource.Id(resource.resource.id)] = StoryPreloadInfo(
|
||||
resource: resource,
|
||||
size: file.preloadSize,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
}
|
||||
|
||||
resultResources[mediaId] = StoryPreloadInfo(
|
||||
peer: peerReference,
|
||||
storyId: itemAndPeer.item.id,
|
||||
media: EngineMedia(media),
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
}
|
||||
|
||||
return resultResources
|
||||
|
@ -6,6 +6,7 @@ import SwiftSignalKit
|
||||
import AccountContext
|
||||
import TelegramCore
|
||||
import Postbox
|
||||
import MediaResources
|
||||
|
||||
private struct StoryKey: Hashable {
|
||||
var peerId: EnginePeer.Id
|
||||
@ -396,7 +397,7 @@ public final class StoryContentContextImpl: StoryContentContext {
|
||||
private var requestedStoryKeys = Set<StoryKey>()
|
||||
private var requestStoryDisposables = DisposableSet()
|
||||
|
||||
private var preloadStoryResourceDisposables: [MediaResourceId: Disposable] = [:]
|
||||
private var preloadStoryResourceDisposables: [MediaId: Disposable] = [:]
|
||||
private var pollStoryMetadataDisposables = DisposableSet()
|
||||
|
||||
private var singlePeerListContext: PeerExpiringStoryListContext?
|
||||
@ -761,55 +762,30 @@ public final class StoryContentContextImpl: StoryContentContext {
|
||||
}
|
||||
|
||||
var nextPriority = 0
|
||||
var resultResources: [EngineMediaResource.Id: StoryPreloadInfo] = [:]
|
||||
var resultResources: [EngineMedia.Id: StoryPreloadInfo] = [:]
|
||||
for i in 0 ..< min(possibleItems.count, 3) {
|
||||
let peer = possibleItems[i].0
|
||||
let item = possibleItems[i].1
|
||||
if let peerReference = PeerReference(peer._asPeer()) {
|
||||
if let image = item.media._asMedia() as? TelegramMediaImage, let resource = image.representations.last?.resource {
|
||||
let resource = MediaResourceReference.media(media: .story(peer: peerReference, id: item.id, media: image), resource: resource)
|
||||
resultResources[EngineMediaResource.Id(resource.resource.id)] = StoryPreloadInfo(
|
||||
resource: resource,
|
||||
size: nil,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
} else if let file = item.media._asMedia() as? TelegramMediaFile {
|
||||
if let preview = file.previewRepresentations.last {
|
||||
let resource = MediaResourceReference.media(media: .story(peer: peerReference, id: item.id, media: file), resource: preview.resource)
|
||||
resultResources[EngineMediaResource.Id(resource.resource.id)] = StoryPreloadInfo(
|
||||
resource: resource,
|
||||
size: nil,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
}
|
||||
|
||||
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: file.preloadSize,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
}
|
||||
if let peerReference = PeerReference(peer._asPeer()), let mediaId = item.media.id {
|
||||
resultResources[mediaId] = StoryPreloadInfo(
|
||||
peer: peerReference,
|
||||
storyId: item.id,
|
||||
media: item.media,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
}
|
||||
}
|
||||
|
||||
var validIds: [MediaResourceId] = []
|
||||
for (_, info) in resultResources.sorted(by: { $0.value.priority < $1.value.priority }) {
|
||||
let resource = info.resource
|
||||
validIds.append(resource.resource.id)
|
||||
if self.preloadStoryResourceDisposables[resource.resource.id] == nil {
|
||||
var fetchRange: (Range<Int64>, MediaBoxFetchPriority)?
|
||||
if let size = info.size {
|
||||
fetchRange = (0 ..< Int64(size), .default)
|
||||
}
|
||||
self.preloadStoryResourceDisposables[resource.resource.id] = fetchedMediaResource(mediaBox: self.context.account.postbox.mediaBox, userLocation: .other, userContentType: .other, reference: resource, range: fetchRange).start()
|
||||
var validIds: [EngineMedia.Id] = []
|
||||
for (id, info) in resultResources.sorted(by: { $0.value.priority < $1.value.priority }) {
|
||||
validIds.append(id)
|
||||
if self.preloadStoryResourceDisposables[id] == nil {
|
||||
self.preloadStoryResourceDisposables[id] = preloadStoryMedia(context: context, peer: info.peer, storyId: info.storyId, media: info.media).start()
|
||||
}
|
||||
}
|
||||
|
||||
var removeIds: [MediaResourceId] = []
|
||||
var removeIds: [EngineMedia.Id] = []
|
||||
for (id, disposable) in self.preloadStoryResourceDisposables {
|
||||
if !validIds.contains(id) {
|
||||
removeIds.append(id)
|
||||
@ -1075,7 +1051,7 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
|
||||
private var focusedId: Int32?
|
||||
private var focusedIdUpdated = Promise<Void>(Void())
|
||||
|
||||
private var preloadStoryResourceDisposables: [MediaResourceId: Disposable] = [:]
|
||||
private var preloadStoryResourceDisposables: [EngineMedia.Id: Disposable] = [:]
|
||||
private var pollStoryMetadataDisposables = DisposableSet()
|
||||
|
||||
public init(context: AccountContext, peerId: EnginePeer.Id, listContext: PeerStoryListContext, initialId: Int32?) {
|
||||
@ -1184,7 +1160,7 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
|
||||
self.statePromise.set(.single(stateValue))
|
||||
self.updatedPromise.set(.single(Void()))
|
||||
|
||||
var resultResources: [EngineMediaResource.Id: StoryPreloadInfo] = [:]
|
||||
var resultResources: [EngineMedia.Id: StoryPreloadInfo] = [:]
|
||||
var pollItems: [StoryKey] = []
|
||||
|
||||
if let focusedIndex, let slice = stateValue.slice {
|
||||
@ -1207,52 +1183,29 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
|
||||
for i in 0 ..< min(possibleItems.count, 3) {
|
||||
let peer = possibleItems[i].0
|
||||
let item = possibleItems[i].1
|
||||
if let peerReference = PeerReference(peer._asPeer()) {
|
||||
if let image = item.media._asMedia() as? TelegramMediaImage, let resource = image.representations.last?.resource {
|
||||
let resource = MediaResourceReference.media(media: .story(peer: peerReference, id: item.id, media: image), resource: resource)
|
||||
resultResources[EngineMediaResource.Id(resource.resource.id)] = StoryPreloadInfo(
|
||||
resource: resource,
|
||||
size: nil,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
} else if let file = item.media._asMedia() as? TelegramMediaFile {
|
||||
if let preview = file.previewRepresentations.last {
|
||||
let resource = MediaResourceReference.media(media: .story(peer: peerReference, id: item.id, media: file), resource: preview.resource)
|
||||
resultResources[EngineMediaResource.Id(resource.resource.id)] = StoryPreloadInfo(
|
||||
resource: resource,
|
||||
size: nil,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
}
|
||||
|
||||
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: file.preloadSize,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
}
|
||||
if let peerReference = PeerReference(peer._asPeer()), let mediaId = item.media.id {
|
||||
resultResources[mediaId] = StoryPreloadInfo(
|
||||
peer: peerReference,
|
||||
storyId: item.id,
|
||||
media: item.media,
|
||||
priority: .top(position: nextPriority)
|
||||
)
|
||||
nextPriority += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var validIds: [MediaResourceId] = []
|
||||
var validIds: [EngineMedia.Id] = []
|
||||
for (_, info) in resultResources.sorted(by: { $0.value.priority < $1.value.priority }) {
|
||||
let resource = info.resource
|
||||
validIds.append(resource.resource.id)
|
||||
if self.preloadStoryResourceDisposables[resource.resource.id] == nil {
|
||||
var fetchRange: (Range<Int64>, MediaBoxFetchPriority)?
|
||||
if let size = info.size {
|
||||
fetchRange = (0 ..< Int64(size), .default)
|
||||
if let mediaId = info.media.id {
|
||||
validIds.append(mediaId)
|
||||
if self.preloadStoryResourceDisposables[mediaId] == nil {
|
||||
self.preloadStoryResourceDisposables[mediaId] = preloadStoryMedia(context: context, peer: info.peer, storyId: info.storyId, media: info.media).start()
|
||||
}
|
||||
self.preloadStoryResourceDisposables[resource.resource.id] = fetchedMediaResource(mediaBox: self.context.account.postbox.mediaBox, userLocation: .other, userContentType: .other, reference: resource, range: fetchRange).start()
|
||||
}
|
||||
}
|
||||
|
||||
var removeIds: [MediaResourceId] = []
|
||||
var removeIds: [EngineMedia.Id] = []
|
||||
for (id, disposable) in self.preloadStoryResourceDisposables {
|
||||
if !validIds.contains(id) {
|
||||
removeIds.append(id)
|
||||
@ -1330,3 +1283,40 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
|
||||
let _ = self.context.engine.messages.markStoryAsSeen(peerId: id.peerId, id: id.id, asPinned: true).start()
|
||||
}
|
||||
}
|
||||
|
||||
public func preloadStoryMedia(context: AccountContext, peer: PeerReference, storyId: Int32, media: EngineMedia) -> Signal<Never, NoError> {
|
||||
var signals: [Signal<Never, NoError>] = []
|
||||
|
||||
switch media {
|
||||
case let .image(image):
|
||||
if let representation = largestImageRepresentation(image.representations) {
|
||||
signals.append(fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .peer(peer.id), userContentType: .other, reference: .media(media: .story(peer: peer, id: storyId, media: media._asMedia()), resource: representation.resource), range: nil)
|
||||
|> ignoreValues
|
||||
|> `catch` { _ -> Signal<Never, NoError> in
|
||||
return .complete()
|
||||
})
|
||||
}
|
||||
case let .file(file):
|
||||
var fetchRange: (Range<Int64>, MediaBoxFetchPriority)?
|
||||
for attribute in file.attributes {
|
||||
if case let .Video(_, _, _, preloadSize) = attribute {
|
||||
if let preloadSize {
|
||||
fetchRange = (0 ..< Int64(preloadSize), .default)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
signals.append(fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, userLocation: .peer(peer.id), userContentType: .other, reference: .media(media: .story(peer: peer, id: storyId, media: media._asMedia()), resource: file.resource), range: fetchRange)
|
||||
|> ignoreValues
|
||||
|> `catch` { _ -> Signal<Never, NoError> in
|
||||
return .complete()
|
||||
})
|
||||
signals.append(context.account.postbox.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedVideoFirstFrameRepresentation(), complete: true, fetch: true, attemptSynchronously: false)
|
||||
|> ignoreValues)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return combineLatest(signals) |> ignoreValues
|
||||
}
|
||||
|
@ -693,7 +693,7 @@ public final class StoryPeerListComponent: Component {
|
||||
expandBoundsFraction = 0.0
|
||||
}
|
||||
|
||||
let blurRadius: CGFloat = collapsedState.sideAlphaFraction * 0.0 + (1.0 - collapsedState.sideAlphaFraction) * 14.0
|
||||
/*let blurRadius: CGFloat = collapsedState.sideAlphaFraction * 0.0 + (1.0 - collapsedState.sideAlphaFraction) * 14.0
|
||||
if blurRadius == 0.0 {
|
||||
self.sharedBlurEffect = nil
|
||||
} else {
|
||||
@ -706,7 +706,7 @@ public final class StoryPeerListComponent: Component {
|
||||
self.sharedBlurEffect = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
var targetCollapsedContentWidth: CGFloat = 0.0
|
||||
if collapsedItemCount > 0 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user