Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2020-07-16 17:07:25 +03:00
commit f7061fde4f
5 changed files with 75 additions and 32 deletions

View File

@ -256,6 +256,7 @@ public final class AvatarNode: ASDisplayNode {
var iconColor = theme.chatList.unpinnedArchiveAvatarColor.foregroundColor
var backgroundColor = theme.chatList.unpinnedArchiveAvatarColor.backgroundColors.topColor
let animationBackgroundNode = ASImageNode()
animationBackgroundNode.isUserInteractionEnabled = false
animationBackgroundNode.frame = self.imageNode.frame
if let overrideImage = self.overrideImage, case let .archivedChatsIcon(hiddenByDefault) = overrideImage {
let backgroundColors: (UIColor, UIColor)
@ -274,6 +275,7 @@ public final class AvatarNode: ASDisplayNode {
self.addSubnode(animationBackgroundNode)
let animationNode = AnimationNode(animation: "anim_archiveAvatar", colors: ["box1.box1.Fill 1": iconColor, "box3.box3.Fill 1": iconColor, "box2.box2.Fill 1": backgroundColor], scale: 0.1653828)
animationNode.isUserInteractionEnabled = false
animationNode.completion = { [weak animationBackgroundNode, weak self] in
self?.imageNode.isHidden = false
animationBackgroundNode?.removeFromSupernode()
@ -344,6 +346,7 @@ public final class AvatarNode: ASDisplayNode {
if self.editOverlayNode == nil {
let editOverlayNode = AvatarEditOverlayNode()
editOverlayNode.frame = self.imageNode.frame
editOverlayNode.isUserInteractionEnabled = false
self.addSubnode(editOverlayNode)
self.editOverlayNode = editOverlayNode

View File

@ -296,11 +296,13 @@ public class ItemListAvatarAndNameInfoItemNode: ListViewItemNode, ItemListItemNo
self.avatarNode = AvatarNode(font: avatarFont)
self.updatingAvatarOverlay = ASImageNode()
self.updatingAvatarOverlay.isUserInteractionEnabled = false
self.updatingAvatarOverlay.displayWithoutProcessing = true
self.updatingAvatarOverlay.displaysAsynchronously = false
self.activityIndicator = ActivityIndicator(type: .custom(.white, 22.0, 1.0, false))
self.activityIndicator.isHidden = true
self.activityIndicator.isUserInteractionEnabled = false
self.nameNode = TextNode()
self.nameNode.isUserInteractionEnabled = false

View File

@ -287,6 +287,7 @@ final class FFMpegMediaFrameSourceContext: NSObject {
fileprivate var requestedDataOffset: Int?
fileprivate let fetchedDataDisposable = MetaDisposable()
fileprivate let keepDataDisposable = MetaDisposable()
fileprivate let fetchedFullDataDisposable = MetaDisposable()
fileprivate var requestedCompleteFetch = false
@ -294,6 +295,7 @@ final class FFMpegMediaFrameSourceContext: NSObject {
didSet {
self.fetchedDataDisposable.dispose()
self.fetchedFullDataDisposable.dispose()
self.keepDataDisposable.dispose()
}
}
@ -316,6 +318,7 @@ final class FFMpegMediaFrameSourceContext: NSObject {
self.fetchedDataDisposable.dispose()
self.fetchedFullDataDisposable.dispose()
self.keepDataDisposable.dispose()
}
func initializeState(postbox: Postbox, resourceReference: MediaResourceReference, tempFilePath: String?, streamable: Bool, video: Bool, preferSoftwareDecoding: Bool, fetchAutomatically: Bool, maximumFetchSize: Int?) {
@ -341,6 +344,10 @@ final class FFMpegMediaFrameSourceContext: NSObject {
}
}
if self.tempFilePath == nil {
self.keepDataDisposable.set(postbox.mediaBox.keepResource(id: resourceReference.resource.id).start())
}
if streamable {
if self.tempFilePath == nil {
self.fetchedDataDisposable.set(fetchedMediaResource(mediaBox: postbox.mediaBox, reference: resourceReference, range: (0 ..< Int(Int32.max), .elevated), statsCategory: self.statsCategory ?? .generic, preferBackgroundReferenceRevalidation: streamable).start())

View File

@ -132,6 +132,14 @@ public enum ResourceDataRequestOption {
case incremental(waitUntilFetchStatus: Bool)
}
private final class MediaBoxKeepResourceContext {
let subscribers = Bag<Void>()
var isEmpty: Bool {
return self.subscribers.isEmpty
}
}
public final class MediaBox {
public let basePath: String
@ -145,6 +153,7 @@ public final class MediaBox {
private var cachedRepresentationContexts: [CachedMediaResourceRepresentationKey: CachedMediaResourceRepresentationContext] = [:]
private var fileContexts: [WrappedMediaResourceId: MediaBoxFileContext] = [:]
private var keepResourceContexts: [WrappedMediaResourceId: MediaBoxKeepResourceContext] = [:]
private var wrappedFetchResource = Promise<(MediaResource, Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>>()
public var preFetchedResourcePath: (MediaResource) -> String? = { _ in return nil }
@ -204,6 +213,10 @@ public final class MediaBox {
return ResourceStorePaths(partial: "\(self.basePath)/\(fileNameForId(id))_partial", complete: "\(self.basePath)/\(fileNameForId(id))")
}
private func fileNamesForId(_ id: MediaResourceId) -> ResourceStorePaths {
return ResourceStorePaths(partial: "\(fileNameForId(id))_partial", complete: "\(fileNameForId(id))")
}
private func cachedRepresentationPathsForId(_ id: MediaResourceId, representation: CachedMediaResourceRepresentation) -> ResourceStorePaths {
let cacheString: String
switch representation.keepDuration {
@ -697,6 +710,38 @@ public final class MediaBox {
}
}
public func keepResource(id: MediaResourceId) -> Signal<Never, NoError> {
return Signal { subscriber in
let disposable = MetaDisposable()
let dataQueue = self.dataQueue
self.dataQueue.async {
let context: MediaBoxKeepResourceContext
if let current = self.keepResourceContexts[WrappedMediaResourceId(id)] {
context = current
} else {
context = MediaBoxKeepResourceContext()
self.keepResourceContexts[WrappedMediaResourceId(id)] = context
}
let index = context.subscribers.add(Void())
disposable.set(ActionDisposable { [weak self, weak context] in
dataQueue.async {
guard let strongSelf = self, let context = context, let currentContext = strongSelf.keepResourceContexts[WrappedMediaResourceId(id)], currentContext === context else {
return
}
currentContext.subscribers.remove(index)
if currentContext.isEmpty {
strongSelf.keepResourceContexts.removeValue(forKey: WrappedMediaResourceId(id))
}
}
})
}
return disposable
}
}
public func cancelInteractiveResourceFetch(_ resource: MediaResource) {
self.dataQueue.async {
if let (fileContext, releaseContext) = self.fileContext(for: resource) {
@ -991,7 +1036,20 @@ public final class MediaBox {
public func removeOtherCachedResources(paths: [String]) -> Signal<Void, NoError> {
return Signal { subscriber in
self.dataQueue.async {
for path in paths {
var keepPrefixes: [String] = []
for id in self.keepResourceContexts.keys {
let resourcePaths = self.fileNamesForId(id.id)
keepPrefixes.append(resourcePaths.partial)
keepPrefixes.append(resourcePaths.complete)
}
outer: for path in paths {
for prefix in keepPrefixes {
if path.starts(with: prefix) {
continue outer
}
}
unlink(self.basePath + "/" + path)
}
subscriber.putCompletion()
@ -1007,6 +1065,9 @@ public final class MediaBox {
if self.fileContexts[id] != nil {
continue
}
if self.keepResourceContexts[id] != nil {
continue
}
let paths = self.storePathsForId(id.id)
unlink(paths.complete)
unlink(paths.partial)
@ -1044,35 +1105,4 @@ public final class MediaBox {
return EmptyDisposable
}
}
public func clearFileContexts() -> Signal<Void, NoError> {
return Signal { subscriber in
self.dataQueue.async {
for (id, _) in self.fileContexts {
let paths = self.storePathsForId(id.id)
unlink(paths.complete)
unlink(paths.partial)
unlink(paths.partial + ".meta")
}
self.fileContexts.removeAll()
subscriber.putCompletion()
}
return EmptyDisposable
}
}
public func fileConxtets() -> Signal<[(partial: String, complete: String)], NoError> {
return Signal { subscriber in
self.dataQueue.async {
var result: [(partial: String, complete: String)] = []
for (id, _) in self.fileContexts {
let paths = self.storePathsForId(id.id)
result.append((partial: paths.partial, complete: paths.complete))
}
subscriber.putNext(result)
subscriber.putCompletion()
}
return EmptyDisposable
}
}
}

View File

@ -1307,6 +1307,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
strongSelf.hiddenPane?.removeFromSupernode()
strongSelf.hiddenListView?.removeFromSupernode()
strongSelf.isHidden = true
strongSelf.dismiss?()
}
})
}