Refactoring

This commit is contained in:
Ali 2021-09-24 11:59:21 +03:00
parent 54841cc6fb
commit 7140c69dbf
52 changed files with 421 additions and 502 deletions

View File

@ -1317,7 +1317,7 @@ private func mapPeersToFriends(accountId: AccountRecordId, accountPeerId: PeerId
} }
} }
} else if let resource = smallestImageRepresentation(peer.profileImageRepresentations)?.resource, let path = mediaBox.completedResourcePath(resource) { } else if let resource = smallestImageRepresentation(peer.profileImageRepresentations)?.resource, let path = mediaBox.completedResourcePath(resource) {
let cachedPath = mediaBox.cachedRepresentationPathForId(resource.id.uniqueId, representationId: "intents.png", keepDuration: .shortLived) let cachedPath = mediaBox.cachedRepresentationPathForId(resource.id.stringRepresentation, representationId: "intents.png", keepDuration: .shortLived)
if let _ = fileSize(cachedPath) { if let _ = fileSize(cachedPath) {
do { do {
let data = try Data(contentsOf: URL(fileURLWithPath: cachedPath), options: .alwaysMapped) let data = try Data(contentsOf: URL(fileURLWithPath: cachedPath), options: .alwaysMapped)

View File

@ -13,7 +13,6 @@ swift_library(
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
"//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit",
"//submodules/Display:Display", "//submodules/Display:Display",
"//submodules/Postbox:Postbox",
"//submodules/TelegramCore:TelegramCore", "//submodules/TelegramCore:TelegramCore",
"//submodules/TelegramPresentationData:TelegramPresentationData", "//submodules/TelegramPresentationData:TelegramPresentationData",
"//submodules/AccountContext:AccountContext", "//submodules/AccountContext:AccountContext",

View File

@ -3,7 +3,6 @@ import UIKit
import AsyncDisplayKit import AsyncDisplayKit
import Display import Display
import SwiftSignalKit import SwiftSignalKit
import Postbox
import TelegramCore import TelegramCore
import TelegramPresentationData import TelegramPresentationData
import TelegramUIPreferences import TelegramUIPreferences
@ -321,7 +320,7 @@ private struct InviteLinkEditControllerState: Equatable {
var updating = false var updating = false
} }
public func inviteLinkEditController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, invite: ExportedInvitation?, completion: ((ExportedInvitation?) -> Void)? = nil) -> ViewController { public func inviteLinkEditController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, invite: ExportedInvitation?, completion: ((ExportedInvitation?) -> Void)? = nil) -> ViewController {
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)? var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
let actionsDisposable = DisposableSet() let actionsDisposable = DisposableSet()

View File

@ -4,7 +4,6 @@ import SwiftSignalKit
import TelegramPresentationData import TelegramPresentationData
import AppBundle import AppBundle
import AsyncDisplayKit import AsyncDisplayKit
import Postbox
import TelegramCore import TelegramCore
import Display import Display
import AccountContext import AccountContext
@ -158,13 +157,13 @@ public final class InviteLinkInviteController: ViewController {
private var animatedIn = false private var animatedIn = false
private let context: AccountContext private let context: AccountContext
private let peerId: PeerId private let peerId: EnginePeer.Id
private weak var parentNavigationController: NavigationController? private weak var parentNavigationController: NavigationController?
private var presentationData: PresentationData private var presentationData: PresentationData
private var presentationDataDisposable: Disposable? private var presentationDataDisposable: Disposable?
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, parentNavigationController: NavigationController?) { public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, parentNavigationController: NavigationController?) {
self.context = context self.context = context
self.peerId = peerId self.peerId = peerId
self.parentNavigationController = parentNavigationController self.parentNavigationController = parentNavigationController
@ -251,7 +250,7 @@ public final class InviteLinkInviteController: ViewController {
private weak var controller: InviteLinkInviteController? private weak var controller: InviteLinkInviteController?
private let context: AccountContext private let context: AccountContext
private let peerId: PeerId private let peerId: EnginePeer.Id
private let invitesContext: PeerExportedInvitationsContext private let invitesContext: PeerExportedInvitationsContext
private var interaction: InviteLinkInviteInteraction? private var interaction: InviteLinkInviteInteraction?
@ -278,7 +277,7 @@ public final class InviteLinkInviteController: ViewController {
private var revokeDisposable = MetaDisposable() private var revokeDisposable = MetaDisposable()
init(context: AccountContext, presentationData: PresentationData, peerId: PeerId, controller: InviteLinkInviteController) { init(context: AccountContext, presentationData: PresentationData, peerId: EnginePeer.Id, controller: InviteLinkInviteController) {
self.context = context self.context = context
self.peerId = peerId self.peerId = peerId

View File

@ -3,7 +3,6 @@ import UIKit
import AsyncDisplayKit import AsyncDisplayKit
import Display import Display
import SwiftSignalKit import SwiftSignalKit
import Postbox
import TelegramCore import TelegramCore
import TelegramPresentationData import TelegramPresentationData
import TelegramUIPreferences import TelegramUIPreferences
@ -59,7 +58,7 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
case header(PresentationTheme, String) case header(PresentationTheme, String)
case mainLinkHeader(PresentationTheme, String) case mainLinkHeader(PresentationTheme, String)
case mainLink(PresentationTheme, ExportedInvitation?, [Peer], Int32, Bool) case mainLink(PresentationTheme, ExportedInvitation?, [EnginePeer], Int32, Bool)
case mainLinkOtherInfo(PresentationTheme, String) case mainLinkOtherInfo(PresentationTheme, String)
case linksHeader(PresentationTheme, String) case linksHeader(PresentationTheme, String)
@ -135,7 +134,7 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
return false return false
} }
case let .mainLink(lhsTheme, lhsInvite, lhsPeers, lhsImportersCount, lhsIsPublic): case let .mainLink(lhsTheme, lhsInvite, lhsPeers, lhsImportersCount, lhsIsPublic):
if case let .mainLink(rhsTheme, rhsInvite, rhsPeers, rhsImportersCount, rhsIsPublic) = rhs, lhsTheme === rhsTheme, lhsInvite == rhsInvite, arePeerArraysEqual(lhsPeers, rhsPeers), lhsImportersCount == rhsImportersCount, lhsIsPublic == rhsIsPublic { if case let .mainLink(rhsTheme, rhsInvite, rhsPeers, rhsImportersCount, rhsIsPublic) = rhs, lhsTheme === rhsTheme, lhsInvite == rhsInvite, lhsPeers == rhsPeers, lhsImportersCount == rhsImportersCount, lhsIsPublic == rhsIsPublic {
return true return true
} else { } else {
return false return false
@ -268,12 +267,12 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
} }
} }
private func inviteLinkListControllerEntries(presentationData: PresentationData, view: PeerView, invites: [ExportedInvitation]?, revokedInvites: [ExportedInvitation]?, importers: PeerInvitationImportersState?, creators: [ExportedInvitationCreator], admin: ExportedInvitationCreator?, tick: Int32) -> [InviteLinksListEntry] { private func inviteLinkListControllerEntries(presentationData: PresentationData, exportedInvitation: EngineExportedPeerInvitation?, peer: EnginePeer?, invites: [ExportedInvitation]?, revokedInvites: [ExportedInvitation]?, importers: PeerInvitationImportersState?, creators: [ExportedInvitationCreator], admin: ExportedInvitationCreator?, tick: Int32) -> [InviteLinksListEntry] {
var entries: [InviteLinksListEntry] = [] var entries: [InviteLinksListEntry] = []
if admin == nil { if admin == nil {
let helpText: String let helpText: String
if let peer = peerViewMainPeer(view) as? TelegramChannel, case .broadcast = peer.info { if case let .channel(peer) = peer, case .broadcast = peer.info {
helpText = presentationData.strings.InviteLink_CreatePrivateLinkHelpChannel helpText = presentationData.strings.InviteLink_CreatePrivateLinkHelpChannel
} else { } else {
helpText = presentationData.strings.InviteLink_CreatePrivateLinkHelp helpText = presentationData.strings.InviteLink_CreatePrivateLinkHelp
@ -283,14 +282,12 @@ private func inviteLinkListControllerEntries(presentationData: PresentationData,
let mainInvite: ExportedInvitation? let mainInvite: ExportedInvitation?
var isPublic = false var isPublic = false
if let peer = peerViewMainPeer(view), let address = peer.addressName, !address.isEmpty && admin == nil { if let peer = peer, let address = peer.addressName, !address.isEmpty && admin == nil {
mainInvite = ExportedInvitation(link: "t.me/\(address)", isPermanent: true, isRevoked: false, adminId: PeerId(0), date: 0, startDate: nil, expireDate: nil, usageLimit: nil, count: nil) mainInvite = ExportedInvitation(link: "t.me/\(address)", isPermanent: true, isRevoked: false, adminId: EnginePeer.Id(0), date: 0, startDate: nil, expireDate: nil, usageLimit: nil, count: nil)
isPublic = true isPublic = true
} else if let invites = invites, let invite = invites.first(where: { $0.isPermanent && !$0.isRevoked }) { } else if let invites = invites, let invite = invites.first(where: { $0.isPermanent && !$0.isRevoked }) {
mainInvite = invite mainInvite = invite
} else if let invite = (view.cachedData as? CachedChannelData)?.exportedInvitation, admin == nil { } else if let invite = exportedInvitation, admin == nil {
mainInvite = invite
} else if let invite = (view.cachedData as? CachedGroupData)?.exportedInvitation, admin == nil {
mainInvite = invite mainInvite = invite
} else { } else {
mainInvite = nil mainInvite = nil
@ -307,9 +304,9 @@ private func inviteLinkListControllerEntries(presentationData: PresentationData,
importersCount = 0 importersCount = 0
} }
entries.append(.mainLink(presentationData.theme, mainInvite, importers?.importers.prefix(3).compactMap { $0.peer.peer } ?? [], importersCount, isPublic)) entries.append(.mainLink(presentationData.theme, mainInvite, importers?.importers.prefix(3).compactMap { $0.peer.peer.flatMap(EnginePeer.init) } ?? [], importersCount, isPublic))
if let adminPeer = admin?.peer.peer, let peer = peerViewMainPeer(view) { if let adminPeer = admin?.peer.peer, let peer = peer {
let string = presentationData.strings.InviteLink_OtherPermanentLinkInfo(EnginePeer(adminPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)) let string = presentationData.strings.InviteLink_OtherPermanentLinkInfo(EnginePeer(adminPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))
entries.append(.mainLinkOtherInfo(presentationData.theme, string.string)) entries.append(.mainLinkOtherInfo(presentationData.theme, string.string))
} }
@ -393,7 +390,7 @@ private struct InviteLinkListControllerState: Equatable {
var revokingPrivateLink: Bool var revokingPrivateLink: Bool
} }
public func inviteLinkListController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, admin: ExportedInvitationCreator?) -> ViewController { public func inviteLinkListController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, admin: ExportedInvitationCreator?) -> ViewController {
var pushControllerImpl: ((ViewController) -> Void)? var pushControllerImpl: ((ViewController) -> Void)?
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)? var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
var presentInGlobalOverlayImpl: ((ViewController) -> Void)? var presentInGlobalOverlayImpl: ((ViewController) -> Void)?
@ -742,9 +739,6 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
}) })
let peerView = context.account.viewTracker.peerView(peerId)
|> deliverOnMainQueue
let mainLink: Signal<ExportedInvitation?, NoError> let mainLink: Signal<ExportedInvitation?, NoError>
if let _ = admin { if let _ = admin {
mainLink = invitesContext.state mainLink = invitesContext.state
@ -752,16 +746,9 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
return .single(state.invitations.first(where: { $0.isPermanent && !$0.isRevoked })) return .single(state.invitations.first(where: { $0.isPermanent && !$0.isRevoked }))
} }
} else { } else {
mainLink = peerView mainLink = context.engine.data.subscribe(
|> mapToSignal { view -> Signal<ExportedInvitation?, NoError> in TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: peerId)
if let cachedData = view.cachedData as? CachedGroupData, let exportedInvitation = cachedData.exportedInvitation { )
return .single(exportedInvitation)
} else if let cachedData = view.cachedData as? CachedChannelData, let exportedInvitation = cachedData.exportedInvitation {
return .single(exportedInvitation)
} else {
return .single(nil)
}
}
} }
let importersState = Promise<PeerInvitationImportersState?>(nil) let importersState = Promise<PeerInvitationImportersState?>(nil)
@ -789,9 +776,22 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
let previousCreators = Atomic<[ExportedInvitationCreator]?>(value: nil) let previousCreators = Atomic<[ExportedInvitationCreator]?>(value: nil)
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
let signal = combineLatest(presentationData, peerView, importersContext, importersState.get(), invitesContext.state, revokedInvitesContext.state, creators, timerPromise.get()) let signal = combineLatest(queue: .mainQueue(),
|> deliverOnMainQueue presentationData,
|> map { presentationData, view, importersContext, importers, invites, revokedInvites, creators, tick -> (ItemListControllerState, (ItemListNodeState, Any)) in context.engine.data.subscribe(
TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: peerId)
),
context.engine.data.subscribe(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
),
importersContext,
importersState.get(),
invitesContext.state,
revokedInvitesContext.state,
creators,
timerPromise.get()
)
|> map { presentationData, exportedInvitation, peer, importersContext, importers, invites, revokedInvites, creators, tick -> (ItemListControllerState, (ItemListNodeState, Any)) in
let previousInvites = previousInvites.swap(invites) let previousInvites = previousInvites.swap(invites)
let previousRevokedInvites = previousRevokedInvites.swap(revokedInvites) let previousRevokedInvites = previousRevokedInvites.swap(revokedInvites)
let previousCreators = previousCreators.swap(creators) let previousCreators = previousCreators.swap(creators)
@ -820,7 +820,7 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
} }
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: title, leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: title, leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: inviteLinkListControllerEntries(presentationData: presentationData, view: view, invites: invites.hasLoadedOnce ? invites.invitations : nil, revokedInvites: revokedInvites.hasLoadedOnce ? revokedInvites.invitations : nil, importers: importers, creators: creators, admin: admin, tick: tick), style: .blocks, emptyStateItem: nil, crossfadeState: crossfade, animateChanges: animateChanges) let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: inviteLinkListControllerEntries(presentationData: presentationData, exportedInvitation: exportedInvitation, peer: peer, invites: invites.hasLoadedOnce ? invites.invitations : nil, revokedInvites: revokedInvites.hasLoadedOnce ? revokedInvites.invitations : nil, importers: importers, creators: creators, admin: admin, tick: tick), style: .blocks, emptyStateItem: nil, crossfadeState: crossfade, animateChanges: animateChanges)
return (controllerState, (listState, arguments)) return (controllerState, (listState, arguments))
} }

View File

@ -4,7 +4,6 @@ import SwiftSignalKit
import TelegramPresentationData import TelegramPresentationData
import AppBundle import AppBundle
import AsyncDisplayKit import AsyncDisplayKit
import Postbox
import TelegramCore import TelegramCore
import Display import Display
import AccountContext import AccountContext
@ -23,13 +22,13 @@ import UndoUI
class InviteLinkViewInteraction { class InviteLinkViewInteraction {
let context: AccountContext let context: AccountContext
let openPeer: (PeerId) -> Void let openPeer: (EnginePeer.Id) -> Void
let copyLink: (ExportedInvitation) -> Void let copyLink: (ExportedInvitation) -> Void
let shareLink: (ExportedInvitation) -> Void let shareLink: (ExportedInvitation) -> Void
let editLink: (ExportedInvitation) -> Void let editLink: (ExportedInvitation) -> Void
let contextAction: (ExportedInvitation, ASDisplayNode, ContextGesture?) -> Void let contextAction: (ExportedInvitation, ASDisplayNode, ContextGesture?) -> Void
init(context: AccountContext, openPeer: @escaping (PeerId) -> Void, copyLink: @escaping (ExportedInvitation) -> Void, shareLink: @escaping (ExportedInvitation) -> Void, editLink: @escaping (ExportedInvitation) -> Void, contextAction: @escaping (ExportedInvitation, ASDisplayNode, ContextGesture?) -> Void) { init(context: AccountContext, openPeer: @escaping (EnginePeer.Id) -> Void, copyLink: @escaping (ExportedInvitation) -> Void, shareLink: @escaping (ExportedInvitation) -> Void, editLink: @escaping (ExportedInvitation) -> Void, contextAction: @escaping (ExportedInvitation, ASDisplayNode, ContextGesture?) -> Void) {
self.context = context self.context = context
self.openPeer = openPeer self.openPeer = openPeer
self.copyLink = copyLink self.copyLink = copyLink
@ -53,15 +52,15 @@ private enum InviteLinkViewEntryId: Hashable {
case creatorHeader case creatorHeader
case creator case creator
case importerHeader case importerHeader
case importer(PeerId) case importer(EnginePeer.Id)
} }
private enum InviteLinkViewEntry: Comparable, Identifiable { private enum InviteLinkViewEntry: Comparable, Identifiable {
case link(PresentationTheme, ExportedInvitation) case link(PresentationTheme, ExportedInvitation)
case creatorHeader(PresentationTheme, String) case creatorHeader(PresentationTheme, String)
case creator(PresentationTheme, PresentationDateTimeFormat, Peer, Int32) case creator(PresentationTheme, PresentationDateTimeFormat, EnginePeer, Int32)
case importerHeader(PresentationTheme, String, String, Bool) case importerHeader(PresentationTheme, String, String, Bool)
case importer(Int32, PresentationTheme, PresentationDateTimeFormat, Peer, Int32, Bool) case importer(Int32, PresentationTheme, PresentationDateTimeFormat, EnginePeer, Int32, Bool)
var stableId: InviteLinkViewEntryId { var stableId: InviteLinkViewEntryId {
switch self { switch self {
@ -93,7 +92,7 @@ private enum InviteLinkViewEntry: Comparable, Identifiable {
return false return false
} }
case let .creator(lhsTheme, lhsDateTimeFormat, lhsPeer, lhsDate): case let .creator(lhsTheme, lhsDateTimeFormat, lhsPeer, lhsDate):
if case let .creator(rhsTheme, rhsDateTimeFormat, rhsPeer, rhsDate) = rhs, lhsTheme === rhsTheme, lhsDateTimeFormat == rhsDateTimeFormat, arePeersEqual(lhsPeer, rhsPeer), lhsDate == rhsDate { if case let .creator(rhsTheme, rhsDateTimeFormat, rhsPeer, rhsDate) = rhs, lhsTheme === rhsTheme, lhsDateTimeFormat == rhsDateTimeFormat, lhsPeer == rhsPeer, lhsDate == rhsDate {
return true return true
} else { } else {
return false return false
@ -105,7 +104,7 @@ private enum InviteLinkViewEntry: Comparable, Identifiable {
return false return false
} }
case let .importer(lhsIndex, lhsTheme, lhsDateTimeFormat, lhsPeer, lhsDate, lhsLoading): case let .importer(lhsIndex, lhsTheme, lhsDateTimeFormat, lhsPeer, lhsDate, lhsLoading):
if case let .importer(rhsIndex, rhsTheme, rhsDateTimeFormat, rhsPeer, rhsDate, rhsLoading) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsDateTimeFormat == rhsDateTimeFormat, arePeersEqual(lhsPeer, rhsPeer), lhsDate == rhsDate, lhsLoading == rhsLoading { if case let .importer(rhsIndex, rhsTheme, rhsDateTimeFormat, rhsPeer, rhsDate, rhsLoading) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsDateTimeFormat == rhsDateTimeFormat, lhsPeer == rhsPeer, lhsDate == rhsDate, lhsLoading == rhsLoading {
return true return true
} else { } else {
return false return false
@ -172,7 +171,7 @@ private enum InviteLinkViewEntry: Comparable, Identifiable {
return SectionHeaderItem(presentationData: ItemListPresentationData(presentationData), title: title) return SectionHeaderItem(presentationData: ItemListPresentationData(presentationData), title: title)
case let .creator(_, dateTimeFormat, peer, date): case let .creator(_, dateTimeFormat, peer, date):
let dateString = stringForFullDate(timestamp: date, strings: presentationData.strings, dateTimeFormat: dateTimeFormat) let dateString = stringForFullDate(timestamp: date, strings: presentationData.strings, dateTimeFormat: dateTimeFormat)
return ItemListPeerItem(presentationData: ItemListPresentationData(presentationData), dateTimeFormat: dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, context: interaction.context, peer: EnginePeer(peer), height: .generic, nameStyle: .distinctBold, presence: nil, text: .text(dateString, .secondary), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: peer.id != account.peerId, sectionId: 0, action: { return ItemListPeerItem(presentationData: ItemListPresentationData(presentationData), dateTimeFormat: dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, context: interaction.context, peer: peer, height: .generic, nameStyle: .distinctBold, presence: nil, text: .text(dateString, .secondary), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: peer.id != account.peerId, sectionId: 0, action: {
interaction.openPeer(peer.id) interaction.openPeer(peer.id)
}, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, hasTopStripe: false, noInsets: true, tag: nil) }, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, hasTopStripe: false, noInsets: true, tag: nil)
case let .importerHeader(_, title, subtitle, expired): case let .importerHeader(_, title, subtitle, expired):
@ -189,7 +188,7 @@ private enum InviteLinkViewEntry: Comparable, Identifiable {
return SectionHeaderItem(presentationData: ItemListPresentationData(presentationData), title: title, additionalText: additionalText) return SectionHeaderItem(presentationData: ItemListPresentationData(presentationData), title: title, additionalText: additionalText)
case let .importer(_, _, dateTimeFormat, peer, date, loading): case let .importer(_, _, dateTimeFormat, peer, date, loading):
let dateString = stringForFullDate(timestamp: date, strings: presentationData.strings, dateTimeFormat: dateTimeFormat) let dateString = stringForFullDate(timestamp: date, strings: presentationData.strings, dateTimeFormat: dateTimeFormat)
return ItemListPeerItem(presentationData: ItemListPresentationData(presentationData), dateTimeFormat: dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, context: interaction.context, peer: EnginePeer(peer), height: .generic, nameStyle: .distinctBold, presence: nil, text: .text(dateString, .secondary), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: peer.id != account.peerId, sectionId: 0, action: { return ItemListPeerItem(presentationData: ItemListPresentationData(presentationData), dateTimeFormat: dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, context: interaction.context, peer: peer, height: .generic, nameStyle: .distinctBold, presence: nil, text: .text(dateString, .secondary), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: peer.id != account.peerId, sectionId: 0, action: {
interaction.openPeer(peer.id) interaction.openPeer(peer.id)
}, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, hasTopStripe: false, noInsets: true, tag: nil, shimmering: loading ? ItemListPeerItemShimmering(alternationIndex: 0) : nil) }, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, hasTopStripe: false, noInsets: true, tag: nil, shimmering: loading ? ItemListPeerItemShimmering(alternationIndex: 0) : nil)
} }
@ -233,7 +232,7 @@ public final class InviteLinkViewController: ViewController {
private var animatedIn = false private var animatedIn = false
private let context: AccountContext private let context: AccountContext
private let peerId: PeerId private let peerId: EnginePeer.Id
private let invite: ExportedInvitation private let invite: ExportedInvitation
private let invitationsContext: PeerExportedInvitationsContext? private let invitationsContext: PeerExportedInvitationsContext?
private let revokedInvitationsContext: PeerExportedInvitationsContext? private let revokedInvitationsContext: PeerExportedInvitationsContext?
@ -243,7 +242,7 @@ public final class InviteLinkViewController: ViewController {
private var presentationDataDisposable: Disposable? private var presentationDataDisposable: Disposable?
fileprivate var presentationDataPromise = Promise<PresentationData>() fileprivate var presentationDataPromise = Promise<PresentationData>()
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, invite: ExportedInvitation, invitationsContext: PeerExportedInvitationsContext?, revokedInvitationsContext: PeerExportedInvitationsContext?, importersContext: PeerInvitationImportersContext?) { public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, invite: ExportedInvitation, invitationsContext: PeerExportedInvitationsContext?, revokedInvitationsContext: PeerExportedInvitationsContext?, importersContext: PeerInvitationImportersContext?) {
self.context = context self.context = context
self.peerId = peerId self.peerId = peerId
self.invite = invite self.invite = invite
@ -338,7 +337,7 @@ public final class InviteLinkViewController: ViewController {
private weak var controller: InviteLinkViewController? private weak var controller: InviteLinkViewController?
private let context: AccountContext private let context: AccountContext
private let peerId: PeerId private let peerId: EnginePeer.Id
private let invite: ExportedInvitation private let invite: ExportedInvitation
private let importersContext: PeerInvitationImportersContext private let importersContext: PeerInvitationImportersContext
@ -369,7 +368,7 @@ public final class InviteLinkViewController: ViewController {
private var validLayout: ContainerViewLayout? private var validLayout: ContainerViewLayout?
init(context: AccountContext, presentationData: PresentationData, peerId: PeerId, invite: ExportedInvitation, importersContext: PeerInvitationImportersContext?, controller: InviteLinkViewController) { init(context: AccountContext, presentationData: PresentationData, peerId: EnginePeer.Id, invite: ExportedInvitation, importersContext: PeerInvitationImportersContext?, controller: InviteLinkViewController) {
self.context = context self.context = context
self.peerId = peerId self.peerId = peerId
self.invite = invite self.invite = invite
@ -581,7 +580,7 @@ public final class InviteLinkViewController: ViewController {
entries.append(.link(presentationData.theme, invite)) entries.append(.link(presentationData.theme, invite))
entries.append(.creatorHeader(presentationData.theme, presentationData.strings.InviteLink_CreatedBy.uppercased())) entries.append(.creatorHeader(presentationData.theme, presentationData.strings.InviteLink_CreatedBy.uppercased()))
entries.append(.creator(presentationData.theme, presentationData.dateTimeFormat, creatorPeer, invite.date)) entries.append(.creator(presentationData.theme, presentationData.dateTimeFormat, EnginePeer(creatorPeer), invite.date))
if !state.importers.isEmpty || (state.isLoadingMore && state.count > 0) { if !state.importers.isEmpty || (state.isLoadingMore && state.count > 0) {
let subtitle: String let subtitle: String
@ -605,16 +604,16 @@ public final class InviteLinkViewController: ViewController {
if state.importers.isEmpty && state.isLoadingMore { if state.importers.isEmpty && state.isLoadingMore {
count = min(4, state.count) count = min(4, state.count)
loading = true loading = true
let fakeUser = TelegramUser(id: PeerId(namespace: .max, id: PeerId.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [])
for i in 0 ..< count { for i in 0 ..< count {
entries.append(.importer(Int32(i), presentationData.theme, presentationData.dateTimeFormat, fakeUser, 0, true)) entries.append(.importer(Int32(i), presentationData.theme, presentationData.dateTimeFormat, EnginePeer.user(fakeUser), 0, true))
} }
} else { } else {
count = min(4, Int32(state.importers.count)) count = min(4, Int32(state.importers.count))
loading = false loading = false
for importer in state.importers { for importer in state.importers {
if let peer = importer.peer.peer { if let peer = importer.peer.peer {
entries.append(.importer(index, presentationData.theme, presentationData.dateTimeFormat, peer, importer.date, false)) entries.append(.importer(index, presentationData.theme, presentationData.dateTimeFormat, EnginePeer(peer), importer.date, false))
} }
index += 1 index += 1
} }

View File

@ -3,7 +3,6 @@ import UIKit
import Display import Display
import AsyncDisplayKit import AsyncDisplayKit
import SwiftSignalKit import SwiftSignalKit
import Postbox
import AccountContext import AccountContext
import TelegramPresentationData import TelegramPresentationData
import ItemListUI import ItemListUI
@ -31,7 +30,7 @@ public class ItemListPermanentInviteLinkItem: ListViewItem, ItemListItem {
let presentationData: ItemListPresentationData let presentationData: ItemListPresentationData
let invite: ExportedInvitation? let invite: ExportedInvitation?
let count: Int32 let count: Int32
let peers: [Peer] let peers: [EnginePeer]
let displayButton: Bool let displayButton: Bool
let displayImporters: Bool let displayImporters: Bool
let buttonColor: UIColor? let buttonColor: UIColor?
@ -48,7 +47,7 @@ public class ItemListPermanentInviteLinkItem: ListViewItem, ItemListItem {
presentationData: ItemListPresentationData, presentationData: ItemListPresentationData,
invite: ExportedInvitation?, invite: ExportedInvitation?,
count: Int32, count: Int32,
peers: [Peer], peers: [EnginePeer],
displayButton: Bool, displayButton: Bool,
displayImporters: Bool, displayImporters: Bool,
buttonColor: UIColor?, buttonColor: UIColor?,
@ -322,7 +321,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
let (invitedPeersLayout, invitedPeersApply) = makeInvitedPeersLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: subtitle, font: titleFont, textColor: subtitleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - 20.0 - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) let (invitedPeersLayout, invitedPeersApply) = makeInvitedPeersLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: subtitle, font: titleFont, textColor: subtitleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - 20.0 - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let avatarsContent = avatarsContext.update(peers: item.peers.map(EnginePeer.init), animated: false) let avatarsContent = avatarsContext.update(peers: item.peers, animated: false)
let verticalInset: CGFloat = 16.0 let verticalInset: CGFloat = 16.0
let fieldHeight: CGFloat = 52.0 let fieldHeight: CGFloat = 52.0

View File

@ -1084,7 +1084,7 @@ public class ItemListAvatarAndNameInfoItemNode: ListViewItemNode, ItemListItemNo
var hidden = false var hidden = false
if let item = self.item, let context = item.context, let peer = item.peer, let hiddenAvatarRepresentation = context.hiddenAvatarRepresentation { if let item = self.item, let context = item.context, let peer = item.peer, let hiddenAvatarRepresentation = context.hiddenAvatarRepresentation {
for representation in peer.profileImageRepresentations { for representation in peer.profileImageRepresentations {
if representation.resource.id.isEqual(to: hiddenAvatarRepresentation.resource.id) { if representation.resource.id == hiddenAvatarRepresentation.resource.id {
hidden = true hidden = true
} }
} }

View File

@ -5,7 +5,7 @@ import TelegramCore
public func legacyImageLocationUri(resource: MediaResource) -> String? { public func legacyImageLocationUri(resource: MediaResource) -> String? {
if let resource = resource as? CloudPeerPhotoSizeMediaResource { if let resource = resource as? CloudPeerPhotoSizeMediaResource {
return resource.id.uniqueId return resource.id.stringRepresentation
} }
return nil return nil
} }

View File

@ -28,7 +28,7 @@ public final class VideoMediaResourceAdjustments: PostboxCoding, Equatable {
} }
} }
public struct VideoLibraryMediaResourceId: MediaResourceId { public struct VideoLibraryMediaResourceId {
public let localIdentifier: String public let localIdentifier: String
public let adjustmentsDigest: MemoryBuffer? public let adjustmentsDigest: MemoryBuffer?
@ -43,14 +43,6 @@ public struct VideoLibraryMediaResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.localIdentifier.hashValue return self.localIdentifier.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? VideoLibraryMediaResourceId {
return self.localIdentifier == to.localIdentifier && self.adjustmentsDigest == to.adjustmentsDigest
} else {
return false
}
}
} }
public enum VideoLibraryMediaResourceConversion: PostboxCoding, Equatable { public enum VideoLibraryMediaResourceConversion: PostboxCoding, Equatable {
@ -131,7 +123,7 @@ public final class VideoLibraryMediaResource: TelegramMediaResource {
case let .compress(adjustments): case let .compress(adjustments):
adjustmentsDigest = adjustments?.digest adjustmentsDigest = adjustments?.digest
} }
return VideoLibraryMediaResourceId(localIdentifier: self.localIdentifier, adjustmentsDigest: adjustmentsDigest) return MediaResourceId(VideoLibraryMediaResourceId(localIdentifier: self.localIdentifier, adjustmentsDigest: adjustmentsDigest).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -143,7 +135,7 @@ public final class VideoLibraryMediaResource: TelegramMediaResource {
} }
} }
public struct LocalFileVideoMediaResourceId: MediaResourceId { public struct LocalFileVideoMediaResourceId {
public let randomId: Int64 public let randomId: Int64
public var uniqueId: String { public var uniqueId: String {
@ -153,14 +145,6 @@ public struct LocalFileVideoMediaResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.randomId.hashValue return self.randomId.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? LocalFileVideoMediaResourceId {
return self.randomId == to.randomId
} else {
return false
}
}
} }
public final class LocalFileVideoMediaResource: TelegramMediaResource { public final class LocalFileVideoMediaResource: TelegramMediaResource {
@ -195,7 +179,7 @@ public final class LocalFileVideoMediaResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return LocalFileVideoMediaResourceId(randomId: self.randomId) return MediaResourceId(LocalFileVideoMediaResourceId(randomId: self.randomId).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -207,7 +191,7 @@ public final class LocalFileVideoMediaResource: TelegramMediaResource {
} }
} }
public struct PhotoLibraryMediaResourceId: MediaResourceId { public struct PhotoLibraryMediaResourceId {
public let localIdentifier: String public let localIdentifier: String
public let resourceId: Int64 public let resourceId: Int64
@ -222,14 +206,6 @@ public struct PhotoLibraryMediaResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.localIdentifier.hashValue return self.localIdentifier.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? PhotoLibraryMediaResourceId {
return self.localIdentifier == to.localIdentifier
} else {
return false
}
}
} }
public class PhotoLibraryMediaResource: TelegramMediaResource { public class PhotoLibraryMediaResource: TelegramMediaResource {
@ -252,7 +228,7 @@ public class PhotoLibraryMediaResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return PhotoLibraryMediaResourceId(localIdentifier: self.localIdentifier, resourceId: self.uniqueId) return MediaResourceId(PhotoLibraryMediaResourceId(localIdentifier: self.localIdentifier, resourceId: self.uniqueId).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -264,7 +240,7 @@ public class PhotoLibraryMediaResource: TelegramMediaResource {
} }
} }
public struct LocalFileGifMediaResourceId: MediaResourceId { public struct LocalFileGifMediaResourceId {
public let randomId: Int64 public let randomId: Int64
public var uniqueId: String { public var uniqueId: String {
@ -274,14 +250,6 @@ public struct LocalFileGifMediaResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.randomId.hashValue return self.randomId.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? LocalFileGifMediaResourceId {
return self.randomId == to.randomId
} else {
return false
}
}
} }
public final class LocalFileGifMediaResource: TelegramMediaResource { public final class LocalFileGifMediaResource: TelegramMediaResource {
@ -308,7 +276,7 @@ public final class LocalFileGifMediaResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return LocalFileGifMediaResourceId(randomId: self.randomId) return MediaResourceId(LocalFileGifMediaResourceId(randomId: self.randomId).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -321,7 +289,7 @@ public final class LocalFileGifMediaResource: TelegramMediaResource {
} }
public struct BundleResourceId: MediaResourceId { public struct BundleResourceId {
public let nameHash: Int64 public let nameHash: Int64
public var uniqueId: String { public var uniqueId: String {
@ -331,14 +299,6 @@ public struct BundleResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.nameHash.hashValue return self.nameHash.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? BundleResourceId {
return self.nameHash == to.nameHash
} else {
return false
}
}
} }
public class BundleResource: TelegramMediaResource { public class BundleResource: TelegramMediaResource {
@ -361,7 +321,7 @@ public class BundleResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return BundleResourceId(nameHash: self.nameHash) return MediaResourceId(BundleResourceId(nameHash: self.nameHash).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {

View File

@ -6,7 +6,7 @@ import TelegramCore
import MapKit import MapKit
import SwiftSignalKit import SwiftSignalKit
public struct MapSnapshotMediaResourceId: MediaResourceId { public struct MapSnapshotMediaResourceId {
public let latitude: Double public let latitude: Double
public let longitude: Double public let longitude: Double
public let width: Int32 public let width: Int32
@ -19,14 +19,6 @@ public struct MapSnapshotMediaResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.uniqueId.hashValue return self.uniqueId.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? MapSnapshotMediaResourceId {
return self.latitude == to.latitude && self.longitude == to.longitude && self.width == to.width && self.height == to.height
} else {
return false
}
}
} }
public class MapSnapshotMediaResource: TelegramMediaResource { public class MapSnapshotMediaResource: TelegramMediaResource {
@ -57,7 +49,7 @@ public class MapSnapshotMediaResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return MapSnapshotMediaResourceId(latitude: self.latitude, longitude: self.longitude, width: self.width, height: self.height) return MediaResourceId(MapSnapshotMediaResourceId(latitude: self.latitude, longitude: self.longitude, width: self.width, height: self.height).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {

View File

@ -6,7 +6,7 @@ import TelegramCore
import SwiftSignalKit import SwiftSignalKit
import AppBundle import AppBundle
public struct VenueIconResourceId: MediaResourceId { public struct VenueIconResourceId {
public let type: String public let type: String
public init(type: String) { public init(type: String) {
@ -20,14 +20,6 @@ public struct VenueIconResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.type.hashValue return self.type.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? VenueIconResourceId {
return self.type == to.type
} else {
return false
}
}
} }
public class VenueIconResource: TelegramMediaResource { public class VenueIconResource: TelegramMediaResource {
@ -46,7 +38,7 @@ public class VenueIconResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return VenueIconResourceId(type: self.type) return MediaResourceId(VenueIconResourceId(type: self.type).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {

View File

@ -13,7 +13,6 @@ swift_library(
"//submodules/Display:Display", "//submodules/Display:Display",
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
"//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit",
"//submodules/Postbox:Postbox",
"//submodules/TelegramCore:TelegramCore", "//submodules/TelegramCore:TelegramCore",
"//submodules/GZip:GZip", "//submodules/GZip:GZip",
"//submodules/rlottie:RLottieBinding", "//submodules/rlottie:RLottieBinding",

View File

@ -2,7 +2,6 @@ import Foundation
import UIKit import UIKit
import Display import Display
import AsyncDisplayKit import AsyncDisplayKit
import Postbox
import TelegramCore import TelegramCore
import RLottieBinding import RLottieBinding
import AppBundle import AppBundle
@ -79,14 +78,14 @@ public enum ManagedAnimationFrameRange: Equatable {
public enum ManagedAnimationSource: Equatable { public enum ManagedAnimationSource: Equatable {
case local(String) case local(String)
case resource(Account, MediaResource) case resource(Account, EngineMediaResource)
var cacheKey: String { var cacheKey: String {
switch self { switch self {
case let .local(name): case let .local(name):
return name return name
case let .resource(_, resource): case let .resource(_, resource):
return resource.id.uniqueId return resource.id.stringRepresentation
} }
} }
@ -95,11 +94,11 @@ public enum ManagedAnimationSource: Equatable {
case let .local(name): case let .local(name):
return getAppBundle().path(forResource: name, ofType: "tgs") return getAppBundle().path(forResource: name, ofType: "tgs")
case let .resource(account, resource): case let .resource(account, resource):
return account.postbox.mediaBox.completedResourcePath(resource) return account.postbox.mediaBox.completedResourcePath(resource._asResource())
} }
} }
public static func == (lhs: ManagedAnimationSource, rhs: ManagedAnimationSource) -> Bool { public static func ==(lhs: ManagedAnimationSource, rhs: ManagedAnimationSource) -> Bool {
switch lhs { switch lhs {
case let .local(lhsPath): case let .local(lhsPath):
if case let .local(rhsPath) = rhs, lhsPath == rhsPath { if case let .local(rhsPath) = rhs, lhsPath == rhsPath {
@ -108,7 +107,7 @@ public enum ManagedAnimationSource: Equatable {
return false return false
} }
case let .resource(lhsAccount, lhsResource): case let .resource(lhsAccount, lhsResource):
if case let .resource(rhsAccount, rhsResource) = rhs, lhsAccount === rhsAccount, lhsResource.isEqual(to: rhsResource) { if case let .resource(rhsAccount, rhsResource) = rhs, lhsAccount === rhsAccount, lhsResource == rhsResource {
return true return true
} else { } else {
return false return false

View File

@ -5,7 +5,7 @@ import SwiftSignalKit
import Postbox import Postbox
import UrlEscaping import UrlEscaping
public struct ExternalMusicAlbumArtResourceId: MediaResourceId { public struct ExternalMusicAlbumArtResourceId {
public let title: String public let title: String
public let performer: String public let performer: String
public let isThumbnail: Bool public let isThumbnail: Bool
@ -23,14 +23,6 @@ public struct ExternalMusicAlbumArtResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.title.hashValue &* 31 &+ self.performer.hashValue return self.title.hashValue &* 31 &+ self.performer.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? ExternalMusicAlbumArtResourceId {
return self.title == to.title && self.performer == to.performer && self.isThumbnail == to.isThumbnail
} else {
return false
}
}
} }
public class ExternalMusicAlbumArtResource: TelegramMediaResource { public class ExternalMusicAlbumArtResource: TelegramMediaResource {
@ -57,7 +49,7 @@ public class ExternalMusicAlbumArtResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return ExternalMusicAlbumArtResourceId(title: self.title, performer: self.performer, isThumbnail: self.isThumbnail) return MediaResourceId(ExternalMusicAlbumArtResourceId(title: self.title, performer: self.performer, isThumbnail: self.isThumbnail).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {

View File

@ -4,7 +4,7 @@ import TelegramCore
import SwiftSignalKit import SwiftSignalKit
import Postbox import Postbox
public struct OpenInAppIconResourceId: MediaResourceId { public struct OpenInAppIconResourceId {
public let appStoreId: Int64 public let appStoreId: Int64
public var uniqueId: String { public var uniqueId: String {
@ -14,14 +14,6 @@ public struct OpenInAppIconResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.appStoreId.hashValue return self.appStoreId.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? OpenInAppIconResourceId {
return self.appStoreId == to.appStoreId
} else {
return false
}
}
} }
public class OpenInAppIconResource: TelegramMediaResource { public class OpenInAppIconResource: TelegramMediaResource {
@ -48,7 +40,7 @@ public class OpenInAppIconResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return OpenInAppIconResourceId(appStoreId: self.appStoreId) return MediaResourceId(OpenInAppIconResourceId(appStoreId: self.appStoreId).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {

View File

@ -5,7 +5,7 @@ import TelegramCore
import SwiftSignalKit import SwiftSignalKit
import Display import Display
public struct SecureIdLocalImageResourceId: MediaResourceId { public struct SecureIdLocalImageResourceId {
public let id: Int64 public let id: Int64
public var uniqueId: String { public var uniqueId: String {
@ -15,14 +15,6 @@ public struct SecureIdLocalImageResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.id.hashValue return self.id.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? SecureIdLocalImageResourceId {
return self.id == to.id
} else {
return false
}
}
} }
public class SecureIdLocalImageResource: TelegramMediaResource { public class SecureIdLocalImageResource: TelegramMediaResource {
@ -45,7 +37,7 @@ public class SecureIdLocalImageResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return SecureIdLocalImageResourceId(id: self.localId) return MediaResourceId(SecureIdLocalImageResourceId(id: self.localId).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {

View File

@ -76,12 +76,12 @@ public enum AvatarGalleryEntry: Equatable {
switch self { switch self {
case let .topImage(representations, _, _, _, _, _): case let .topImage(representations, _, _, _, _, _):
if let last = representations.last { if let last = representations.last {
return .resource(last.representation.resource.id.uniqueId) return .resource(last.representation.resource.id.stringRepresentation)
} }
return .topImage return .topImage
case let .image(id, _, representations, _, _, _, _, _, _, _): case let .image(id, _, representations, _, _, _, _, _, _, _):
if let last = representations.last { if let last = representations.last {
return .resource(last.representation.resource.id.uniqueId) return .resource(last.representation.resource.id.stringRepresentation)
} }
return .image(id) return .image(id)
} }

View File

@ -77,7 +77,7 @@ private class PeerInfoAvatarListLoadingStripNode: ASImageNode {
} }
} }
private struct CustomListItemResourceId: MediaResourceId { private struct CustomListItemResourceId {
public var uniqueId: String { public var uniqueId: String {
return "customNode" return "customNode"
} }
@ -85,14 +85,6 @@ private struct CustomListItemResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return 0 return 0
} }
public func isEqual(to: MediaResourceId) -> Bool {
if to is CustomListItemResourceId {
return true
} else {
return false
}
}
} }
public enum PeerInfoAvatarListItem: Equatable { public enum PeerInfoAvatarListItem: Equatable {
@ -100,16 +92,16 @@ public enum PeerInfoAvatarListItem: Equatable {
case topImage([ImageRepresentationWithReference], [VideoRepresentationWithReference], Data?) case topImage([ImageRepresentationWithReference], [VideoRepresentationWithReference], Data?)
case image(TelegramMediaImageReference?, [ImageRepresentationWithReference], [VideoRepresentationWithReference], Data?) case image(TelegramMediaImageReference?, [ImageRepresentationWithReference], [VideoRepresentationWithReference], Data?)
var id: WrappedMediaResourceId { var id: MediaResourceId {
switch self { switch self {
case .custom: case .custom:
return WrappedMediaResourceId(CustomListItemResourceId()) return MediaResourceId(CustomListItemResourceId().uniqueId)
case let .topImage(representations, _, _): case let .topImage(representations, _, _):
let representation = largestImageRepresentation(representations.map { $0.representation }) ?? representations[representations.count - 1].representation let representation = largestImageRepresentation(representations.map { $0.representation }) ?? representations[representations.count - 1].representation
return WrappedMediaResourceId(representation.resource.id) return representation.resource.id
case let .image(_, representations, _, _): case let .image(_, representations, _, _):
let representation = largestImageRepresentation(representations.map { $0.representation }) ?? representations[representations.count - 1].representation let representation = largestImageRepresentation(representations.map { $0.representation }) ?? representations[representations.count - 1].representation
return WrappedMediaResourceId(representation.resource.id) return representation.resource.id
} }
} }
@ -465,7 +457,7 @@ public final class PeerInfoAvatarListContainerNode: ASDisplayNode {
public let highlightContainerNode: ASDisplayNode public let highlightContainerNode: ASDisplayNode
public private(set) var galleryEntries: [AvatarGalleryEntry] = [] public private(set) var galleryEntries: [AvatarGalleryEntry] = []
private var items: [PeerInfoAvatarListItem] = [] private var items: [PeerInfoAvatarListItem] = []
private var itemNodes: [WrappedMediaResourceId: PeerInfoAvatarListItemNode] = [:] private var itemNodes: [MediaResourceId: PeerInfoAvatarListItemNode] = [:]
private var stripNodes: [ASImageNode] = [] private var stripNodes: [ASImageNode] = []
private var activeStripNode: ASImageNode private var activeStripNode: ASImageNode
private var loadingStripNode: PeerInfoAvatarListLoadingStripNode private var loadingStripNode: PeerInfoAvatarListLoadingStripNode
@ -1131,7 +1123,7 @@ public final class PeerInfoAvatarListContainerNode: ASDisplayNode {
public var updateCustomItemsOnlySynchronously = false public var updateCustomItemsOnlySynchronously = false
private func updateItems(size: CGSize, update: Bool = false, transition: ContainedViewLayoutTransition, stripTransition: ContainedViewLayoutTransition, synchronous: Bool = false) { private func updateItems(size: CGSize, update: Bool = false, transition: ContainedViewLayoutTransition, stripTransition: ContainedViewLayoutTransition, synchronous: Bool = false) {
var validIds: [WrappedMediaResourceId] = [] var validIds: [MediaResourceId] = []
var addedItemNodesForAdditiveTransition: [PeerInfoAvatarListItemNode] = [] var addedItemNodesForAdditiveTransition: [PeerInfoAvatarListItemNode] = []
var additiveTransitionOffset: CGFloat = 0.0 var additiveTransitionOffset: CGFloat = 0.0
var itemsAdded = false var itemsAdded = false
@ -1185,7 +1177,7 @@ public final class PeerInfoAvatarListContainerNode: ASDisplayNode {
for itemNode in addedItemNodesForAdditiveTransition { for itemNode in addedItemNodesForAdditiveTransition {
transition.animatePositionAdditive(node: itemNode, offset: CGPoint(x: additiveTransitionOffset, y: 0.0)) transition.animatePositionAdditive(node: itemNode, offset: CGPoint(x: additiveTransitionOffset, y: 0.0))
} }
var removeIds: [WrappedMediaResourceId] = [] var removeIds: [MediaResourceId] = []
for (id, _) in self.itemNodes { for (id, _) in self.itemNodes {
if !validIds.contains(id) { if !validIds.contains(id) {
removeIds.append(id) removeIds.append(id)

View File

@ -102,7 +102,7 @@ private struct CachedMediaResourceRepresentationKey: Hashable {
let representation: CachedMediaResourceRepresentation let representation: CachedMediaResourceRepresentation
static func ==(lhs: CachedMediaResourceRepresentationKey, rhs: CachedMediaResourceRepresentationKey) -> Bool { static func ==(lhs: CachedMediaResourceRepresentationKey, rhs: CachedMediaResourceRepresentationKey) -> Bool {
return lhs.resourceId.isEqual(to: rhs.resourceId) && lhs.representation.isEqual(to: rhs.representation) return lhs.resourceId == rhs.resourceId && lhs.representation.isEqual(to: rhs.representation)
} }
func hash(into hasher: inout Hasher) { func hash(into hasher: inout Hasher) {
@ -150,11 +150,11 @@ public final class MediaBox {
private let cacheQueue = Queue() private let cacheQueue = Queue()
private let timeBasedCleanup: TimeBasedCleanup private let timeBasedCleanup: TimeBasedCleanup
private var statusContexts: [WrappedMediaResourceId: ResourceStatusContext] = [:] private var statusContexts: [MediaResourceId: ResourceStatusContext] = [:]
private var cachedRepresentationContexts: [CachedMediaResourceRepresentationKey: CachedMediaResourceRepresentationContext] = [:] private var cachedRepresentationContexts: [CachedMediaResourceRepresentationKey: CachedMediaResourceRepresentationContext] = [:]
private var fileContexts: [WrappedMediaResourceId: MediaBoxFileContext] = [:] private var fileContexts: [MediaResourceId: MediaBoxFileContext] = [:]
private var keepResourceContexts: [WrappedMediaResourceId: MediaBoxKeepResourceContext] = [:] private var keepResourceContexts: [MediaResourceId: MediaBoxKeepResourceContext] = [:]
private var wrappedFetchResource = Promise<(MediaResource, Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>>() private var wrappedFetchResource = Promise<(MediaResource, Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>>()
public var preFetchedResourcePath: (MediaResource) -> String? = { _ in return nil } public var preFetchedResourcePath: (MediaResource) -> String? = { _ in return nil }
@ -203,7 +203,7 @@ public final class MediaBox {
} }
private func fileNameForId(_ id: MediaResourceId) -> String { private func fileNameForId(_ id: MediaResourceId) -> String {
return "\(id.uniqueId)" return "\(id.stringRepresentation)"
} }
private func fileNameForId(_ id: String) -> String { private func fileNameForId(_ id: String) -> String {
@ -287,7 +287,7 @@ public final class MediaBox {
} }
public func moveResourceData(from: MediaResourceId, to: MediaResourceId) { public func moveResourceData(from: MediaResourceId, to: MediaResourceId) {
if from.isEqual(to: to) { if from == to {
return return
} }
self.dataQueue.async { self.dataQueue.async {
@ -301,7 +301,7 @@ public final class MediaBox {
} }
public func copyResourceData(from: MediaResourceId, to: MediaResourceId, synchronous: Bool = false) { public func copyResourceData(from: MediaResourceId, to: MediaResourceId, synchronous: Bool = false) {
if from.isEqual(to: to) { if from == to {
return return
} }
let begin = { let begin = {
@ -348,7 +348,7 @@ public final class MediaBox {
} }
self.statusQueue.async { self.statusQueue.async {
let resourceId = WrappedMediaResourceId(resource.id) let resourceId = resource.id
let statusContext: ResourceStatusContext let statusContext: ResourceStatusContext
var statusUpdateDisposable: MetaDisposable? var statusUpdateDisposable: MetaDisposable?
if let current = self.statusContexts[resourceId] { if let current = self.statusContexts[resourceId] {
@ -402,10 +402,10 @@ public final class MediaBox {
disposable.set(ActionDisposable { [weak statusContext] in disposable.set(ActionDisposable { [weak statusContext] in
self.statusQueue.async { self.statusQueue.async {
if let current = self.statusContexts[WrappedMediaResourceId(resource.id)], current === statusContext { if let current = self.statusContexts[resource.id], current === statusContext {
current.subscribers.remove(index) current.subscribers.remove(index)
if current.subscribers.isEmpty { if current.subscribers.isEmpty {
self.statusContexts.removeValue(forKey: WrappedMediaResourceId(resource.id)) self.statusContexts.removeValue(forKey: resource.id)
current.disposable.dispose() current.disposable.dispose()
} }
} }
@ -538,7 +538,7 @@ public final class MediaBox {
private func fileContext(for resource: MediaResource) -> (MediaBoxFileContext, () -> Void)? { private func fileContext(for resource: MediaResource) -> (MediaBoxFileContext, () -> Void)? {
assert(self.dataQueue.isCurrent()) assert(self.dataQueue.isCurrent())
let resourceId = WrappedMediaResourceId(resource.id) let resourceId = resource.id
var context: MediaBoxFileContext? var context: MediaBoxFileContext?
if let current = self.fileContexts[resourceId] { if let current = self.fileContexts[resourceId] {
@ -769,22 +769,22 @@ public final class MediaBox {
let dataQueue = self.dataQueue let dataQueue = self.dataQueue
self.dataQueue.async { self.dataQueue.async {
let context: MediaBoxKeepResourceContext let context: MediaBoxKeepResourceContext
if let current = self.keepResourceContexts[WrappedMediaResourceId(id)] { if let current = self.keepResourceContexts[id] {
context = current context = current
} else { } else {
context = MediaBoxKeepResourceContext() context = MediaBoxKeepResourceContext()
self.keepResourceContexts[WrappedMediaResourceId(id)] = context self.keepResourceContexts[id] = context
} }
let index = context.subscribers.add(Void()) let index = context.subscribers.add(Void())
disposable.set(ActionDisposable { [weak self, weak context] in disposable.set(ActionDisposable { [weak self, weak context] in
dataQueue.async { dataQueue.async {
guard let strongSelf = self, let context = context, let currentContext = strongSelf.keepResourceContexts[WrappedMediaResourceId(id)], currentContext === context else { guard let strongSelf = self, let context = context, let currentContext = strongSelf.keepResourceContexts[id], currentContext === context else {
return return
} }
currentContext.subscribers.remove(index) currentContext.subscribers.remove(index)
if currentContext.isEmpty { if currentContext.isEmpty {
strongSelf.keepResourceContexts.removeValue(forKey: WrappedMediaResourceId(id)) strongSelf.keepResourceContexts.removeValue(forKey: id)
} }
} }
}) })
@ -977,12 +977,12 @@ public final class MediaBox {
} }
} }
public func collectResourceCacheUsage(_ ids: [MediaResourceId]) -> Signal<[WrappedMediaResourceId: Int64], NoError> { public func collectResourceCacheUsage(_ ids: [MediaResourceId]) -> Signal<[MediaResourceId: Int64], NoError> {
return Signal { subscriber in return Signal { subscriber in
self.dataQueue.async { self.dataQueue.async {
var result: [WrappedMediaResourceId: Int64] = [:] var result: [MediaResourceId: Int64] = [:]
for id in ids { for id in ids {
let wrappedId = WrappedMediaResourceId(id) let wrappedId = id
let paths = self.storePathsForId(id) let paths = self.storePathsForId(id)
if let size = fileSize(paths.complete) { if let size = fileSize(paths.complete) {
result[wrappedId] = Int64(size) result[wrappedId] = Int64(size)
@ -997,16 +997,16 @@ public final class MediaBox {
} }
} }
public func collectOtherResourceUsage(excludeIds: Set<WrappedMediaResourceId>, combinedExcludeIds: Set<WrappedMediaResourceId>) -> Signal<(Int64, [String], Int64), NoError> { public func collectOtherResourceUsage(excludeIds: Set<MediaResourceId>, combinedExcludeIds: Set<MediaResourceId>) -> Signal<(Int64, [String], Int64), NoError> {
return Signal { subscriber in return Signal { subscriber in
self.dataQueue.async { self.dataQueue.async {
var result: Int64 = 0 var result: Int64 = 0
var excludeNames = Set<String>() var excludeNames = Set<String>()
for id in combinedExcludeIds { for id in combinedExcludeIds {
let partial = "\(self.fileNameForId(id.id))_partial" let partial = "\(self.fileNameForId(id))_partial"
let meta = "\(self.fileNameForId(id.id))_meta" let meta = "\(self.fileNameForId(id))_meta"
let complete = self.fileNameForId(id.id) let complete = self.fileNameForId(id)
excludeNames.insert(meta) excludeNames.insert(meta)
excludeNames.insert(partial) excludeNames.insert(partial)
@ -1044,7 +1044,7 @@ public final class MediaBox {
var excludePrefixes = Set<String>() var excludePrefixes = Set<String>()
for id in excludeIds { for id in excludeIds {
let cachedRepresentationPrefix = self.fileNameForId(id.id) let cachedRepresentationPrefix = self.fileNameForId(id)
excludePrefixes.insert(cachedRepresentationPrefix) excludePrefixes.insert(cachedRepresentationPrefix)
} }
@ -1091,7 +1091,7 @@ public final class MediaBox {
self.dataQueue.async { self.dataQueue.async {
var keepPrefixes: [String] = [] var keepPrefixes: [String] = []
for id in self.keepResourceContexts.keys { for id in self.keepResourceContexts.keys {
let resourcePaths = self.fileNamesForId(id.id) let resourcePaths = self.fileNamesForId(id)
keepPrefixes.append(resourcePaths.partial) keepPrefixes.append(resourcePaths.partial)
keepPrefixes.append(resourcePaths.complete) keepPrefixes.append(resourcePaths.complete)
} }
@ -1111,7 +1111,7 @@ public final class MediaBox {
} }
} }
public func removeCachedResources(_ ids: Set<WrappedMediaResourceId>, force: Bool = false) -> Signal<Void, NoError> { public func removeCachedResources(_ ids: Set<MediaResourceId>, force: Bool = false) -> Signal<Void, NoError> {
return Signal { subscriber in return Signal { subscriber in
self.dataQueue.async { self.dataQueue.async {
for id in ids { for id in ids {
@ -1123,14 +1123,14 @@ public final class MediaBox {
continue continue
} }
} }
let paths = self.storePathsForId(id.id) let paths = self.storePathsForId(id)
unlink(paths.complete) unlink(paths.complete)
unlink(paths.partial) unlink(paths.partial)
unlink(paths.partial + ".meta") unlink(paths.partial + ".meta")
self.fileContexts.removeValue(forKey: id) self.fileContexts.removeValue(forKey: id)
} }
let uniqueIds = Set(ids.map { $0.id.uniqueId }) let uniqueIds = Set(ids.map { $0.stringRepresentation })
var pathsToDelete: [String] = [] var pathsToDelete: [String] = []
@ -1161,14 +1161,12 @@ public final class MediaBox {
} }
} }
public func allFileContexts() -> Signal<[(partial: String, complete: String)], NoError> { public func allFileContexts() -> Signal<[(partial: String, complete: String)], NoError> {
return Signal { subscriber in return Signal { subscriber in
self.dataQueue.async { self.dataQueue.async {
var result: [(partial: String, complete: String)] = [] var result: [(partial: String, complete: String)] = []
for (id, _) in self.fileContexts { for (id, _) in self.fileContexts {
let paths = self.storePathsForId(id.id) let paths = self.storePathsForId(id)
result.append((partial: paths.partial, complete: paths.complete)) result.append((partial: paths.partial, complete: paths.complete))
} }
subscriber.putNext(result) subscriber.putNext(result)

View File

@ -1,33 +1,11 @@
import Foundation import Foundation
public protocol MediaResourceId { public struct MediaResourceId: Equatable, Hashable {
var uniqueId: String { get } public var stringRepresentation: String
var hashValue: Int { get }
func isEqual(to: MediaResourceId) -> Bool
}
public struct WrappedMediaResourceId: Hashable { public init(_ stringRepresentation: String) {
public let id: MediaResourceId self.stringRepresentation = stringRepresentation
public init(_ id: MediaResourceId) {
self.id = id
} }
public static func ==(lhs: WrappedMediaResourceId, rhs: WrappedMediaResourceId) -> Bool {
return lhs.id.isEqual(to: rhs.id)
}
// public var hashValue: Int {
// return self.id.hashValue
// }
public func hash(into hasher: inout Hasher) {
hasher.combine(self.id.hashValue)
}
}
public func anyHashableFromMediaResourceId(_ id: MediaResourceId) -> AnyHashable {
return AnyHashable(WrappedMediaResourceId(id))
} }
public protocol MediaResource { public protocol MediaResource {

View File

@ -8,7 +8,7 @@ final class SharedAccountMediaManager {
} }
private func fileNameForId(_ id: MediaResourceId) -> String { private func fileNameForId(_ id: MediaResourceId) -> String {
return "\(id.uniqueId)" return "\(id.stringRepresentation)"
} }
private func pathForId(_ id: MediaResourceId) -> String { private func pathForId(_ id: MediaResourceId) -> String {

View File

@ -565,11 +565,11 @@ public func storageUsageController(context: AccountContext, cacheUsagePromise: P
media[peerId] = categories media[peerId] = categories
} }
var clearResourceIds = Set<WrappedMediaResourceId>() var clearResourceIds = Set<MediaResourceId>()
for id in clearMediaIds { for id in clearMediaIds {
if let ids = stats.mediaResourceIds[id] { if let ids = stats.mediaResourceIds[id] {
for resourceId in ids { for resourceId in ids {
clearResourceIds.insert(WrappedMediaResourceId(resourceId)) clearResourceIds.insert(resourceId)
} }
} }
} }
@ -774,11 +774,11 @@ public func storageUsageController(context: AccountContext, cacheUsagePromise: P
} }
} }
var clearResourceIds = Set<WrappedMediaResourceId>() var clearResourceIds = Set<MediaResourceId>()
for id in clearMediaIds { for id in clearMediaIds {
if let ids = stats.mediaResourceIds[id] { if let ids = stats.mediaResourceIds[id] {
for resourceId in ids { for resourceId in ids {
clearResourceIds.insert(WrappedMediaResourceId(resourceId)) clearResourceIds.insert(resourceId)
} }
} }
} }
@ -901,11 +901,11 @@ public func storageUsageController(context: AccountContext, cacheUsagePromise: P
} }
} }
var clearResourceIds = Set<WrappedMediaResourceId>() var clearResourceIds = Set<MediaResourceId>()
for id in clearMediaIds { for id in clearMediaIds {
if let ids = stats.mediaResourceIds[id] { if let ids = stats.mediaResourceIds[id] {
for resourceId in ids { for resourceId in ids {
clearResourceIds.insert(WrappedMediaResourceId(resourceId)) clearResourceIds.insert(resourceId)
} }
} }
} }

View File

@ -66,7 +66,7 @@ struct ThemeGridControllerEntry: Comparable, Identifiable {
return .file(file.id, file.settings.colors, file.settings.intensity ?? 0) return .file(file.id, file.settings.colors, file.settings.intensity ?? 0)
case let .image(representations, _): case let .image(representations, _):
if let largest = largestImageRepresentation(representations) { if let largest = largestImageRepresentation(representations) {
return .image(largest.resource.id.uniqueId) return .image(largest.resource.id.stringRepresentation)
} else { } else {
return .image("") return .image("")
} }

View File

@ -312,7 +312,7 @@ class DiceAnimatedStickerNode: ASDisplayNode {
case let .local(animationName): case let .local(animationName):
source = AnimatedStickerNodeLocalFileSource(name: animationName) source = AnimatedStickerNodeLocalFileSource(name: animationName)
case let .resource(account, resource): case let .resource(account, resource):
source = AnimatedStickerResourceSource(account: account, resource: resource) source = AnimatedStickerResourceSource(account: account, resource: resource._asResource())
} }
let playbackMode: AnimatedStickerPlaybackMode let playbackMode: AnimatedStickerPlaybackMode

View File

@ -75,7 +75,7 @@ private func chatMessageStickerDatas(postbox: Postbox, file: TelegramMediaFile,
} }
var fetchThumbnail: Disposable? var fetchThumbnail: Disposable?
if !thumbnailResource.id.isEqual(to: resource.id) { if thumbnailResource.id != resource.id {
fetchThumbnail = fetchedMediaResource(mediaBox: postbox.mediaBox, reference: stickerPackFileReference(file).resourceReference(thumbnailResource)).start() fetchThumbnail = fetchedMediaResource(mediaBox: postbox.mediaBox, reference: stickerPackFileReference(file).resourceReference(thumbnailResource)).start()
} }
let disposable = (combineLatest(thumbnailData, fullSizeData) let disposable = (combineLatest(thumbnailData, fullSizeData)
@ -126,7 +126,7 @@ public func chatMessageAnimatedStickerDatas(postbox: Postbox, file: TelegramMedi
} }
var fetchThumbnail: Disposable? var fetchThumbnail: Disposable?
if !thumbnailResource.id.isEqual(to: resource.id) { if thumbnailResource.id != resource.id {
fetchThumbnail = fetchedMediaResource(mediaBox: postbox.mediaBox, reference: stickerPackFileReference(file).resourceReference(thumbnailResource)).start() fetchThumbnail = fetchedMediaResource(mediaBox: postbox.mediaBox, reference: stickerPackFileReference(file).resourceReference(thumbnailResource)).start()
} }
let disposable = (combineLatest(thumbnailData, fullSizeData) let disposable = (combineLatest(thumbnailData, fullSizeData)

View File

@ -116,7 +116,7 @@ public func downloadAppUpdate(account: Account, source: String, messageId: Int32
var dataDisposable: Disposable? var dataDisposable: Disposable?
var fetchDisposable: Disposable? var fetchDisposable: Disposable?
var statusDisposable: Disposable? var statusDisposable: Disposable?
let removeDisposable = account.postbox.mediaBox.removeCachedResources(Set([WrappedMediaResourceId(media.resource.id)])).start(completed: { let removeDisposable = account.postbox.mediaBox.removeCachedResources(Set([media.resource.id])).start(completed: {
let reference = MediaResourceReference.media(media: .message(message: MessageReference(message), media: media), resource: media.resource) let reference = MediaResourceReference.media(media: .message(message: MessageReference(message), media: media), resource: media.resource)
fetchDisposable = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: reference).start() fetchDisposable = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: reference).start()

View File

@ -78,7 +78,7 @@ private func areResourcesEqual(_ lhs: MediaResource, _ rhs: MediaResource) -> Bo
return true return true
} }
} }
return lhs.id.isEqual(to: rhs.id) return lhs.id == rhs.id
} }
private func findMediaResource(media: Media, previousMedia: Media?, resource: MediaResource) -> TelegramMediaResource? { private func findMediaResource(media: Media, previousMedia: Media?, resource: MediaResource) -> TelegramMediaResource? {
@ -89,12 +89,12 @@ private func findMediaResource(media: Media, previousMedia: Media?, resource: Me
return representation.resource return representation.resource
} }
} }
if representation.resource.id.isEqual(to: resource.id) { if representation.resource.id == resource.id {
return representation.resource return representation.resource
} }
} }
for representation in image.videoRepresentations { for representation in image.videoRepresentations {
if representation.resource.id.isEqual(to: resource.id) { if representation.resource.id == resource.id {
return representation.resource return representation.resource
} }
} }
@ -622,7 +622,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali
return .single(RevalidatedMediaResource(updatedResource: representation.resource, updatedReference: nil)) return .single(RevalidatedMediaResource(updatedResource: representation.resource, updatedReference: nil))
} }
} }
if representation.resource.id.isEqual(to: resource.id) { if representation.resource.id == resource.id {
return .single(RevalidatedMediaResource(updatedResource: representation.resource, updatedReference: nil)) return .single(RevalidatedMediaResource(updatedResource: representation.resource, updatedReference: nil))
} }
} }
@ -645,7 +645,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali
return .fail(.generic) return .fail(.generic)
} }
for representation in author.profileImageRepresentations { for representation in author.profileImageRepresentations {
if representation.resource.id.isEqual(to: resource.id) { if representation.resource.id == resource.id {
return .single(RevalidatedMediaResource(updatedResource: representation.resource, updatedReference: .avatar(peer: authorReference, resource: representation.resource))) return .single(RevalidatedMediaResource(updatedResource: representation.resource, updatedReference: .avatar(peer: authorReference, resource: representation.resource)))
} }
} }
@ -667,7 +667,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali
switch wallpaper { switch wallpaper {
case let .image(representations, _): case let .image(representations, _):
for representation in representations { for representation in representations {
if representation.resource.id.isEqual(to: resource.id) { if representation.resource.id == resource.id {
return .single(RevalidatedMediaResource(updatedResource: representation.resource, updatedReference: nil)) return .single(RevalidatedMediaResource(updatedResource: representation.resource, updatedReference: nil))
} }
} }
@ -685,7 +685,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali
return revalidationContext.stickerPack(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, stickerPack: packReference) return revalidationContext.stickerPack(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, stickerPack: packReference)
|> mapToSignal { result -> Signal<RevalidatedMediaResource, RevalidateMediaReferenceError> in |> mapToSignal { result -> Signal<RevalidatedMediaResource, RevalidateMediaReferenceError> in
if let thumbnail = result.0.thumbnail { if let thumbnail = result.0.thumbnail {
if thumbnail.resource.id.isEqual(to: resource.id) { if thumbnail.resource.id == resource.id {
return .single(RevalidatedMediaResource(updatedResource: thumbnail.resource, updatedReference: nil)) return .single(RevalidatedMediaResource(updatedResource: thumbnail.resource, updatedReference: nil))
} }
if let _ = thumbnail.resource as? CloudStickerPackThumbnailMediaResource, let _ = resource as? CloudStickerPackThumbnailMediaResource { if let _ = thumbnail.resource as? CloudStickerPackThumbnailMediaResource, let _ = resource as? CloudStickerPackThumbnailMediaResource {
@ -698,7 +698,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali
return revalidationContext.themes(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation) return revalidationContext.themes(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation)
|> mapToSignal { themes -> Signal<RevalidatedMediaResource, RevalidateMediaReferenceError> in |> mapToSignal { themes -> Signal<RevalidatedMediaResource, RevalidateMediaReferenceError> in
for theme in themes { for theme in themes {
if let file = theme.file, file.resource.id.isEqual(to: resource.id) { if let file = theme.file, file.resource.id == resource.id {
return .single(RevalidatedMediaResource(updatedResource: file.resource, updatedReference: nil)) return .single(RevalidatedMediaResource(updatedResource: file.resource, updatedReference: nil))
} }
} }

View File

@ -2599,7 +2599,7 @@ func replayFinalState(
} }
} }
case let .DeleteMessagesWithGlobalIds(ids): case let .DeleteMessagesWithGlobalIds(ids):
var resourceIds: [WrappedMediaResourceId] = [] var resourceIds: [MediaResourceId] = []
transaction.deleteMessagesWithGlobalIds(ids, forEachMedia: { media in transaction.deleteMessagesWithGlobalIds(ids, forEachMedia: { media in
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds) addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
}) })
@ -2616,7 +2616,7 @@ func replayFinalState(
if let message = transaction.getMessage(id) { if let message = transaction.getMessage(id) {
updatePeerChatInclusionWithMinTimestamp(transaction: transaction, id: id.peerId, minTimestamp: message.timestamp, forceRootGroupIfNotExists: false) updatePeerChatInclusionWithMinTimestamp(transaction: transaction, id: id.peerId, minTimestamp: message.timestamp, forceRootGroupIfNotExists: false)
} }
var resourceIds: [WrappedMediaResourceId] = [] var resourceIds: [MediaResourceId] = []
transaction.deleteMessagesInRange(peerId: id.peerId, namespace: id.namespace, minId: 1, maxId: id.id, forEachMedia: { media in transaction.deleteMessagesInRange(peerId: id.peerId, namespace: id.namespace, minId: 1, maxId: id.id, forEachMedia: { media in
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds) addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
}) })

View File

@ -32,7 +32,7 @@ func applyMediaResourceChanges(from: Media, to: Media, postbox: Postbox, force:
if let fromPreview = smallestImageRepresentation(fromFile.previewRepresentations), let toPreview = smallestImageRepresentation(toFile.previewRepresentations) { if let fromPreview = smallestImageRepresentation(fromFile.previewRepresentations), let toPreview = smallestImageRepresentation(toFile.previewRepresentations) {
copyOrMoveResourceData(from: fromPreview.resource, to: toPreview.resource, mediaBox: postbox.mediaBox) copyOrMoveResourceData(from: fromPreview.resource, to: toPreview.resource, mediaBox: postbox.mediaBox)
} }
if let fromVideoThumbnail = fromFile.videoThumbnails.first, let toVideoThumbnail = toFile.videoThumbnails.first, fromVideoThumbnail.resource.id.uniqueId != toVideoThumbnail.resource.id.uniqueId { if let fromVideoThumbnail = fromFile.videoThumbnails.first, let toVideoThumbnail = toFile.videoThumbnails.first, fromVideoThumbnail.resource.id != toVideoThumbnail.resource.id {
copyOrMoveResourceData(from: fromVideoThumbnail.resource, to: toVideoThumbnail.resource, mediaBox: postbox.mediaBox) copyOrMoveResourceData(from: fromVideoThumbnail.resource, to: toVideoThumbnail.resource, mediaBox: postbox.mediaBox)
} }
if (force || fromFile.size == toFile.size || fromFile.resource.size == toFile.resource.size) && fromFile.mimeType == toFile.mimeType { if (force || fromFile.size == toFile.size || fromFile.resource.size == toFile.resource.size) && fromFile.mimeType == toFile.mimeType {

View File

@ -1,7 +1,7 @@
import Foundation import Foundation
import Postbox import Postbox
public struct CloudFileMediaResourceId: MediaResourceId, Hashable, Equatable { public struct CloudFileMediaResourceId: Hashable, Equatable {
let datacenterId: Int let datacenterId: Int
let volumeId: Int64 let volumeId: Int64
let localId: Int32 let localId: Int32
@ -17,14 +17,6 @@ public struct CloudFileMediaResourceId: MediaResourceId, Hashable, Equatable {
public var uniqueId: String { public var uniqueId: String {
return "telegram-cloud-file-\(self.datacenterId)-\(self.volumeId)-\(self.localId)-\(self.secret)" return "telegram-cloud-file-\(self.datacenterId)-\(self.volumeId)-\(self.localId)-\(self.secret)"
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? CloudFileMediaResourceId {
return self == to
} else {
return false
}
}
} }
public final class CloudFileMediaResource: TelegramMediaResource { public final class CloudFileMediaResource: TelegramMediaResource {
@ -36,7 +28,7 @@ public final class CloudFileMediaResource: TelegramMediaResource {
public let fileReference: Data? public let fileReference: Data?
public var id: MediaResourceId { public var id: MediaResourceId {
return CloudFileMediaResourceId(datacenterId: self.datacenterId, volumeId: self.volumeId, localId: self.localId, secret: self.secret) return MediaResourceId(CloudFileMediaResourceId(datacenterId: self.datacenterId, volumeId: self.volumeId, localId: self.localId, secret: self.secret).uniqueId)
} }
public init(datacenterId: Int, volumeId: Int64, localId: Int32, secret: Int64, size: Int?, fileReference: Data?) { public init(datacenterId: Int, volumeId: Int64, localId: Int32, secret: Int64, size: Int?, fileReference: Data?) {
@ -87,7 +79,7 @@ public final class CloudFileMediaResource: TelegramMediaResource {
} }
} }
public struct CloudPhotoSizeMediaResourceId: MediaResourceId, Hashable, Equatable { public struct CloudPhotoSizeMediaResourceId: Hashable, Equatable {
let datacenterId: Int32 let datacenterId: Int32
let photoId: Int64 let photoId: Int64
let sizeSpec: String let sizeSpec: String
@ -101,14 +93,6 @@ public struct CloudPhotoSizeMediaResourceId: MediaResourceId, Hashable, Equatabl
public var uniqueId: String { public var uniqueId: String {
return "telegram-cloud-photo-size-\(self.datacenterId)-\(self.photoId)-\(self.sizeSpec)" return "telegram-cloud-photo-size-\(self.datacenterId)-\(self.photoId)-\(self.sizeSpec)"
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? CloudPhotoSizeMediaResourceId {
return self == to
} else {
return false
}
}
} }
public final class CloudPhotoSizeMediaResource: TelegramMediaResource { public final class CloudPhotoSizeMediaResource: TelegramMediaResource {
@ -120,7 +104,7 @@ public final class CloudPhotoSizeMediaResource: TelegramMediaResource {
public let fileReference: Data? public let fileReference: Data?
public var id: MediaResourceId { public var id: MediaResourceId {
return CloudPhotoSizeMediaResourceId(datacenterId: Int32(self.datacenterId), photoId: self.photoId, sizeSpec: self.sizeSpec) return MediaResourceId(CloudPhotoSizeMediaResourceId(datacenterId: Int32(self.datacenterId), photoId: self.photoId, sizeSpec: self.sizeSpec).uniqueId)
} }
public init(datacenterId: Int32, photoId: Int64, accessHash: Int64, sizeSpec: String, size: Int?, fileReference: Data?) { public init(datacenterId: Int32, photoId: Int64, accessHash: Int64, sizeSpec: String, size: Int?, fileReference: Data?) {
@ -171,7 +155,7 @@ public final class CloudPhotoSizeMediaResource: TelegramMediaResource {
} }
} }
public struct CloudDocumentSizeMediaResourceId: MediaResourceId, Hashable, Equatable { public struct CloudDocumentSizeMediaResourceId: Hashable, Equatable {
let datacenterId: Int32 let datacenterId: Int32
let documentId: Int64 let documentId: Int64
let sizeSpec: String let sizeSpec: String
@ -185,14 +169,6 @@ public struct CloudDocumentSizeMediaResourceId: MediaResourceId, Hashable, Equat
public var uniqueId: String { public var uniqueId: String {
return "telegram-cloud-document-size-\(self.datacenterId)-\(self.documentId)-\(self.sizeSpec)" return "telegram-cloud-document-size-\(self.datacenterId)-\(self.documentId)-\(self.sizeSpec)"
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? CloudDocumentSizeMediaResourceId {
return self == to
} else {
return false
}
}
} }
public final class CloudDocumentSizeMediaResource: TelegramMediaResource { public final class CloudDocumentSizeMediaResource: TelegramMediaResource {
@ -203,7 +179,7 @@ public final class CloudDocumentSizeMediaResource: TelegramMediaResource {
public let fileReference: Data? public let fileReference: Data?
public var id: MediaResourceId { public var id: MediaResourceId {
return CloudDocumentSizeMediaResourceId(datacenterId: Int32(self.datacenterId), documentId: self.documentId, sizeSpec: self.sizeSpec) return MediaResourceId(CloudDocumentSizeMediaResourceId(datacenterId: Int32(self.datacenterId), documentId: self.documentId, sizeSpec: self.sizeSpec).uniqueId)
} }
public init(datacenterId: Int32, documentId: Int64, accessHash: Int64, sizeSpec: String, fileReference: Data?) { public init(datacenterId: Int32, documentId: Int64, accessHash: Int64, sizeSpec: String, fileReference: Data?) {
@ -248,7 +224,7 @@ public enum CloudPeerPhotoSizeSpec: Int32 {
case fullSize case fullSize
} }
public struct CloudPeerPhotoSizeMediaResourceId: MediaResourceId, Hashable, Equatable { public struct CloudPeerPhotoSizeMediaResourceId: Hashable, Equatable {
let datacenterId: Int32 let datacenterId: Int32
let photoId: Int64? let photoId: Int64?
let sizeSpec: CloudPeerPhotoSizeSpec let sizeSpec: CloudPeerPhotoSizeSpec
@ -270,14 +246,6 @@ public struct CloudPeerPhotoSizeMediaResourceId: MediaResourceId, Hashable, Equa
return "telegram-peer-photo-size-\(self.datacenterId)-\(self.sizeSpec.rawValue)-\(self.volumeId ?? 0)-\(self.localId ?? 0)" return "telegram-peer-photo-size-\(self.datacenterId)-\(self.sizeSpec.rawValue)-\(self.volumeId ?? 0)-\(self.localId ?? 0)"
} }
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? CloudPeerPhotoSizeMediaResourceId {
return self == to
} else {
return false
}
}
} }
public final class CloudPeerPhotoSizeMediaResource: TelegramMediaResource { public final class CloudPeerPhotoSizeMediaResource: TelegramMediaResource {
@ -288,7 +256,7 @@ public final class CloudPeerPhotoSizeMediaResource: TelegramMediaResource {
public let localId: Int32? public let localId: Int32?
public var id: MediaResourceId { public var id: MediaResourceId {
return CloudPeerPhotoSizeMediaResourceId(datacenterId: Int32(self.datacenterId), photoId: self.photoId, sizeSpec: self.sizeSpec, volumeId: self.volumeId, localId: self.localId) return MediaResourceId(CloudPeerPhotoSizeMediaResourceId(datacenterId: Int32(self.datacenterId), photoId: self.photoId, sizeSpec: self.sizeSpec, volumeId: self.volumeId, localId: self.localId).uniqueId)
} }
public init(datacenterId: Int32, photoId: Int64?, sizeSpec: CloudPeerPhotoSizeSpec, volumeId: Int64?, localId: Int32?) { public init(datacenterId: Int32, photoId: Int64?, sizeSpec: CloudPeerPhotoSizeSpec, volumeId: Int64?, localId: Int32?) {
@ -336,7 +304,7 @@ public final class CloudPeerPhotoSizeMediaResource: TelegramMediaResource {
} }
} }
public struct CloudStickerPackThumbnailMediaResourceId: MediaResourceId, Hashable, Equatable { public struct CloudStickerPackThumbnailMediaResourceId: Hashable, Equatable {
let datacenterId: Int32 let datacenterId: Int32
let thumbVersion: Int32? let thumbVersion: Int32?
let volumeId: Int64? let volumeId: Int64?
@ -356,14 +324,6 @@ public struct CloudStickerPackThumbnailMediaResourceId: MediaResourceId, Hashabl
return "telegram-stickerpackthumbnail-\(self.datacenterId)-\(self.volumeId ?? 0)-\(self.localId ?? 0)" return "telegram-stickerpackthumbnail-\(self.datacenterId)-\(self.volumeId ?? 0)-\(self.localId ?? 0)"
} }
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? CloudStickerPackThumbnailMediaResourceId {
return self == to
} else {
return false
}
}
} }
public final class CloudStickerPackThumbnailMediaResource: TelegramMediaResource { public final class CloudStickerPackThumbnailMediaResource: TelegramMediaResource {
@ -373,7 +333,7 @@ public final class CloudStickerPackThumbnailMediaResource: TelegramMediaResource
public let localId: Int32? public let localId: Int32?
public var id: MediaResourceId { public var id: MediaResourceId {
return CloudStickerPackThumbnailMediaResourceId(datacenterId: Int32(self.datacenterId), thumbVersion: self.thumbVersion, volumeId: self.volumeId, localId: self.localId) return MediaResourceId(CloudStickerPackThumbnailMediaResourceId(datacenterId: Int32(self.datacenterId), thumbVersion: self.thumbVersion, volumeId: self.volumeId, localId: self.localId).uniqueId)
} }
public init(datacenterId: Int32, thumbVersion: Int32?, volumeId: Int64?, localId: Int32?) { public init(datacenterId: Int32, thumbVersion: Int32?, volumeId: Int64?, localId: Int32?) {
@ -418,7 +378,7 @@ public final class CloudStickerPackThumbnailMediaResource: TelegramMediaResource
} }
} }
public struct CloudDocumentMediaResourceId: MediaResourceId, Hashable, Equatable { public struct CloudDocumentMediaResourceId: Hashable, Equatable {
public let datacenterId: Int public let datacenterId: Int
public let fileId: Int64 public let fileId: Int64
@ -430,14 +390,6 @@ public struct CloudDocumentMediaResourceId: MediaResourceId, Hashable, Equatable
public var uniqueId: String { public var uniqueId: String {
return "telegram-cloud-document-\(self.datacenterId)-\(self.fileId)" return "telegram-cloud-document-\(self.datacenterId)-\(self.fileId)"
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? CloudDocumentMediaResourceId {
return self == to
} else {
return false
}
}
} }
public final class CloudDocumentMediaResource: TelegramMediaResource { public final class CloudDocumentMediaResource: TelegramMediaResource {
@ -449,7 +401,7 @@ public final class CloudDocumentMediaResource: TelegramMediaResource {
public let fileName: String? public let fileName: String?
public var id: MediaResourceId { public var id: MediaResourceId {
return CloudDocumentMediaResourceId(datacenterId: self.datacenterId, fileId: self.fileId) return MediaResourceId(CloudDocumentMediaResourceId(datacenterId: self.datacenterId, fileId: self.fileId).uniqueId)
} }
public init(datacenterId: Int, fileId: Int64, accessHash: Int64, size: Int?, fileReference: Data?, fileName: String?) { public init(datacenterId: Int, fileId: Int64, accessHash: Int64, size: Int?, fileReference: Data?, fileName: String?) {
@ -504,20 +456,12 @@ public final class CloudDocumentMediaResource: TelegramMediaResource {
} }
} }
public struct LocalFileMediaResourceId: MediaResourceId, Hashable, Equatable { public struct LocalFileMediaResourceId: Hashable, Equatable {
public let fileId: Int64 public let fileId: Int64
public var uniqueId: String { public var uniqueId: String {
return "telegram-local-file-\(self.fileId)" return "telegram-local-file-\(self.fileId)"
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? LocalFileMediaResourceId {
return self == to
} else {
return false
}
}
} }
public class LocalFileMediaResource: TelegramMediaResource, Codable { public class LocalFileMediaResource: TelegramMediaResource, Codable {
@ -569,7 +513,7 @@ public class LocalFileMediaResource: TelegramMediaResource, Codable {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return LocalFileMediaResourceId(fileId: self.fileId) return MediaResourceId(LocalFileMediaResourceId(fileId: self.fileId).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -581,20 +525,12 @@ public class LocalFileMediaResource: TelegramMediaResource, Codable {
} }
} }
public struct LocalFileReferenceMediaResourceId: MediaResourceId, Hashable, Equatable { public struct LocalFileReferenceMediaResourceId: Hashable, Equatable {
public let randomId: Int64 public let randomId: Int64
public var uniqueId: String { public var uniqueId: String {
return "local-file-\(self.randomId)" return "local-file-\(self.randomId)"
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? LocalFileReferenceMediaResourceId {
return self == to
} else {
return false
}
}
} }
public class LocalFileReferenceMediaResource: TelegramMediaResource { public class LocalFileReferenceMediaResource: TelegramMediaResource {
@ -629,7 +565,7 @@ public class LocalFileReferenceMediaResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return LocalFileReferenceMediaResourceId(randomId: self.randomId) return MediaResourceId(LocalFileReferenceMediaResourceId(randomId: self.randomId).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -641,17 +577,9 @@ public class LocalFileReferenceMediaResource: TelegramMediaResource {
} }
} }
public struct HttpReferenceMediaResourceId: MediaResourceId, Hashable, Equatable { public struct HttpReferenceMediaResourceId: Hashable, Equatable {
public let url: String public let url: String
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? HttpReferenceMediaResourceId {
return self == to
} else {
return false
}
}
public var uniqueId: String { public var uniqueId: String {
return "http-\(persistentHash32(self.url))" return "http-\(persistentHash32(self.url))"
} }
@ -685,7 +613,7 @@ public final class HttpReferenceMediaResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return HttpReferenceMediaResourceId(url: self.url) return MediaResourceId(HttpReferenceMediaResourceId(url: self.url).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -697,19 +625,11 @@ public final class HttpReferenceMediaResource: TelegramMediaResource {
} }
} }
public struct WebFileReferenceMediaResourceId: MediaResourceId, Hashable, Equatable { public struct WebFileReferenceMediaResourceId: Hashable, Equatable {
public let url: String public let url: String
public let accessHash: Int64 public let accessHash: Int64
public let size: Int32 public let size: Int32
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? WebFileReferenceMediaResourceId {
return self == to
} else {
return false
}
}
public var uniqueId: String { public var uniqueId: String {
return "proxy-\(persistentHash32(self.url))-\(size)-\(accessHash)" return "proxy-\(persistentHash32(self.url))-\(size)-\(accessHash)"
} }
@ -739,7 +659,7 @@ public final class WebFileReferenceMediaResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return WebFileReferenceMediaResourceId(url: self.url, accessHash: accessHash, size: self.size) return MediaResourceId(WebFileReferenceMediaResourceId(url: self.url, accessHash: accessHash, size: self.size).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -752,7 +672,7 @@ public final class WebFileReferenceMediaResource: TelegramMediaResource {
} }
public struct SecretFileMediaResourceId: MediaResourceId, Hashable, Equatable { public struct SecretFileMediaResourceId: Hashable, Equatable {
public let fileId: Int64 public let fileId: Int64
public let datacenterId: Int32 public let datacenterId: Int32
@ -764,14 +684,6 @@ public struct SecretFileMediaResourceId: MediaResourceId, Hashable, Equatable {
self.fileId = fileId self.fileId = fileId
self.datacenterId = datacenterId self.datacenterId = datacenterId
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? SecretFileMediaResourceId {
return self == to
} else {
return false
}
}
} }
public final class SecretFileMediaResource: TelegramMediaResource { public final class SecretFileMediaResource: TelegramMediaResource {
@ -813,7 +725,7 @@ public final class SecretFileMediaResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return SecretFileMediaResourceId(fileId: self.fileId, datacenterId: Int32(self.datacenterId)) return MediaResourceId(SecretFileMediaResourceId(fileId: self.fileId, datacenterId: Int32(self.datacenterId)).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -843,7 +755,7 @@ public final class SecretFileMediaResource: TelegramMediaResource {
} }
} }
public struct EmptyMediaResourceId: MediaResourceId { public struct EmptyMediaResourceId {
public var uniqueId: String { public var uniqueId: String {
return "empty-resource" return "empty-resource"
} }
@ -851,10 +763,6 @@ public struct EmptyMediaResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return 0 return 0
} }
public func isEqual(to: MediaResourceId) -> Bool {
return to is EmptyMediaResourceId
}
} }
public final class EmptyMediaResource: TelegramMediaResource { public final class EmptyMediaResource: TelegramMediaResource {
@ -868,7 +776,7 @@ public final class EmptyMediaResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return EmptyMediaResourceId() return MediaResourceId(EmptyMediaResourceId().uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -876,7 +784,7 @@ public final class EmptyMediaResource: TelegramMediaResource {
} }
} }
public struct WallpaperDataResourceId: MediaResourceId { public struct WallpaperDataResourceId {
public var uniqueId: String { public var uniqueId: String {
return "wallpaper-\(self.slug)" return "wallpaper-\(self.slug)"
} }
@ -890,16 +798,6 @@ public struct WallpaperDataResourceId: MediaResourceId {
public init(slug: String) { public init(slug: String) {
self.slug = slug self.slug = slug
} }
public func isEqual(to: MediaResourceId) -> Bool {
guard let to = to as? WallpaperDataResourceId else {
return false
}
if self.slug != to.slug {
return false
}
return true
}
} }
public final class WallpaperDataResource: TelegramMediaResource { public final class WallpaperDataResource: TelegramMediaResource {
@ -918,7 +816,7 @@ public final class WallpaperDataResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return WallpaperDataResourceId(slug: self.slug) return MediaResourceId(WallpaperDataResourceId(slug: self.slug).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {

View File

@ -1,7 +1,7 @@
import Foundation import Foundation
import Postbox import Postbox
public struct SecureFileMediaResourceId: MediaResourceId { public struct SecureFileMediaResourceId {
public let fileId: Int64 public let fileId: Int64
public init(fileId: Int64) { public init(fileId: Int64) {
@ -15,21 +15,13 @@ public struct SecureFileMediaResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.fileId.hashValue return self.fileId.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? SecureFileMediaResourceId {
return self.fileId == to.fileId
} else {
return false
}
}
} }
public final class SecureFileMediaResource: TelegramMediaResource { public final class SecureFileMediaResource: TelegramMediaResource {
public let file: SecureIdFileReference public let file: SecureIdFileReference
public var id: MediaResourceId { public var id: MediaResourceId {
return SecureFileMediaResourceId(fileId: self.file.id) return MediaResourceId(SecureFileMediaResourceId(fileId: self.file.id).uniqueId)
} }
public var datacenterId: Int { public var datacenterId: Int {

View File

@ -554,7 +554,7 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
return false return false
} }
if !self.resource.id.isEqual(to: other.resource.id) { if self.resource.id != other.resource.id {
return false return false
} }

View File

@ -340,7 +340,7 @@ public final class TelegramMediaImageRepresentation: PostboxCoding, Equatable, C
if self.dimensions != other.dimensions { if self.dimensions != other.dimensions {
return false return false
} }
if !self.resource.id.isEqual(to: other.resource.id) { if self.resource.id != other.resource.id {
return false return false
} }
if self.progressiveSizes != other.progressiveSizes { if self.progressiveSizes != other.progressiveSizes {

View File

@ -1,6 +1,8 @@
import SwiftSignalKit import SwiftSignalKit
import Postbox import Postbox
public typealias EngineExportedPeerInvitation = ExportedInvitation
public extension TelegramEngine.EngineData.Item { public extension TelegramEngine.EngineData.Item {
enum Peer { enum Peer {
public struct Peer: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { public struct Peer: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
@ -192,5 +194,39 @@ public extension TelegramEngine.EngineData.Item {
} }
} }
} }
public struct ExportedInvitation: TelegramEngineDataItem, PostboxViewDataItem {
public typealias Result = Optional<EngineExportedPeerInvitation>
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
guard let cachedPeerData = view.cachedPeerData else {
return nil
}
switch cachedPeerData {
case let channel as CachedChannelData:
return channel.exportedInvitation
case let group as CachedGroupData:
return group.exportedInvitation
default:
return nil
}
}
}
} }
} }

View File

@ -3,27 +3,27 @@ import Postbox
import SwiftSignalKit import SwiftSignalKit
import TelegramApi import TelegramApi
func addMessageMediaResourceIdsToRemove(media: Media, resourceIds: inout [WrappedMediaResourceId]) { func addMessageMediaResourceIdsToRemove(media: Media, resourceIds: inout [MediaResourceId]) {
if let image = media as? TelegramMediaImage { if let image = media as? TelegramMediaImage {
for representation in image.representations { for representation in image.representations {
resourceIds.append(WrappedMediaResourceId(representation.resource.id)) resourceIds.append(representation.resource.id)
} }
} else if let file = media as? TelegramMediaFile { } else if let file = media as? TelegramMediaFile {
for representation in file.previewRepresentations { for representation in file.previewRepresentations {
resourceIds.append(WrappedMediaResourceId(representation.resource.id)) resourceIds.append(representation.resource.id)
} }
resourceIds.append(WrappedMediaResourceId(file.resource.id)) resourceIds.append(file.resource.id)
} }
} }
func addMessageMediaResourceIdsToRemove(message: Message, resourceIds: inout [WrappedMediaResourceId]) { func addMessageMediaResourceIdsToRemove(message: Message, resourceIds: inout [MediaResourceId]) {
for media in message.media { for media in message.media {
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds) addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
} }
} }
public func _internal_deleteMessages(transaction: Transaction, mediaBox: MediaBox, ids: [MessageId], deleteMedia: Bool = true, manualAddMessageThreadStatsDifference: ((MessageId, Int, Int) -> Void)? = nil) { public func _internal_deleteMessages(transaction: Transaction, mediaBox: MediaBox, ids: [MessageId], deleteMedia: Bool = true, manualAddMessageThreadStatsDifference: ((MessageId, Int, Int) -> Void)? = nil) {
var resourceIds: [WrappedMediaResourceId] = [] var resourceIds: [MediaResourceId] = []
if deleteMedia { if deleteMedia {
for id in ids { for id in ids {
if id.peerId.namespace == Namespaces.Peer.SecretChat { if id.peerId.namespace == Namespaces.Peer.SecretChat {
@ -57,7 +57,7 @@ public func _internal_deleteMessages(transaction: Transaction, mediaBox: MediaBo
} }
func _internal_deleteAllMessagesWithAuthor(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, authorId: PeerId, namespace: MessageId.Namespace) { func _internal_deleteAllMessagesWithAuthor(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, authorId: PeerId, namespace: MessageId.Namespace) {
var resourceIds: [WrappedMediaResourceId] = [] var resourceIds: [MediaResourceId] = []
transaction.removeAllMessagesWithAuthor(peerId, authorId: authorId, namespace: namespace, forEachMedia: { media in transaction.removeAllMessagesWithAuthor(peerId, authorId: authorId, namespace: namespace, forEachMedia: { media in
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds) addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
}) })
@ -67,7 +67,7 @@ func _internal_deleteAllMessagesWithAuthor(transaction: Transaction, mediaBox: M
} }
func _internal_deleteAllMessagesWithForwardAuthor(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, forwardAuthorId: PeerId, namespace: MessageId.Namespace) { func _internal_deleteAllMessagesWithForwardAuthor(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, forwardAuthorId: PeerId, namespace: MessageId.Namespace) {
var resourceIds: [WrappedMediaResourceId] = [] var resourceIds: [MediaResourceId] = []
transaction.removeAllMessagesWithForwardAuthor(peerId, forwardAuthorId: forwardAuthorId, namespace: namespace, forEachMedia: { media in transaction.removeAllMessagesWithForwardAuthor(peerId, forwardAuthorId: forwardAuthorId, namespace: namespace, forEachMedia: { media in
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds) addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
}) })
@ -78,7 +78,7 @@ func _internal_deleteAllMessagesWithForwardAuthor(transaction: Transaction, medi
func _internal_clearHistory(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, namespaces: MessageIdNamespaces) { func _internal_clearHistory(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, namespaces: MessageIdNamespaces) {
if peerId.namespace == Namespaces.Peer.SecretChat { if peerId.namespace == Namespaces.Peer.SecretChat {
var resourceIds: [WrappedMediaResourceId] = [] var resourceIds: [MediaResourceId] = []
transaction.withAllMessages(peerId: peerId, { message in transaction.withAllMessages(peerId: peerId, { message in
addMessageMediaResourceIdsToRemove(message: message, resourceIds: &resourceIds) addMessageMediaResourceIdsToRemove(message: message, resourceIds: &resourceIds)
return true return true

View File

@ -1,17 +1,5 @@
import Postbox import Postbox
public final class EngineMediaResource {
private let resource: MediaResource
public init(_ resource: MediaResource) {
self.resource = resource
}
public func _asResource() -> MediaResource {
return self.resource
}
}
public enum EngineMedia { public enum EngineMedia {
public typealias Id = MediaId public typealias Id = MediaId

View File

@ -103,7 +103,7 @@ func managedApplyPendingScheduledMessagesActions(postbox: Postbox, network: Netw
}) })
|> then( |> then(
postbox.transaction { transaction -> Void in postbox.transaction { transaction -> Void in
var resourceIds: [WrappedMediaResourceId] = [] var resourceIds: [MediaResourceId] = []
transaction.deleteMessages([entry.id], forEachMedia: { media in transaction.deleteMessages([entry.id], forEachMedia: { media in
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds) addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
}) })

View File

@ -544,7 +544,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
}) })
if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated { if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated {
var resourceIds: [WrappedMediaResourceId] = [] var resourceIds: [MediaResourceId] = []
transaction.deleteMessagesInRange(peerId: peerId, namespace: minAvailableMessageId.namespace, minId: 1, maxId: minAvailableMessageId.id, forEachMedia: { media in transaction.deleteMessagesInRange(peerId: peerId, namespace: minAvailableMessageId.namespace, minId: 1, maxId: minAvailableMessageId.id, forEachMedia: { media in
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds) addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
}) })

View File

@ -47,7 +47,7 @@ private enum CollectCacheUsageStatsError {
private final class CacheUsageStatsState { private final class CacheUsageStatsState {
var media: [PeerId: [PeerCacheUsageCategory: [MediaId: Int64]]] = [:] var media: [PeerId: [PeerCacheUsageCategory: [MediaId: Int64]]] = [:]
var mediaResourceIds: [MediaId: [MediaResourceId]] = [:] var mediaResourceIds: [MediaId: [MediaResourceId]] = [:]
var allResourceIds = Set<WrappedMediaResourceId>() var allResourceIds = Set<MediaResourceId>()
var lowerBound: MessageIndex? var lowerBound: MessageIndex?
var upperBound: MessageIndex? var upperBound: MessageIndex?
} }
@ -61,10 +61,10 @@ func _internal_collectCacheUsageStats(account: Account, peerId: PeerId? = nil, a
let state = Atomic<CacheUsageStatsState>(value: initialState) let state = Atomic<CacheUsageStatsState>(value: initialState)
let excludeResourceIds = account.postbox.transaction { transaction -> Set<WrappedMediaResourceId> in let excludeResourceIds = account.postbox.transaction { transaction -> Set<MediaResourceId> in
var result = Set<WrappedMediaResourceId>() var result = Set<MediaResourceId>()
transaction.enumeratePreferencesEntries({ entry in transaction.enumeratePreferencesEntries({ entry in
result.formUnion(entry.relatedResources.map(WrappedMediaResourceId.init)) result.formUnion(entry.relatedResources)
return true return true
}) })
return result return result
@ -85,7 +85,7 @@ func _internal_collectCacheUsageStats(account: Account, peerId: PeerId? = nil, a
} }
} }
var resourceIdToMediaId: [WrappedMediaResourceId: (MediaId, PeerCacheUsageCategory)] = [:] var resourceIdToMediaId: [MediaResourceId: (MediaId, PeerCacheUsageCategory)] = [:]
var mediaResourceIds: [MediaId: [MediaResourceId]] = [:] var mediaResourceIds: [MediaId: [MediaResourceId]] = [:]
var resourceIds: [MediaResourceId] = [] var resourceIds: [MediaResourceId] = []
for (id, media) in mediaRefs { for (id, media) in mediaRefs {
@ -112,7 +112,7 @@ func _internal_collectCacheUsageStats(account: Account, peerId: PeerId? = nil, a
if let image = media as? TelegramMediaImage { if let image = media as? TelegramMediaImage {
for representation in image.representations { for representation in image.representations {
resourceIds.append(representation.resource.id) resourceIds.append(representation.resource.id)
resourceIdToMediaId[WrappedMediaResourceId(representation.resource.id)] = (id, .image) resourceIdToMediaId[representation.resource.id] = (id, .image)
mediaResourceIds[id]!.append(representation.resource.id) mediaResourceIds[id]!.append(representation.resource.id)
} }
} else if let file = media as? TelegramMediaFile { } else if let file = media as? TelegramMediaFile {
@ -131,11 +131,11 @@ func _internal_collectCacheUsageStats(account: Account, peerId: PeerId? = nil, a
} }
for representation in file.previewRepresentations { for representation in file.previewRepresentations {
resourceIds.append(representation.resource.id) resourceIds.append(representation.resource.id)
resourceIdToMediaId[WrappedMediaResourceId(representation.resource.id)] = (id, category) resourceIdToMediaId[representation.resource.id] = (id, category)
mediaResourceIds[id]!.append(representation.resource.id) mediaResourceIds[id]!.append(representation.resource.id)
} }
resourceIds.append(file.resource.id) resourceIds.append(file.resource.id)
resourceIdToMediaId[WrappedMediaResourceId(file.resource.id)] = (id, category) resourceIdToMediaId[file.resource.id] = (id, category)
mediaResourceIds[id]!.append(file.resource.id) mediaResourceIds[id]!.append(file.resource.id)
} }
} }
@ -165,13 +165,13 @@ func _internal_collectCacheUsageStats(account: Account, peerId: PeerId? = nil, a
for (id, ids) in mediaResourceIds { for (id, ids) in mediaResourceIds {
state.mediaResourceIds[id] = ids state.mediaResourceIds[id] = ids
for resourceId in ids { for resourceId in ids {
state.allResourceIds.insert(WrappedMediaResourceId(resourceId)) state.allResourceIds.insert(resourceId)
} }
} }
} }
if updatedLowerBound == nil { if updatedLowerBound == nil {
if peerId != nil { if peerId != nil {
let (finalMedia, finalMediaResourceIds, _) = state.with { state -> ([PeerId: [PeerCacheUsageCategory: [MediaId: Int64]]], [MediaId: [MediaResourceId]], Set<WrappedMediaResourceId>) in let (finalMedia, finalMediaResourceIds, _) = state.with { state -> ([PeerId: [PeerCacheUsageCategory: [MediaId: Int64]]], [MediaId: [MediaResourceId]], Set<MediaResourceId>) in
return (state.media, state.mediaResourceIds, state.allResourceIds) return (state.media, state.mediaResourceIds, state.allResourceIds)
} }
return account.postbox.transaction { transaction -> CacheUsageStats in return account.postbox.transaction { transaction -> CacheUsageStats in
@ -191,7 +191,7 @@ func _internal_collectCacheUsageStats(account: Account, peerId: PeerId? = nil, a
} }
} }
let (finalMedia, finalMediaResourceIds, allResourceIds) = state.with { state -> ([PeerId: [PeerCacheUsageCategory: [MediaId: Int64]]], [MediaId: [MediaResourceId]], Set<WrappedMediaResourceId>) in let (finalMedia, finalMediaResourceIds, allResourceIds) = state.with { state -> ([PeerId: [PeerCacheUsageCategory: [MediaId: Int64]]], [MediaId: [MediaResourceId]], Set<MediaResourceId>) in
return (state.media, state.mediaResourceIds, state.allResourceIds) return (state.media, state.mediaResourceIds, state.allResourceIds)
} }
@ -290,6 +290,6 @@ func _internal_collectCacheUsageStats(account: Account, peerId: PeerId? = nil, a
} }
} }
func _internal_clearCachedMediaResources(account: Account, mediaResourceIds: Set<WrappedMediaResourceId>) -> Signal<Void, NoError> { func _internal_clearCachedMediaResources(account: Account, mediaResourceIds: Set<MediaResourceId>) -> Signal<Void, NoError> {
return account.postbox.mediaBox.removeCachedResources(mediaResourceIds) return account.postbox.mediaBox.removeCachedResources(mediaResourceIds)
} }

View File

@ -1,6 +1,150 @@
import Foundation
import SwiftSignalKit import SwiftSignalKit
import Postbox import Postbox
public final class EngineMediaResource: Equatable {
public struct ByteRange {
public enum Priority {
case `default`
case elevated
case maximum
}
public var range: Range<Int>
public var priority: Priority
public init(range: Range<Int>, priority: Priority) {
self.range = range
self.priority = priority
}
}
public final class Fetch {
public enum Result {
case dataPart(resourceOffset: Int, data: Data, range: Range<Int>, complete: Bool)
case resourceSizeUpdated(Int)
case progressUpdated(Float)
case replaceHeader(data: Data, range: Range<Int>)
case moveLocalFile(path: String)
case moveTempFile(file: TempBoxFile)
case copyLocalItem(MediaResourceDataFetchCopyLocalItem)
case reset
}
public enum Error {
case generic
}
public let signal: (
Signal<[EngineMediaResource.ByteRange], NoError>
) -> Signal<Result, Error>
public init(_ signal: @escaping (
Signal<[EngineMediaResource.ByteRange], NoError>
) -> Signal<Result, Error>) {
self.signal = signal
}
}
public final class ResourceData {
public let path: String
public let availableSize: Int
public let isComplete: Bool
public init(
path: String,
availableSize: Int,
isComplete: Bool
) {
self.path = path
self.availableSize = availableSize
self.isComplete = isComplete
}
}
public struct Id: Equatable, Hashable {
public var stringRepresentation: String
public init(_ stringRepresentation: String) {
self.stringRepresentation = stringRepresentation
}
public init(_ id: MediaResourceId) {
self.stringRepresentation = id.stringRepresentation
}
}
private let resource: MediaResource
public init(_ resource: MediaResource) {
self.resource = resource
}
public func _asResource() -> MediaResource {
return self.resource
}
public var id: Id {
return Id(self.resource.id)
}
public static func ==(lhs: EngineMediaResource, rhs: EngineMediaResource) -> Bool {
return lhs.resource.isEqual(to: rhs.resource)
}
}
public extension MediaResource {
func fetch(engine: TelegramEngine, parameters: MediaResourceFetchParameters?) -> EngineMediaResource.Fetch {
return EngineMediaResource.Fetch { ranges in
return Signal { subscriber in
return engine.account.postbox.mediaBox.fetchResource!(
self,
ranges |> map { ranges -> [(Range<Int>, MediaBoxFetchPriority)] in
return ranges.map { range -> (Range<Int>, MediaBoxFetchPriority) in
let mappedPriority: MediaBoxFetchPriority
switch range.priority {
case .default:
mappedPriority = .default
case .elevated:
mappedPriority = .elevated
case .maximum:
mappedPriority = .maximum
}
return (range.range, mappedPriority)
}
},
parameters
).start(next: { result in
let mappedResult: EngineMediaResource.Fetch.Result
switch result {
case let .dataPart(resourceOffset, data, range, complete):
mappedResult = .dataPart(resourceOffset: resourceOffset, data: data, range: range, complete: complete)
case let .resourceSizeUpdated(size):
mappedResult = .resourceSizeUpdated(size)
case let .progressUpdated(progress):
mappedResult = .progressUpdated(progress)
case let .replaceHeader(data, range):
mappedResult = .replaceHeader(data: data, range: range)
case let .moveLocalFile(path):
mappedResult = .moveLocalFile(path: path)
case let .moveTempFile(file):
mappedResult = .moveTempFile(file: file)
case let .copyLocalItem(item):
mappedResult = .copyLocalItem(item)
case .reset:
mappedResult = .reset
}
subscriber.putNext(mappedResult)
}, error: { _ in
subscriber.putError(.generic)
}, completed: {
subscriber.putCompletion()
})
}
}
}
}
public extension TelegramEngine { public extension TelegramEngine {
final class Resources { final class Resources {
private let account: Account private let account: Account
@ -17,8 +161,20 @@ public extension TelegramEngine {
return _internal_collectCacheUsageStats(account: self.account, peerId: peerId, additionalCachePaths: additionalCachePaths, logFilesPath: logFilesPath) return _internal_collectCacheUsageStats(account: self.account, peerId: peerId, additionalCachePaths: additionalCachePaths, logFilesPath: logFilesPath)
} }
public func clearCachedMediaResources(mediaResourceIds: Set<WrappedMediaResourceId>) -> Signal<Void, NoError> { public func clearCachedMediaResources(mediaResourceIds: Set<MediaResourceId>) -> Signal<Void, NoError> {
return _internal_clearCachedMediaResources(account: self.account, mediaResourceIds: mediaResourceIds) return _internal_clearCachedMediaResources(account: self.account, mediaResourceIds: mediaResourceIds)
} }
public func data(id: String) -> Signal<EngineMediaResource.ResourceData, NoError> {
preconditionFailure()
}
public func fetch(id: String, fetch: EngineMediaResource.Fetch) -> Signal<Never, NoError> {
preconditionFailure()
}
public func cancelAllFetches(id: String) {
preconditionFailure()
}
} }
} }

View File

@ -9075,11 +9075,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
media[peerId] = categories media[peerId] = categories
} }
var clearResourceIds = Set<WrappedMediaResourceId>() var clearResourceIds = Set<MediaResourceId>()
for id in clearMediaIds { for id in clearMediaIds {
if let ids = stats.mediaResourceIds[id] { if let ids = stats.mediaResourceIds[id] {
for resourceId in ids { for resourceId in ids {
clearResourceIds.insert(WrappedMediaResourceId(resourceId)) clearResourceIds.insert(resourceId)
} }
} }
} }

View File

@ -179,14 +179,14 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
if let file = media as? TelegramMediaFile { if let file = media as? TelegramMediaFile {
updatedFile = file updatedFile = file
if let previousFile = previousFile { if let previousFile = previousFile {
updatedMedia = !previousFile.resource.id.isEqual(to: file.resource.id) updatedMedia = previousFile.resource.id != file.resource.id
} else if previousFile == nil { } else if previousFile == nil {
updatedMedia = true updatedMedia = true
} }
} else if let webPage = media as? TelegramMediaWebpage, case let .Loaded(content) = webPage.content, let file = content.file { } else if let webPage = media as? TelegramMediaWebpage, case let .Loaded(content) = webPage.content, let file = content.file {
updatedFile = file updatedFile = file
if let previousFile = previousFile { if let previousFile = previousFile {
updatedMedia = !previousFile.resource.id.isEqual(to: file.resource.id) updatedMedia = previousFile.resource.id != file.resource.id
} else if previousFile == nil { } else if previousFile == nil {
updatedMedia = true updatedMedia = true
} }

View File

@ -10,7 +10,7 @@ import Emoji
import AppBundle import AppBundle
import AccountContext import AccountContext
public struct EmojiThumbnailResourceId: MediaResourceId { public struct EmojiThumbnailResourceId {
public let emoji: String public let emoji: String
public var uniqueId: String { public var uniqueId: String {
@ -20,14 +20,6 @@ public struct EmojiThumbnailResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.emoji.hashValue return self.emoji.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? EmojiThumbnailResourceId {
return self.emoji == to.emoji
} else {
return false
}
}
} }
public class EmojiThumbnailResource: TelegramMediaResource { public class EmojiThumbnailResource: TelegramMediaResource {
@ -46,7 +38,7 @@ public class EmojiThumbnailResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return EmojiThumbnailResourceId(emoji: self.emoji) return MediaResourceId(EmojiThumbnailResourceId(emoji: self.emoji).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {
@ -58,7 +50,7 @@ public class EmojiThumbnailResource: TelegramMediaResource {
} }
} }
public struct EmojiSpriteResourceId: MediaResourceId { public struct EmojiSpriteResourceId {
public let packId: UInt8 public let packId: UInt8
public let stickerId: UInt8 public let stickerId: UInt8
@ -69,14 +61,6 @@ public struct EmojiSpriteResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.packId.hashValue &* 31 &+ self.stickerId.hashValue return self.packId.hashValue &* 31 &+ self.stickerId.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? EmojiSpriteResourceId {
return self.packId == to.packId && self.stickerId == to.stickerId
} else {
return false
}
}
} }
public class EmojiSpriteResource: TelegramMediaResource { public class EmojiSpriteResource: TelegramMediaResource {
@ -99,7 +83,7 @@ public class EmojiSpriteResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return EmojiSpriteResourceId(packId: self.packId, stickerId: self.stickerId) return MediaResourceId(EmojiSpriteResourceId(packId: self.packId, stickerId: self.stickerId).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {

View File

@ -698,7 +698,7 @@ private func fetchEmojiRepresentation(account: Account, resource: MediaResource,
private func fetchAnimatedStickerFirstFrameRepresentation(account: Account, resource: MediaResource, resourceData: MediaResourceData, representation: CachedAnimatedStickerFirstFrameRepresentation) -> Signal<CachedMediaResourceRepresentationResult, NoError> { private func fetchAnimatedStickerFirstFrameRepresentation(account: Account, resource: MediaResource, resourceData: MediaResourceData, representation: CachedAnimatedStickerFirstFrameRepresentation) -> Signal<CachedMediaResourceRepresentationResult, NoError> {
return Signal({ subscriber in return Signal({ subscriber in
if let data = try? Data(contentsOf: URL(fileURLWithPath: resourceData.path), options: [.mappedIfSafe]) { if let data = try? Data(contentsOf: URL(fileURLWithPath: resourceData.path), options: [.mappedIfSafe]) {
return fetchCompressedLottieFirstFrameAJpeg(data: data, size: CGSize(width: CGFloat(representation.width), height: CGFloat(representation.height)), fitzModifier: representation.fitzModifier, cacheKey: "\(resource.id.uniqueId)-\(representation.uniqueId)").start(next: { file in return fetchCompressedLottieFirstFrameAJpeg(data: data, size: CGSize(width: CGFloat(representation.width), height: CGFloat(representation.height)), fitzModifier: representation.fitzModifier, cacheKey: "\(resource.id.stringRepresentation)-\(representation.uniqueId)").start(next: { file in
subscriber.putNext(.tempFile(file)) subscriber.putNext(.tempFile(file))
subscriber.putCompletion() subscriber.putCompletion()
}) })
@ -713,7 +713,7 @@ private func fetchAnimatedStickerRepresentation(account: Account, resource: Medi
return Signal({ subscriber in return Signal({ subscriber in
if let data = try? Data(contentsOf: URL(fileURLWithPath: resourceData.path), options: [.mappedIfSafe]) { if let data = try? Data(contentsOf: URL(fileURLWithPath: resourceData.path), options: [.mappedIfSafe]) {
if #available(iOS 9.0, *) { if #available(iOS 9.0, *) {
return experimentalConvertCompressedLottieToCombinedMp4(data: data, size: CGSize(width: CGFloat(representation.width), height: CGFloat(representation.height)), fitzModifier: representation.fitzModifier, cacheKey: "\(resource.id.uniqueId)-\(representation.uniqueId)").start(next: { value in return experimentalConvertCompressedLottieToCombinedMp4(data: data, size: CGSize(width: CGFloat(representation.width), height: CGFloat(representation.height)), fitzModifier: representation.fitzModifier, cacheKey: "\(resource.id.stringRepresentation)-\(representation.uniqueId)").start(next: { value in
subscriber.putNext(value) subscriber.putNext(value)
}, completed: { }, completed: {
subscriber.putCompletion() subscriber.putCompletion()

View File

@ -16,7 +16,7 @@ private struct FetchManagerLocationEntryId: Hashable {
if lhs.location != rhs.location { if lhs.location != rhs.location {
return false return false
} }
if !lhs.resourceId.isEqual(to: rhs.resourceId) { if lhs.resourceId != rhs.resourceId {
return false return false
} }
if lhs.locationKey != rhs.locationKey { if lhs.locationKey != rhs.locationKey {
@ -388,7 +388,7 @@ private final class FetchManagerCategoryContext {
var id: FetchManagerLocationEntryId = entryId var id: FetchManagerLocationEntryId = entryId
if self.entries[id] == nil { if self.entries[id] == nil {
for (key, _) in self.entries { for (key, _) in self.entries {
if key.resourceId.isEqual(to: entryId.resourceId) { if key.resourceId == entryId.resourceId {
id = key id = key
break break
} }

View File

@ -7,7 +7,7 @@ import Display
import Pdf import Pdf
import AVFoundation import AVFoundation
public struct ICloudFileResourceId: MediaResourceId { public struct ICloudFileResourceId {
public let urlData: String public let urlData: String
public let thumbnail: Bool public let thumbnail: Bool
@ -22,14 +22,6 @@ public struct ICloudFileResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.uniqueId.hashValue return self.uniqueId.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? ICloudFileResourceId {
return self.urlData == to.urlData
} else {
return false
}
}
} }
public class ICloudFileResource: TelegramMediaResource { public class ICloudFileResource: TelegramMediaResource {
@ -52,7 +44,7 @@ public class ICloudFileResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return ICloudFileResourceId(urlData: self.urlData, thumbnail: self.thumbnail) return MediaResourceId(ICloudFileResourceId(urlData: self.urlData, thumbnail: self.thumbnail).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {

View File

@ -29,9 +29,9 @@ private func animationItem(account: Account, emojis: Signal<[TelegramMediaFile],
if let _ = account.postbox.mediaBox.completedResourcePath(file.resource) { if let _ = account.postbox.mediaBox.completedResourcePath(file.resource) {
if immediate { if immediate {
return .single(ManagedAnimationItem(source: .resource(account, file.resource), frames: .still(.end), duration: 0)) return .single(ManagedAnimationItem(source: .resource(account, EngineMediaResource(file.resource)), frames: .still(.end), duration: 0))
} else { } else {
return .single(ManagedAnimationItem(source: .resource(account, file.resource), loop: loop, callbacks: callbacks)) return .single(ManagedAnimationItem(source: .resource(account, EngineMediaResource(file.resource)), loop: loop, callbacks: callbacks))
} }
} else { } else {
let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512) let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512)
@ -44,7 +44,7 @@ private func animationItem(account: Account, emojis: Signal<[TelegramMediaFile],
|> filter { data in |> filter { data in
return data.complete return data.complete
}).start(next: { next in }).start(next: { next in
subscriber.putNext(ManagedAnimationItem(source: .resource(account, file.resource), loop: loop, callbacks: callbacks)) subscriber.putNext(ManagedAnimationItem(source: .resource(account, EngineMediaResource(file.resource)), loop: loop, callbacks: callbacks))
subscriber.putCompletion() subscriber.putCompletion()
}) })

View File

@ -188,13 +188,13 @@ public final class NotificationViewControllerImpl {
let mediaBoxPath = accountsPath + "/" + accountRecordIdPathName(AccountRecordId(rawValue: accountIdValue)) + "/postbox/media" let mediaBoxPath = accountsPath + "/" + accountRecordIdPathName(AccountRecordId(rawValue: accountIdValue)) + "/postbox/media"
if let data = try? Data(contentsOf: URL(fileURLWithPath: mediaBoxPath + "/\(largestRepresentation.resource.id.uniqueId)"), options: .mappedRead) { if let data = try? Data(contentsOf: URL(fileURLWithPath: mediaBoxPath + "/\(largestRepresentation.resource.id.stringRepresentation)"), options: .mappedRead) {
self.imageNode.setSignal(chatMessagePhotoInternal(photoData: .single(Tuple(nil, data, .full, true))) self.imageNode.setSignal(chatMessagePhotoInternal(photoData: .single(Tuple(nil, data, .full, true)))
|> map { $0.2 }) |> map { $0.2 })
return return
} }
if let data = try? Data(contentsOf: URL(fileURLWithPath: mediaBoxPath + "/\(thumbnailRepresentation.resource.id.uniqueId)"), options: .mappedRead) { if let data = try? Data(contentsOf: URL(fileURLWithPath: mediaBoxPath + "/\(thumbnailRepresentation.resource.id.stringRepresentation)"), options: .mappedRead) {
self.imageNode.setSignal(chatMessagePhotoInternal(photoData: .single(Tuple(data, nil, .medium, false))) self.imageNode.setSignal(chatMessagePhotoInternal(photoData: .single(Tuple(data, nil, .medium, false)))
|> map { $0.2 }) |> map { $0.2 })
} }

View File

@ -375,11 +375,11 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
overrideImage = .deletedIcon overrideImage = .deletedIcon
} else if let previousItem = previousItem, item == nil { } else if let previousItem = previousItem, item == nil {
if case let .image(_, representations, _, _) = previousItem, let rep = representations.last { if case let .image(_, representations, _, _) = previousItem, let rep = representations.last {
self.removedPhotoResourceIds.insert(rep.representation.resource.id.uniqueId) self.removedPhotoResourceIds.insert(rep.representation.resource.id.stringRepresentation)
} }
overrideImage = AvatarNodeImageOverride.none overrideImage = AvatarNodeImageOverride.none
item = nil item = nil
} else if let rep = peer.profileImageRepresentations.last, self.removedPhotoResourceIds.contains(rep.resource.id.uniqueId) { } else if let rep = peer.profileImageRepresentations.last, self.removedPhotoResourceIds.contains(rep.resource.id.stringRepresentation) {
overrideImage = AvatarNodeImageOverride.none overrideImage = AvatarNodeImageOverride.none
item = nil item = nil
} }
@ -680,11 +680,11 @@ final class PeerInfoEditingAvatarNode: ASDisplayNode {
overrideImage = .editAvatarIcon overrideImage = .editAvatarIcon
} else if let previousItem = previousItem, item == nil { } else if let previousItem = previousItem, item == nil {
if case let .image(_, representations, _, _) = previousItem, let rep = representations.last { if case let .image(_, representations, _, _) = previousItem, let rep = representations.last {
self.removedPhotoResourceIds.insert(rep.representation.resource.id.uniqueId) self.removedPhotoResourceIds.insert(rep.representation.resource.id.stringRepresentation)
} }
overrideImage = AvatarNodeImageOverride.none overrideImage = AvatarNodeImageOverride.none
item = nil item = nil
} else if let rep = peer.profileImageRepresentations.last, self.removedPhotoResourceIds.contains(rep.resource.id.uniqueId) { } else if let rep = peer.profileImageRepresentations.last, self.removedPhotoResourceIds.contains(rep.resource.id.stringRepresentation) {
overrideImage = AvatarNodeImageOverride.none overrideImage = AvatarNodeImageOverride.none
item = nil item = nil
} else { } else {

View File

@ -67,7 +67,7 @@ final class SoftwareVideoLayerFrameManager {
if let resource = resource as? WebFileReferenceMediaResource { if let resource = resource as? WebFileReferenceMediaResource {
return resource.url return resource.url
} else { } else {
return resource.id.uniqueId return resource.id.stringRepresentation
} }
} }
Logger.shared.log("SoftwareVideo", "load video from \(stringForResource(self.resource)) or \(stringForResource(self.secondaryResource))") Logger.shared.log("SoftwareVideo", "load video from \(stringForResource(self.resource)) or \(stringForResource(self.secondaryResource))")

View File

@ -383,7 +383,7 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
} }
} }
public struct YoutubeEmbedStoryboardMediaResourceId: MediaResourceId { public struct YoutubeEmbedStoryboardMediaResourceId {
public let videoId: String public let videoId: String
public let storyboardId: Int32 public let storyboardId: Int32
@ -394,14 +394,6 @@ public struct YoutubeEmbedStoryboardMediaResourceId: MediaResourceId {
public var hashValue: Int { public var hashValue: Int {
return self.uniqueId.hashValue return self.uniqueId.hashValue
} }
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? YoutubeEmbedStoryboardMediaResourceId {
return self.videoId == to.videoId && self.storyboardId == to.storyboardId
} else {
return false
}
}
} }
public class YoutubeEmbedStoryboardMediaResource: TelegramMediaResource { public class YoutubeEmbedStoryboardMediaResource: TelegramMediaResource {
@ -428,7 +420,7 @@ public class YoutubeEmbedStoryboardMediaResource: TelegramMediaResource {
} }
public var id: MediaResourceId { public var id: MediaResourceId {
return YoutubeEmbedStoryboardMediaResourceId(videoId: self.videoId, storyboardId: self.storyboardId) return MediaResourceId(YoutubeEmbedStoryboardMediaResourceId(videoId: self.videoId, storyboardId: self.storyboardId).uniqueId)
} }
public func isEqual(to: MediaResource) -> Bool { public func isEqual(to: MediaResource) -> Bool {