mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 11:23:48 +00:00
Theme file reference invalidation
This commit is contained in:
parent
2f1e573cbf
commit
f13301f7d0
@ -90,7 +90,7 @@ public final class ThemePreviewController: ViewController {
|
||||
self.theme.get()
|
||||
|> mapToSignal { theme in
|
||||
if let file = theme?.file {
|
||||
return telegramThemeData(account: context.account, accountManager: context.sharedContext.accountManager, resource: file.resource)
|
||||
return telegramThemeData(account: context.account, accountManager: context.sharedContext.accountManager, reference: .standalone(resource: file.resource))
|
||||
|> mapToSignal { data -> Signal<PresentationTheme, NoError> in
|
||||
guard let data = data, let presentationTheme = makePresentationTheme(data: data) else {
|
||||
return .complete()
|
||||
|
@ -142,6 +142,39 @@ public enum WebpageReferenceContent: PostboxCoding, Hashable, Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public enum ThemeReference: PostboxCoding, Hashable, Equatable {
|
||||
case slug(String)
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
switch decoder.decodeInt32ForKey("r", orElse: 0) {
|
||||
case 0:
|
||||
self = .slug(decoder.decodeStringForKey("s", orElse: ""))
|
||||
default:
|
||||
self = .slug("")
|
||||
assertionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
switch self {
|
||||
case let .slug(slug):
|
||||
encoder.encodeInt32(0, forKey: "r")
|
||||
encoder.encodeString(slug, forKey: "s")
|
||||
}
|
||||
}
|
||||
|
||||
public static func ==(lhs: ThemeReference, rhs: ThemeReference) -> Bool {
|
||||
switch lhs {
|
||||
case let .slug(slug):
|
||||
if case .slug(slug) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum AnyMediaReference: Equatable {
|
||||
case standalone(media: Media)
|
||||
case message(message: MessageReference, media: Media)
|
||||
@ -430,6 +463,7 @@ public enum MediaResourceReference: Equatable {
|
||||
case messageAuthorAvatar(message: MessageReference, resource: MediaResource)
|
||||
case wallpaper(resource: MediaResource)
|
||||
case stickerPackThumbnail(stickerPack: StickerPackReference, resource: MediaResource)
|
||||
case theme(theme: ThemeReference, resource: MediaResource)
|
||||
|
||||
public var resource: MediaResource {
|
||||
switch self {
|
||||
@ -445,6 +479,8 @@ public enum MediaResourceReference: Equatable {
|
||||
return resource
|
||||
case let .stickerPackThumbnail(_, resource):
|
||||
return resource
|
||||
case let .theme(_, resource):
|
||||
return resource
|
||||
}
|
||||
}
|
||||
|
||||
@ -486,6 +522,12 @@ public enum MediaResourceReference: Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .theme(lhsTheme, lhsResource):
|
||||
if case let .theme(rhsTheme, rhsResource) = rhs, lhsTheme == rhsTheme, lhsResource.isEqual(to: rhsResource) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,6 +141,7 @@ private enum MediaReferenceRevalidationKey: Hashable {
|
||||
case savedGifs
|
||||
case peer(peer: PeerReference)
|
||||
case wallpapers
|
||||
case themes
|
||||
}
|
||||
|
||||
private final class MediaReferenceRevalidationItemContext {
|
||||
@ -402,6 +403,26 @@ final class MediaReferenceRevalidationContext {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func themes(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramTheme], RevalidateMediaReferenceError> {
|
||||
return self.genericItem(key: .themes, background: background, request: { next, error in
|
||||
return (telegramThemes(postbox: postbox, network: network, accountManager: nil, forceUpdate: true)
|
||||
|> take(1)
|
||||
|> mapError { _ -> RevalidateMediaReferenceError in
|
||||
return .generic
|
||||
}).start(next: { value in
|
||||
next(value)
|
||||
}, error: { _ in
|
||||
error(.generic)
|
||||
})
|
||||
}) |> mapToSignal { next -> Signal<[TelegramTheme], RevalidateMediaReferenceError> in
|
||||
if let next = next as? [TelegramTheme] {
|
||||
return .single(next)
|
||||
} else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RevalidatedMediaResource {
|
||||
@ -586,6 +607,16 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali
|
||||
}
|
||||
return .fail(.generic)
|
||||
}
|
||||
case let .theme(themeReference, resource):
|
||||
return revalidationContext.themes(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation)
|
||||
|> mapToSignal { themes -> Signal<RevalidatedMediaResource, RevalidateMediaReferenceError> in
|
||||
for theme in themes {
|
||||
if let file = theme.file, file.resource.id.isEqual(to: resource.id) {
|
||||
return .single(RevalidatedMediaResource(updatedResource: file.resource, updatedReference: nil))
|
||||
}
|
||||
}
|
||||
return .fail(.generic)
|
||||
}
|
||||
case .standalone:
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ let telegramThemeFormat = "ios"
|
||||
let telegramThemeFileExtension = "tgios-theme"
|
||||
#endif
|
||||
|
||||
public func telegramThemes(postbox: Postbox, network: Network, accountManager: AccountManager, forceUpdate: Bool = false) -> Signal<[TelegramTheme], NoError> {
|
||||
public func telegramThemes(postbox: Postbox, network: Network, accountManager: AccountManager?, forceUpdate: Bool = false) -> Signal<[TelegramTheme], NoError> {
|
||||
let fetch: ([TelegramTheme]?, Int32?) -> Signal<[TelegramTheme], NoError> = { current, hash in
|
||||
network.request(Api.functions.account.getThemes(format: telegramThemeFormat, hash: hash ?? 0))
|
||||
|> retryRequest
|
||||
@ -31,6 +31,7 @@ public func telegramThemes(postbox: Postbox, network: Network, accountManager: A
|
||||
}
|
||||
}
|
||||
|> mapToSignal { items, hash -> Signal<[TelegramTheme], NoError> in
|
||||
if let accountManager = accountManager {
|
||||
let _ = accountManager.transaction { transaction in
|
||||
transaction.updateSharedData(SharedDataKeys.themeSettings, { current in
|
||||
var updated = current as? ThemeSettings ?? ThemeSettings(currentTheme: nil)
|
||||
@ -43,6 +44,7 @@ public func telegramThemes(postbox: Postbox, network: Network, accountManager: A
|
||||
return updated
|
||||
})
|
||||
}.start()
|
||||
}
|
||||
|
||||
return postbox.transaction { transaction -> [TelegramTheme] in
|
||||
var entries: [OrderedItemListEntry] = []
|
||||
|
@ -84,7 +84,7 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager {
|
||||
guard let file = theme.file else {
|
||||
return .complete()
|
||||
}
|
||||
return telegramThemeData(account: account, accountManager: accountManager, resource: file.resource)
|
||||
return telegramThemeData(account: account, accountManager: accountManager, reference: .standalone(resource: file.resource))
|
||||
|> mapToSignal { data -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in
|
||||
guard let data = data, let presentationTheme = makePresentationTheme(data: data) else {
|
||||
return .complete()
|
||||
|
@ -699,8 +699,8 @@ public func photoWallpaper(postbox: Postbox, photoLibraryResource: PhotoLibraryM
|
||||
}
|
||||
}
|
||||
|
||||
public func telegramThemeData(account: Account, accountManager: AccountManager, resource: MediaResource, synchronousLoad: Bool = false) -> Signal<Data?, NoError> {
|
||||
let maybeFetched = accountManager.mediaBox.resourceData(resource, option: .complete(waitUntilFetchStatus: false), attemptSynchronously: synchronousLoad)
|
||||
public func telegramThemeData(account: Account, accountManager: AccountManager, reference: MediaResourceReference, synchronousLoad: Bool = false) -> Signal<Data?, NoError> {
|
||||
let maybeFetched = accountManager.mediaBox.resourceData(reference.resource, option: .complete(waitUntilFetchStatus: false), attemptSynchronously: synchronousLoad)
|
||||
return maybeFetched
|
||||
|> take(1)
|
||||
|> mapToSignal { maybeData in
|
||||
@ -708,15 +708,15 @@ public func telegramThemeData(account: Account, accountManager: AccountManager,
|
||||
let loadedData: Data? = try? Data(contentsOf: URL(fileURLWithPath: maybeData.path), options: [])
|
||||
return .single(loadedData)
|
||||
} else {
|
||||
let data = account.postbox.mediaBox.resourceData(resource, option: .complete(waitUntilFetchStatus: false), attemptSynchronously: false)
|
||||
let data = account.postbox.mediaBox.resourceData(reference.resource, option: .complete(waitUntilFetchStatus: false), attemptSynchronously: false)
|
||||
return Signal { subscriber in
|
||||
let fetch = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: .standalone(resource: resource)).start()
|
||||
let fetch = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: reference).start()
|
||||
let disposable = (data
|
||||
|> map { data -> Data? in
|
||||
return data.complete ? try? Data(contentsOf: URL(fileURLWithPath: data.path)) : nil
|
||||
}).start(next: { next in
|
||||
if let data = next {
|
||||
accountManager.mediaBox.storeResourceData(resource.id, data: data)
|
||||
accountManager.mediaBox.storeResourceData(reference.resource.id, data: data)
|
||||
}
|
||||
subscriber.putNext(next)
|
||||
}, error: { error in
|
||||
@ -1153,13 +1153,14 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
colorsSignal = .single(((topBackgroundColor, bottomBackgroundColor), (incomingColor, incomingColor), outgoingColor, nil, rotation))
|
||||
} else {
|
||||
var resource: MediaResource?
|
||||
var reference: MediaResourceReference?
|
||||
if case let .local(theme) = theme {
|
||||
resource = theme.resource
|
||||
} else if case let .cloud(theme) = theme {
|
||||
resource = theme.theme.file?.resource
|
||||
reference = .standalone(resource: theme.resource)
|
||||
} else if case let .cloud(theme) = theme, let resource = theme.theme.file?.resource {
|
||||
reference = .theme(theme: .slug(theme.theme.slug), resource: resource)
|
||||
}
|
||||
if let resource = resource {
|
||||
colorsSignal = telegramThemeData(account: account, accountManager: accountManager, resource: resource, synchronousLoad: false)
|
||||
if let reference = reference {
|
||||
colorsSignal = telegramThemeData(account: account, accountManager: accountManager, reference: reference, synchronousLoad: false)
|
||||
|> mapToSignal { data -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in
|
||||
if let data = data, let theme = makePresentationTheme(data: data) {
|
||||
var wallpaperSignal: Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> = .complete()
|
||||
|
Loading…
x
Reference in New Issue
Block a user