mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-19 12:10:55 +00:00
no message
This commit is contained in:
parent
ec83f35663
commit
cc9ae629ec
@ -892,6 +892,24 @@ public final class PostboxDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func decodeAnyObjectForKey(_ key: StaticString, decoder: (PostboxDecoder) -> Any?) -> Any? {
|
||||||
|
if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) {
|
||||||
|
var typeHash: Int32 = 0
|
||||||
|
memcpy(&typeHash, self.buffer.memory + self.offset, 4)
|
||||||
|
self.offset += 4
|
||||||
|
|
||||||
|
var length: Int32 = 0
|
||||||
|
memcpy(&length, self.buffer.memory + self.offset, 4)
|
||||||
|
|
||||||
|
let innerDecoder = PostboxDecoder(buffer: ReadBuffer(memory: self.buffer.memory + (self.offset + 4), length: Int(length), freeWhenDone: false))
|
||||||
|
self.offset += 4 + Int(length)
|
||||||
|
|
||||||
|
return decoder(innerDecoder)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func decodeObjectForKeyThrowing(_ key: StaticString, decoder: (PostboxDecoder) throws -> Any) throws -> Any? {
|
public func decodeObjectForKeyThrowing(_ key: StaticString, decoder: (PostboxDecoder) throws -> Any) throws -> Any? {
|
||||||
if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) {
|
if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) {
|
||||||
var typeHash: Int32 = 0
|
var typeHash: Int32 = 0
|
||||||
|
@ -117,8 +117,8 @@ public final class MediaBox {
|
|||||||
|
|
||||||
private var fileContexts: [WrappedMediaResourceId: MediaBoxFileContext] = [:]
|
private var fileContexts: [WrappedMediaResourceId: MediaBoxFileContext] = [:]
|
||||||
|
|
||||||
private var wrappedFetchResource = Promise<(MediaResource, Signal<IndexSet, NoError>, MediaResourceFetchTag?) -> Signal<MediaResourceDataFetchResult, NoError>>()
|
private var wrappedFetchResource = Promise<(MediaResource, Signal<IndexSet, NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, NoError>>()
|
||||||
public var fetchResource: ((MediaResource, Signal<IndexSet, NoError>, MediaResourceFetchTag?) -> Signal<MediaResourceDataFetchResult, NoError>)? {
|
public var fetchResource: ((MediaResource, Signal<IndexSet, NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, NoError>)? {
|
||||||
didSet {
|
didSet {
|
||||||
if let fetchResource = self.fetchResource {
|
if let fetchResource = self.fetchResource {
|
||||||
wrappedFetchResource.set(.single(fetchResource))
|
wrappedFetchResource.set(.single(fetchResource))
|
||||||
@ -224,6 +224,7 @@ public final class MediaBox {
|
|||||||
let statusQueue = self.statusQueue
|
let statusQueue = self.statusQueue
|
||||||
self.dataQueue.async {
|
self.dataQueue.async {
|
||||||
if let fileContext = self.fileContext(for: resource) {
|
if let fileContext = self.fileContext(for: resource) {
|
||||||
|
//let reference = fileContext.addReference()
|
||||||
statusUpdateDisposable.set(fileContext.status(next: { [weak statusContext] value in
|
statusUpdateDisposable.set(fileContext.status(next: { [weak statusContext] value in
|
||||||
statusQueue.async {
|
statusQueue.async {
|
||||||
if let current = self.statusContexts[resourceId], current === statusContext, current.status != value {
|
if let current = self.statusContexts[resourceId], current === statusContext, current.status != value {
|
||||||
@ -454,7 +455,7 @@ public final class MediaBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchedResourceData(_ resource: MediaResource, in range: Range<Int>, tag: MediaResourceFetchTag?) -> Signal<Void, NoError> {
|
public func fetchedResourceData(_ resource: MediaResource, in range: Range<Int>, parameters: MediaResourceFetchParameters?) -> Signal<Void, NoError> {
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
let disposable = MetaDisposable()
|
let disposable = MetaDisposable()
|
||||||
|
|
||||||
@ -464,7 +465,7 @@ public final class MediaBox {
|
|||||||
let fetchResource = self.wrappedFetchResource.get()
|
let fetchResource = self.wrappedFetchResource.get()
|
||||||
let fetchedDisposable = fileContext?.fetched(range: Int32(range.lowerBound) ..< Int32(range.upperBound), fetch: { ranges in
|
let fetchedDisposable = fileContext?.fetched(range: Int32(range.lowerBound) ..< Int32(range.upperBound), fetch: { ranges in
|
||||||
return fetchResource |> mapToSignal { fetch in
|
return fetchResource |> mapToSignal { fetch in
|
||||||
return fetch(resource, ranges, tag)
|
return fetch(resource, ranges, parameters)
|
||||||
}
|
}
|
||||||
}, completed: {
|
}, completed: {
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
@ -536,7 +537,7 @@ public final class MediaBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchedResource(_ resource: MediaResource, tag: MediaResourceFetchTag?, implNext: Bool = false) -> Signal<FetchResourceSourceType, NoError> {
|
public func fetchedResource(_ resource: MediaResource, parameters: MediaResourceFetchParameters?, implNext: Bool = false) -> Signal<FetchResourceSourceType, NoError> {
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
let disposable = MetaDisposable()
|
let disposable = MetaDisposable()
|
||||||
|
|
||||||
@ -553,7 +554,7 @@ public final class MediaBox {
|
|||||||
let fetchResource = self.wrappedFetchResource.get()
|
let fetchResource = self.wrappedFetchResource.get()
|
||||||
let fetchedDisposable = fileContext.fetchedFullRange(fetch: { ranges in
|
let fetchedDisposable = fileContext.fetchedFullRange(fetch: { ranges in
|
||||||
return fetchResource |> mapToSignal { fetch in
|
return fetchResource |> mapToSignal { fetch in
|
||||||
return fetch(resource, ranges, tag)
|
return fetch(resource, ranges, parameters)
|
||||||
}
|
}
|
||||||
}, completed: {
|
}, completed: {
|
||||||
if implNext {
|
if implNext {
|
||||||
@ -563,318 +564,6 @@ public final class MediaBox {
|
|||||||
})
|
})
|
||||||
disposable.set(fetchedDisposable)
|
disposable.set(fetchedDisposable)
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
let currentSize = fileSize(paths.partial) ?? 0
|
|
||||||
let dataContext: ResourceDataContext
|
|
||||||
if let current = self.dataContexts[resourceId] {
|
|
||||||
dataContext = current
|
|
||||||
} else {
|
|
||||||
dataContext = ResourceDataContext(data: MediaResourceData(path: paths.partial, offset: 0, size: currentSize, complete: false))
|
|
||||||
self.dataContexts[resourceId] = dataContext
|
|
||||||
}
|
|
||||||
|
|
||||||
let index: Bag<Void>.Index = dataContext.fetchSubscribers.add(Void())
|
|
||||||
|
|
||||||
if dataContext.fetchDisposable == nil {
|
|
||||||
let status: MediaResourceStatus
|
|
||||||
if let resourceSize = resource.size {
|
|
||||||
status = .Fetching(isActive: true, progress: Float(currentSize) / Float(resourceSize))
|
|
||||||
} else {
|
|
||||||
status = .Fetching(isActive: true, progress: 0.0)
|
|
||||||
}
|
|
||||||
self.statusQueue.async {
|
|
||||||
if let statusContext = self.statusContexts[resourceId] {
|
|
||||||
statusContext.status = status
|
|
||||||
for subscriber in statusContext.subscribers.copyItems() {
|
|
||||||
subscriber(status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var offset = currentSize
|
|
||||||
let file = Atomic<ManagedFile?>(value: nil)
|
|
||||||
let dataQueue = self.dataQueue
|
|
||||||
dataContext.fetchDisposable = ((self.wrappedFetchResource.get() |> take(1) |> mapToSignal { fetch -> Signal<MediaResourceDataFetchResult, NoError> in
|
|
||||||
var ranges = IndexSet()
|
|
||||||
ranges.insert(integersIn: currentSize ..< Int.max)
|
|
||||||
return fetch(resource, .single(ranges), tag)
|
|
||||||
}) |> afterDisposed {
|
|
||||||
dataQueue.async {
|
|
||||||
let _ = file.modify { current in
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start(next: { resultOption in
|
|
||||||
self.dataQueue.async {
|
|
||||||
let _ = self.ensureDirectoryCreated
|
|
||||||
|
|
||||||
switch resultOption {
|
|
||||||
case .resourceSizeUpdated:
|
|
||||||
break
|
|
||||||
case let .dataPart(_, data, dataRange, complete):
|
|
||||||
var currentFile: ManagedFile?
|
|
||||||
let _ = file.modify { current in
|
|
||||||
if let current = current {
|
|
||||||
currentFile = current
|
|
||||||
return current
|
|
||||||
} else {
|
|
||||||
let newFile = ManagedFile(queue: self.dataQueue, path: paths.partial, mode: .append)
|
|
||||||
currentFile = newFile
|
|
||||||
return newFile
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let currentFile = currentFile {
|
|
||||||
if !dataRange.isEmpty {
|
|
||||||
let writeResult = data.withUnsafeBytes { bytes -> Int in
|
|
||||||
return currentFile.write(bytes.advanced(by: dataRange.lowerBound), count: dataRange.count)
|
|
||||||
}
|
|
||||||
if writeResult != dataRange.count {
|
|
||||||
assertionFailure("write error \(errno)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += dataRange.count
|
|
||||||
let updatedSize = offset
|
|
||||||
|
|
||||||
let updatedData: MediaResourceData
|
|
||||||
if complete {
|
|
||||||
let linkResult = link(paths.partial, paths.complete)
|
|
||||||
//assert(linkResult == 0)
|
|
||||||
updatedData = MediaResourceData(path: paths.complete, offset: 0, size: updatedSize, complete: true)
|
|
||||||
} else {
|
|
||||||
updatedData = MediaResourceData(path: paths.partial, offset: 0, size: updatedSize, complete: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
dataContext.data = updatedData
|
|
||||||
|
|
||||||
let hadProcessedFetch = dataContext.processedFetch
|
|
||||||
dataContext.processedFetch = true
|
|
||||||
|
|
||||||
for (_, subscriber) in dataContext.progresiveDataSubscribers.copyItems() {
|
|
||||||
subscriber(updatedData)
|
|
||||||
}
|
|
||||||
|
|
||||||
if updatedData.complete {
|
|
||||||
for (_, subscriber) in dataContext.completeDataSubscribers.copyItems() {
|
|
||||||
subscriber(updatedData)
|
|
||||||
}
|
|
||||||
} else if !hadProcessedFetch {
|
|
||||||
for (waitUntilFetchStatus, subscriber) in dataContext.completeDataSubscribers.copyItems() {
|
|
||||||
if waitUntilFetchStatus {
|
|
||||||
subscriber(updatedData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let status: MediaResourceStatus
|
|
||||||
if updatedData.complete {
|
|
||||||
status = .Local
|
|
||||||
if implNext {
|
|
||||||
subscriber.putNext(.remote)
|
|
||||||
}
|
|
||||||
subscriber.putCompletion()
|
|
||||||
} else {
|
|
||||||
if let resourceSize = resource.size {
|
|
||||||
status = .Fetching(isActive: true, progress: Float(updatedSize) / Float(resourceSize))
|
|
||||||
} else {
|
|
||||||
status = .Fetching(isActive: true, progress: 0.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.statusQueue.async {
|
|
||||||
if let statusContext = self.statusContexts[resourceId] {
|
|
||||||
statusContext.status = status
|
|
||||||
for subscriber in statusContext.subscribers.copyItems() {
|
|
||||||
subscriber(status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case let .replaceHeader(data, dataRange):
|
|
||||||
let currentFile = ManagedFile(queue: self.dataQueue, path: paths.partial, mode: .readwrite)
|
|
||||||
let _ = file.modify { _ in
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if let currentFile = currentFile {
|
|
||||||
if !dataRange.isEmpty {
|
|
||||||
currentFile.seek(position: 0)
|
|
||||||
let writeResult = data.withUnsafeBytes { bytes -> Int in
|
|
||||||
return currentFile.write(bytes.advanced(by: dataRange.lowerBound), count: dataRange.count)
|
|
||||||
}
|
|
||||||
currentFile.seek(position: Int64(offset))
|
|
||||||
if writeResult != dataRange.count {
|
|
||||||
assertionFailure("write error \(errno)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case .reset:
|
|
||||||
var currentFile: ManagedFile?
|
|
||||||
let _ = file.modify { current in
|
|
||||||
if let current = current {
|
|
||||||
currentFile = current
|
|
||||||
return current
|
|
||||||
} else {
|
|
||||||
let newFile = ManagedFile(queue: self.dataQueue, path: paths.partial, mode: .append)
|
|
||||||
currentFile = newFile
|
|
||||||
return newFile
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let currentFile = currentFile {
|
|
||||||
currentFile.truncate(count: 0)
|
|
||||||
currentFile.seek(position: 0)
|
|
||||||
} else {
|
|
||||||
assertionFailure()
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = 0
|
|
||||||
let updatedSize = offset
|
|
||||||
|
|
||||||
let updatedData: MediaResourceData
|
|
||||||
updatedData = MediaResourceData(path: paths.partial, offset: 0, size: updatedSize, complete: false)
|
|
||||||
|
|
||||||
dataContext.data = updatedData
|
|
||||||
|
|
||||||
let hadProcessedFetch = dataContext.processedFetch
|
|
||||||
dataContext.processedFetch = true
|
|
||||||
|
|
||||||
for (_, subscriber) in dataContext.progresiveDataSubscribers.copyItems() {
|
|
||||||
subscriber(updatedData)
|
|
||||||
}
|
|
||||||
|
|
||||||
if updatedData.complete {
|
|
||||||
for (_, subscriber) in dataContext.completeDataSubscribers.copyItems() {
|
|
||||||
subscriber(updatedData)
|
|
||||||
}
|
|
||||||
} else if !hadProcessedFetch {
|
|
||||||
for (waitUntilFetchStatus, subscriber) in dataContext.completeDataSubscribers.copyItems() {
|
|
||||||
if waitUntilFetchStatus {
|
|
||||||
subscriber(updatedData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let status: MediaResourceStatus
|
|
||||||
if updatedData.complete {
|
|
||||||
status = .Local
|
|
||||||
} else {
|
|
||||||
if let resourceSize = resource.size {
|
|
||||||
status = .Fetching(isActive: true, progress: Float(updatedSize) / Float(resourceSize))
|
|
||||||
} else {
|
|
||||||
status = .Fetching(isActive: true, progress: 0.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.statusQueue.async {
|
|
||||||
if let statusContext = self.statusContexts[resourceId] {
|
|
||||||
statusContext.status = status
|
|
||||||
for subscriber in statusContext.subscribers.copyItems() {
|
|
||||||
subscriber(status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case let .moveLocalFile(tempPath):
|
|
||||||
let _ = file.modify { _ in
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
unlink(paths.partial)
|
|
||||||
do {
|
|
||||||
try FileManager.default.moveItem(atPath: tempPath, toPath: paths.partial)
|
|
||||||
} catch {
|
|
||||||
assertionFailure()
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let offset = fileSize(paths.partial) else {
|
|
||||||
assertionFailure()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let updatedSize = offset
|
|
||||||
|
|
||||||
let updatedData: MediaResourceData
|
|
||||||
let linkResult = link(paths.partial, paths.complete)
|
|
||||||
assert(linkResult == 0)
|
|
||||||
updatedData = MediaResourceData(path: paths.complete, offset: 0, size: updatedSize, complete: true)
|
|
||||||
|
|
||||||
dataContext.data = updatedData
|
|
||||||
|
|
||||||
let hadProcessedFetch = dataContext.processedFetch
|
|
||||||
dataContext.processedFetch = true
|
|
||||||
|
|
||||||
for (_, subscriber) in dataContext.progresiveDataSubscribers.copyItems() {
|
|
||||||
subscriber(updatedData)
|
|
||||||
}
|
|
||||||
|
|
||||||
if updatedData.complete {
|
|
||||||
for (_, subscriber) in dataContext.completeDataSubscribers.copyItems() {
|
|
||||||
subscriber(updatedData)
|
|
||||||
}
|
|
||||||
} else if !hadProcessedFetch {
|
|
||||||
for (waitUntilFetchStatus, subscriber) in dataContext.completeDataSubscribers.copyItems() {
|
|
||||||
if waitUntilFetchStatus {
|
|
||||||
subscriber(updatedData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let status: MediaResourceStatus
|
|
||||||
if updatedData.complete {
|
|
||||||
status = .Local
|
|
||||||
} else {
|
|
||||||
if let resourceSize = resource.size {
|
|
||||||
status = .Fetching(isActive: true, progress: Float(updatedSize) / Float(resourceSize))
|
|
||||||
} else {
|
|
||||||
status = .Fetching(isActive: true, progress: 0.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.statusQueue.async {
|
|
||||||
if let statusContext = self.statusContexts[resourceId] {
|
|
||||||
statusContext.status = status
|
|
||||||
for subscriber in statusContext.subscribers.copyItems() {
|
|
||||||
subscriber(status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
disposable.set(ActionDisposable {
|
|
||||||
self.dataQueue.async {
|
|
||||||
if let dataContext = self.dataContexts[resourceId] {
|
|
||||||
dataContext.fetchSubscribers.remove(index)
|
|
||||||
|
|
||||||
if dataContext.fetchSubscribers.isEmpty {
|
|
||||||
dataContext.fetchDisposable?.dispose()
|
|
||||||
dataContext.fetchDisposable = nil
|
|
||||||
|
|
||||||
let status: MediaResourceStatus
|
|
||||||
if dataContext.data.complete {
|
|
||||||
status = .Local
|
|
||||||
} else {
|
|
||||||
status = .Remote
|
|
||||||
}
|
|
||||||
|
|
||||||
self.statusQueue.async {
|
|
||||||
if let statusContext = self.statusContexts[resourceId], statusContext.status != status {
|
|
||||||
statusContext.status = status
|
|
||||||
for subscriber in statusContext.subscribers.copyItems() {
|
|
||||||
subscriber(status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if dataContext.completeDataSubscribers.isEmpty && dataContext.progresiveDataSubscribers.isEmpty && dataContext.fetchSubscribers.isEmpty {
|
|
||||||
self.dataContexts.removeValue(forKey: resourceId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -887,27 +576,6 @@ public final class MediaBox {
|
|||||||
if let fileContext = self.fileContext(for: resource) {
|
if let fileContext = self.fileContext(for: resource) {
|
||||||
fileContext.cancelFullRangeFetches()
|
fileContext.cancelFullRangeFetches()
|
||||||
}
|
}
|
||||||
/*let resourceId = WrappedMediaResourceId(resource.id)
|
|
||||||
if let dataContext = self.dataContexts[resourceId], dataContext.fetchDisposable != nil {
|
|
||||||
dataContext.fetchDisposable?.dispose()
|
|
||||||
dataContext.fetchDisposable = nil
|
|
||||||
|
|
||||||
let status: MediaResourceStatus
|
|
||||||
if dataContext.data.complete {
|
|
||||||
status = .Local
|
|
||||||
} else {
|
|
||||||
status = .Remote
|
|
||||||
}
|
|
||||||
|
|
||||||
self.statusQueue.async {
|
|
||||||
if let statusContext = self.statusContexts[resourceId], statusContext.status != status {
|
|
||||||
statusContext.status = status
|
|
||||||
for subscriber in statusContext.subscribers.copyItems() {
|
|
||||||
subscriber(status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ final class MediaBoxPartialFile {
|
|||||||
}
|
}
|
||||||
self.statusRequests.removeAll()
|
self.statusRequests.removeAll()
|
||||||
|
|
||||||
self.completed(self.fileMap.sum)
|
self.completed(Int32(size))
|
||||||
} else {
|
} else {
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
}
|
}
|
||||||
@ -740,6 +740,12 @@ final class MediaBoxFileContext {
|
|||||||
|
|
||||||
private var content: MediaBoxFileContent
|
private var content: MediaBoxFileContent
|
||||||
|
|
||||||
|
private let references = CounterBag()
|
||||||
|
|
||||||
|
var isEmpty: Bool {
|
||||||
|
return self.references.isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
init?(queue: Queue, path: String, partialPath: String) {
|
init?(queue: Queue, path: String, partialPath: String) {
|
||||||
assert(queue.isCurrent())
|
assert(queue.isCurrent())
|
||||||
|
|
||||||
@ -770,6 +776,14 @@ final class MediaBoxFileContext {
|
|||||||
assert(self.queue.isCurrent())
|
assert(self.queue.isCurrent())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addReference() -> Int {
|
||||||
|
return self.references.add()
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeReference(_ index: Int) {
|
||||||
|
self.references.remove(index)
|
||||||
|
}
|
||||||
|
|
||||||
func data(range: Range<Int32>, waitUntilAfterInitialFetch: Bool, next: @escaping (MediaResourceData) -> Void) -> Disposable {
|
func data(range: Range<Int32>, waitUntilAfterInitialFetch: Bool, next: @escaping (MediaResourceData) -> Void) -> Disposable {
|
||||||
switch self.content {
|
switch self.content {
|
||||||
case let .complete(path, size):
|
case let .complete(path, size):
|
||||||
|
@ -54,3 +54,16 @@ public protocol CachedMediaResourceRepresentation {
|
|||||||
|
|
||||||
public protocol MediaResourceFetchTag {
|
public protocol MediaResourceFetchTag {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public protocol MediaResourceFetchInfo {
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct MediaResourceFetchParameters {
|
||||||
|
public let tag: MediaResourceFetchTag?
|
||||||
|
public let info: MediaResourceFetchInfo?
|
||||||
|
|
||||||
|
public init(tag: MediaResourceFetchTag?, info: MediaResourceFetchInfo?) {
|
||||||
|
self.tag = tag
|
||||||
|
self.info = info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -572,7 +572,7 @@ final class MessageHistoryTable: Table {
|
|||||||
processIndexOperationsCommitAccumulatedRemoveIndices(peerId: peerId, accumulatedRemoveIndices: &accumulatedRemoveIndices, updatedCombinedState: &updatedCombinedState, invalidateReadState: &invalidateReadState, unsentMessageOperations: &unsentMessageOperations, outputOperations: &outputOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations)
|
processIndexOperationsCommitAccumulatedRemoveIndices(peerId: peerId, accumulatedRemoveIndices: &accumulatedRemoveIndices, updatedCombinedState: &updatedCombinedState, invalidateReadState: &invalidateReadState, unsentMessageOperations: &unsentMessageOperations, outputOperations: &outputOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations)
|
||||||
|
|
||||||
var updatedGroupInfos: [MessageId: MessageGroupInfo] = [:]
|
var updatedGroupInfos: [MessageId: MessageGroupInfo] = [:]
|
||||||
if let (message, previousTags) = self.justUpdate(index, message: storeMessage, sharedKey: sharedKey, sharedBuffer: sharedBuffer, sharedEncoder: sharedEncoder, unsentMessageOperations: &unsentMessageOperations, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, updatedGroupInfos: &updatedGroupInfos, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations) {
|
if let (message, previousTags) = self.justUpdate(index, message: storeMessage, sharedKey: sharedKey, sharedBuffer: sharedBuffer, sharedEncoder: sharedEncoder, unsentMessageOperations: &unsentMessageOperations, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, updatedGroupInfos: &updatedGroupInfos, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations, updatedMedia: &updatedMedia) {
|
||||||
outputOperations.append(.Remove([(index, true, previousTags)]))
|
outputOperations.append(.Remove([(index, true, previousTags)]))
|
||||||
outputOperations.append(.InsertMessage(message))
|
outputOperations.append(.InsertMessage(message))
|
||||||
if !updatedGroupInfos.isEmpty {
|
if !updatedGroupInfos.isEmpty {
|
||||||
@ -591,7 +591,7 @@ final class MessageHistoryTable: Table {
|
|||||||
processIndexOperationsCommitAccumulatedRemoveIndices(peerId: peerId, accumulatedRemoveIndices: &accumulatedRemoveIndices, updatedCombinedState: &updatedCombinedState, invalidateReadState: &invalidateReadState, unsentMessageOperations: &unsentMessageOperations, outputOperations: &outputOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations)
|
processIndexOperationsCommitAccumulatedRemoveIndices(peerId: peerId, accumulatedRemoveIndices: &accumulatedRemoveIndices, updatedCombinedState: &updatedCombinedState, invalidateReadState: &invalidateReadState, unsentMessageOperations: &unsentMessageOperations, outputOperations: &outputOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations)
|
||||||
|
|
||||||
var updatedGroupInfos: [MessageId: MessageGroupInfo] = [:]
|
var updatedGroupInfos: [MessageId: MessageGroupInfo] = [:]
|
||||||
let tagsAndGlobalTags = self.justUpdateTimestamp(index, timestamp: timestamp, unsentMessageOperations: &unsentMessageOperations, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, updatedGroupInfos: &updatedGroupInfos, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations)
|
let tagsAndGlobalTags = self.justUpdateTimestamp(index, timestamp: timestamp, unsentMessageOperations: &unsentMessageOperations, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, updatedGroupInfos: &updatedGroupInfos, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations, updatedMedia: &updatedMedia)
|
||||||
outputOperations.append(.UpdateTimestamp(index, timestamp))
|
outputOperations.append(.UpdateTimestamp(index, timestamp))
|
||||||
if !updatedGroupInfos.isEmpty {
|
if !updatedGroupInfos.isEmpty {
|
||||||
outputOperations.append(.UpdateGroupInfos(updatedGroupInfos))
|
outputOperations.append(.UpdateGroupInfos(updatedGroupInfos))
|
||||||
@ -1628,8 +1628,10 @@ final class MessageHistoryTable: Table {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private func justUpdate(_ index: MessageIndex, message: InternalStoreMessage, sharedKey: ValueBoxKey, sharedBuffer: WriteBuffer, sharedEncoder: PostboxEncoder, unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], updatedGroupInfos: inout [MessageId: MessageGroupInfo], groupFeedOperations: inout [PeerGroupId : [GroupFeedIndexOperation]], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation]) -> (IntermediateMessage, MessageTags)? {
|
private func justUpdate(_ index: MessageIndex, message: InternalStoreMessage, sharedKey: ValueBoxKey, sharedBuffer: WriteBuffer, sharedEncoder: PostboxEncoder, unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], updatedGroupInfos: inout [MessageId: MessageGroupInfo], groupFeedOperations: inout [PeerGroupId : [GroupFeedIndexOperation]], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation], updatedMedia: inout [MediaId: Media?]) -> (IntermediateMessage, MessageTags)? {
|
||||||
if let previousMessage = self.getMessage(index) {
|
if let previousMessage = self.getMessage(index) {
|
||||||
|
var mediaToUpdate: [Media] = []
|
||||||
|
|
||||||
var previousEmbeddedMediaWithIds: [(MediaId, Media)] = []
|
var previousEmbeddedMediaWithIds: [(MediaId, Media)] = []
|
||||||
if previousMessage.embeddedMediaData.length > 4 {
|
if previousMessage.embeddedMediaData.length > 4 {
|
||||||
var embeddedMediaCount: Int32 = 0
|
var embeddedMediaCount: Int32 = 0
|
||||||
@ -1898,6 +1900,9 @@ final class MessageHistoryTable: Table {
|
|||||||
embeddedMedia.append(media)
|
embeddedMedia.append(media)
|
||||||
case .Reference:
|
case .Reference:
|
||||||
referencedMedia.append(mediaId)
|
referencedMedia.append(mediaId)
|
||||||
|
if let currentMedia = self.messageMediaTable.get(mediaId, embedded: { _, _ in nil }), !currentMedia.isEqual(media) {
|
||||||
|
mediaToUpdate.append(media)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
embeddedMedia.append(media)
|
embeddedMedia.append(media)
|
||||||
@ -1942,6 +1947,13 @@ final class MessageHistoryTable: Table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for media in mediaToUpdate {
|
||||||
|
if let id = media.id {
|
||||||
|
var operationsByPeerId: [PeerId: [MessageHistoryOperation]] = [:]
|
||||||
|
self.updateMedia(id, media: media, operationsByPeerId: &operationsByPeerId, updatedMedia: &updatedMedia)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
@ -1962,7 +1974,7 @@ final class MessageHistoryTable: Table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func justUpdateTimestamp(_ index: MessageIndex, timestamp: Int32, unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], updatedGroupInfos: inout [MessageId: MessageGroupInfo], groupFeedOperations: inout [PeerGroupId : [GroupFeedIndexOperation]], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation]) -> (MessageTags, GlobalMessageTags)? {
|
private func justUpdateTimestamp(_ index: MessageIndex, timestamp: Int32, unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], updatedGroupInfos: inout [MessageId: MessageGroupInfo], groupFeedOperations: inout [PeerGroupId : [GroupFeedIndexOperation]], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation], updatedMedia: inout [MediaId: Media?]) -> (MessageTags, GlobalMessageTags)? {
|
||||||
if let previousMessage = self.getMessage(index) {
|
if let previousMessage = self.getMessage(index) {
|
||||||
var storeForwardInfo: StoreMessageForwardInfo?
|
var storeForwardInfo: StoreMessageForwardInfo?
|
||||||
if let forwardInfo = previousMessage.forwardInfo {
|
if let forwardInfo = previousMessage.forwardInfo {
|
||||||
@ -2010,7 +2022,7 @@ final class MessageHistoryTable: Table {
|
|||||||
|
|
||||||
let updatedIndex = MessageIndex(id: index.id, timestamp: timestamp)
|
let updatedIndex = MessageIndex(id: index.id, timestamp: timestamp)
|
||||||
|
|
||||||
let _ = self.justUpdate(index, message: InternalStoreMessage(id: previousMessage.id, timestamp: timestamp, globallyUniqueId: previousMessage.globallyUniqueId, groupingKey: previousMessage.groupingKey, flags: StoreMessageFlags(previousMessage.flags), tags: previousMessage.tags, globalTags: previousMessage.globalTags, localTags: previousMessage.localTags, forwardInfo: storeForwardInfo, authorId: previousMessage.authorId, text: previousMessage.text, attributes: parsedAttributes, media: parsedMedia), sharedKey: self.key(updatedIndex), sharedBuffer: WriteBuffer(), sharedEncoder: PostboxEncoder(), unsentMessageOperations: &unsentMessageOperations, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, updatedGroupInfos: &updatedGroupInfos, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations)
|
let _ = self.justUpdate(index, message: InternalStoreMessage(id: previousMessage.id, timestamp: timestamp, globallyUniqueId: previousMessage.globallyUniqueId, groupingKey: previousMessage.groupingKey, flags: StoreMessageFlags(previousMessage.flags), tags: previousMessage.tags, globalTags: previousMessage.globalTags, localTags: previousMessage.localTags, forwardInfo: storeForwardInfo, authorId: previousMessage.authorId, text: previousMessage.text, attributes: parsedAttributes, media: parsedMedia), sharedKey: self.key(updatedIndex), sharedBuffer: WriteBuffer(), sharedEncoder: PostboxEncoder(), unsentMessageOperations: &unsentMessageOperations, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, updatedGroupInfos: &updatedGroupInfos, groupFeedOperations: &groupFeedOperations, localTagsOperations: &localTagsOperations, updatedMedia: &updatedMedia)
|
||||||
return (previousMessage.tags, previousMessage.globalTags)
|
return (previousMessage.tags, previousMessage.globalTags)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user