mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit 'a6292e752a7de0c7fd28f07b0a24c215d227e593'
This commit is contained in:
commit
f17f51b5a0
@ -588,6 +588,7 @@ public final class AnimatedStickerDirectFrameSource: AnimatedStickerFrameSource
|
||||
let decompressedData = TGGUnzipData(data, 8 * 1024 * 1024) ?? data
|
||||
|
||||
guard let animation = LottieInstance(data: decompressedData, fitzModifier: fitzModifier?.lottieFitzModifier ?? .none, colorReplacements: nil, cacheKey: "") else {
|
||||
print("Could not load sticker data")
|
||||
return nil
|
||||
}
|
||||
self.animation = animation
|
||||
|
@ -2197,12 +2197,14 @@ public final class ContextController: ViewController, StandalonePresentableContr
|
||||
public var content: Content
|
||||
public var context: AccountContext?
|
||||
public var reactionItems: [ReactionContextItem]
|
||||
public var disablePositionLock: Bool
|
||||
public var tip: Tip?
|
||||
|
||||
public init(content: Content, context: AccountContext? = nil, reactionItems: [ReactionContextItem] = [], tip: Tip? = nil) {
|
||||
public init(content: Content, context: AccountContext? = nil, reactionItems: [ReactionContextItem] = [], disablePositionLock: Bool = false, tip: Tip? = nil) {
|
||||
self.content = content
|
||||
self.context = context
|
||||
self.reactionItems = reactionItems
|
||||
self.disablePositionLock = disablePositionLock
|
||||
self.tip = tip
|
||||
}
|
||||
|
||||
@ -2210,6 +2212,7 @@ public final class ContextController: ViewController, StandalonePresentableContr
|
||||
self.content = .list([])
|
||||
self.context = nil
|
||||
self.reactionItems = []
|
||||
self.disablePositionLock = false
|
||||
self.tip = nil
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +320,10 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
|
||||
func pushItems(items: ContextController.Items) {
|
||||
let currentScrollingState = self.getCurrentScrollingState()
|
||||
let positionLock = self.getActionsStackPositionLock()
|
||||
var positionLock: CGFloat?
|
||||
if !items.disablePositionLock {
|
||||
positionLock = self.getActionsStackPositionLock()
|
||||
}
|
||||
self.actionsStackNode.push(item: makeContextControllerActionsStackItem(items: items), currentScrollingState: currentScrollingState, positionLock: positionLock, animated: true)
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
case experimentalBackground(Bool)
|
||||
case inlineStickers(Bool)
|
||||
case localTranscription(Bool)
|
||||
case enableReactionOverrides(Bool)
|
||||
case playerEmbedding(Bool)
|
||||
case playlistPlayback(Bool)
|
||||
case voiceConference
|
||||
@ -109,7 +110,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
return DebugControllerSection.logging.rawValue
|
||||
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .clearTips, .crash, .resetData, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .reindexUnread, .resetBiometricsData, .resetWebViewCache, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .playerEmbedding, .playlistPlayback, .voiceConference, .experimentalCompatibility, .enableDebugDataDisplay, .acceleratedStickers, .experimentalBackground, .inlineStickers, .localTranscription, .resetInAppPurchases:
|
||||
case .clearTips, .crash, .resetData, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .reindexUnread, .resetBiometricsData, .resetWebViewCache, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .playerEmbedding, .playlistPlayback, .voiceConference, .experimentalCompatibility, .enableDebugDataDisplay, .acceleratedStickers, .experimentalBackground, .inlineStickers, .localTranscription, . enableReactionOverrides, .resetInAppPurchases:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .preferredVideoCodec:
|
||||
return DebugControllerSection.videoExperiments.rawValue
|
||||
@ -188,16 +189,18 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
return 31
|
||||
case .localTranscription:
|
||||
return 32
|
||||
case .resetInAppPurchases:
|
||||
case .enableReactionOverrides:
|
||||
return 33
|
||||
case .playerEmbedding:
|
||||
case .resetInAppPurchases:
|
||||
return 34
|
||||
case .playlistPlayback:
|
||||
case .playerEmbedding:
|
||||
return 35
|
||||
case .voiceConference:
|
||||
case .playlistPlayback:
|
||||
return 36
|
||||
case .voiceConference:
|
||||
return 37
|
||||
case let .preferredVideoCodec(index, _, _, _):
|
||||
return 37 + index
|
||||
return 38 + index
|
||||
case .disableVideoAspectScaling:
|
||||
return 100
|
||||
case .enableVoipTcp:
|
||||
@ -970,6 +973,20 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
})
|
||||
}).start()
|
||||
})
|
||||
case let .enableReactionOverrides(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Effect Overrides", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
||||
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
|
||||
var settings = settings?.get(ExperimentalUISettings.self) ?? ExperimentalUISettings.defaultSettings
|
||||
settings.enableReactionOverrides = value
|
||||
if !value {
|
||||
settings.accountReactionEffectOverrides.removeAll()
|
||||
settings.accountStickerEffectOverrides.removeAll()
|
||||
}
|
||||
return PreferencesEntry(settings)
|
||||
})
|
||||
}).start()
|
||||
})
|
||||
case let .playerEmbedding(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Player Embedding", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
||||
@ -1091,6 +1108,9 @@ private func debugControllerEntries(sharedContext: SharedAccountContext, present
|
||||
entries.append(.experimentalBackground(experimentalSettings.experimentalBackground))
|
||||
entries.append(.inlineStickers(experimentalSettings.inlineStickers))
|
||||
entries.append(.localTranscription(experimentalSettings.localTranscription))
|
||||
if case .internal = sharedContext.applicationBindings.appBuildType {
|
||||
entries.append(.enableReactionOverrides(experimentalSettings.enableReactionOverrides))
|
||||
}
|
||||
entries.append(.resetInAppPurchases(presentationData.theme))
|
||||
entries.append(.playerEmbedding(experimentalSettings.playerEmbedding))
|
||||
entries.append(.playlistPlayback(experimentalSettings.playlistPlayback))
|
||||
|
@ -15,6 +15,7 @@ import MultilineTextComponent
|
||||
import BundleIconComponent
|
||||
import SolidRoundedButtonComponent
|
||||
import Markdown
|
||||
import TelegramUIPreferences
|
||||
|
||||
private final class GradientBackgroundComponent: Component {
|
||||
public let colors: [UIColor]
|
||||
@ -523,6 +524,27 @@ private final class DemoSheetContent: CombinedComponent {
|
||||
|
||||
super.init()
|
||||
|
||||
let accountSpecificReactionOverrides: [ExperimentalUISettings.AccountReactionOverrides.Item]
|
||||
if self.context.sharedContext.immediateExperimentalUISettings.enableReactionOverrides, let value = self.context.sharedContext.immediateExperimentalUISettings.accountReactionEffectOverrides.first(where: { $0.accountId == self.context.account.id.int64 }) {
|
||||
accountSpecificReactionOverrides = value.items
|
||||
} else {
|
||||
accountSpecificReactionOverrides = []
|
||||
}
|
||||
|
||||
let reactionOverrideMessages = self.context.engine.data.get(
|
||||
EngineDataMap(accountSpecificReactionOverrides.map(\.messageId).map(TelegramEngine.EngineData.Item.Messages.Message.init))
|
||||
)
|
||||
|
||||
let accountSpecificStickerOverrides: [ExperimentalUISettings.AccountReactionOverrides.Item]
|
||||
if self.context.sharedContext.immediateExperimentalUISettings.enableReactionOverrides, let value = self.context.sharedContext.immediateExperimentalUISettings.accountStickerEffectOverrides.first(where: { $0.accountId == self.context.account.id.int64 }) {
|
||||
accountSpecificStickerOverrides = value.items
|
||||
} else {
|
||||
accountSpecificStickerOverrides = []
|
||||
}
|
||||
let stickerOverrideMessages = self.context.engine.data.get(
|
||||
EngineDataMap(accountSpecificStickerOverrides.map(\.messageId).map(TelegramEngine.EngineData.Item.Messages.Message.init))
|
||||
)
|
||||
|
||||
let stickersKey: PostboxViewKey = .orderedItemList(id: Namespaces.OrderedItemList.CloudPremiumStickers)
|
||||
self.disposable = (combineLatest(
|
||||
queue: Queue.mainQueue(),
|
||||
@ -542,9 +564,33 @@ private final class DemoSheetContent: CombinedComponent {
|
||||
self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId),
|
||||
TelegramEngine.EngineData.Item.Configuration.PremiumPromo()
|
||||
)
|
||||
),
|
||||
reactionOverrideMessages,
|
||||
stickerOverrideMessages
|
||||
)
|
||||
|> map { reactions, items, data -> ([AvailableReactions.Reaction], [TelegramMediaFile], Bool?, PremiumPromoConfiguration?) in
|
||||
|> map { reactions, items, data, reactionOverrideMessages, stickerOverrideMessages -> ([AvailableReactions.Reaction], [TelegramMediaFile], Bool?, PremiumPromoConfiguration?) in
|
||||
var reactionOverrides: [String: TelegramMediaFile] = [:]
|
||||
for item in accountSpecificReactionOverrides {
|
||||
if let maybeMessage = reactionOverrideMessages[item.messageId], let message = maybeMessage {
|
||||
for media in message.media {
|
||||
if let file = media as? TelegramMediaFile, file.fileId == item.mediaId {
|
||||
reactionOverrides[item.key] = file
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var stickerOverrides: [String: TelegramMediaFile] = [:]
|
||||
for item in accountSpecificStickerOverrides {
|
||||
if let maybeMessage = stickerOverrideMessages[item.messageId], let message = maybeMessage {
|
||||
for media in message.media {
|
||||
if let file = media as? TelegramMediaFile, file.fileId == item.mediaId {
|
||||
stickerOverrides[item.key] = file
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let reactions = reactions {
|
||||
var result: [TelegramMediaFile] = []
|
||||
if let items = items {
|
||||
@ -554,7 +600,49 @@ private final class DemoSheetContent: CombinedComponent {
|
||||
}
|
||||
}
|
||||
}
|
||||
return (reactions.reactions.filter({ $0.isPremium }), result, data.0?.isPremium ?? false, data.1)
|
||||
return (reactions.reactions.filter({ $0.isPremium }).map { reaction -> AvailableReactions.Reaction in
|
||||
var aroundAnimation = reaction.aroundAnimation
|
||||
if let replacementFile = reactionOverrides[reaction.value] {
|
||||
aroundAnimation = replacementFile
|
||||
}
|
||||
|
||||
return AvailableReactions.Reaction(
|
||||
isEnabled: reaction.isEnabled,
|
||||
isPremium: reaction.isPremium,
|
||||
value: reaction.value,
|
||||
title: reaction.title,
|
||||
staticIcon: reaction.staticIcon,
|
||||
appearAnimation: reaction.appearAnimation,
|
||||
selectAnimation: reaction.selectAnimation,
|
||||
activateAnimation: reaction.activateAnimation,
|
||||
effectAnimation: reaction.effectAnimation,
|
||||
aroundAnimation: aroundAnimation,
|
||||
centerAnimation: reaction.centerAnimation
|
||||
)
|
||||
}, result.map { file -> TelegramMediaFile in
|
||||
for attribute in file.attributes {
|
||||
switch attribute {
|
||||
case let .Sticker(displayText, _, _):
|
||||
if let replacementFile = stickerOverrides[displayText], let dimensions = replacementFile.dimensions {
|
||||
let _ = dimensions
|
||||
return TelegramMediaFile(
|
||||
fileId: file.fileId,
|
||||
partialReference: file.partialReference,
|
||||
resource: file.resource,
|
||||
previewRepresentations: file.previewRepresentations,
|
||||
videoThumbnails: [TelegramMediaFile.VideoThumbnail(dimensions: dimensions, resource: replacementFile.resource)],
|
||||
immediateThumbnailData: file.immediateThumbnailData,
|
||||
mimeType: file.mimeType,
|
||||
size: file.size,
|
||||
attributes: file.attributes
|
||||
)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
return file
|
||||
}, data.0?.isPremium ?? false, data.1)
|
||||
} else {
|
||||
return ([], [], nil, nil)
|
||||
}
|
||||
|
@ -97,13 +97,13 @@ private class StickerNode: ASDisplayNode {
|
||||
|
||||
private var setupTimestamp: Double?
|
||||
|
||||
init(context: AccountContext, file: TelegramMediaFile) {
|
||||
init(context: AccountContext, file: TelegramMediaFile, forceIsPremium: Bool) {
|
||||
self.context = context
|
||||
self.file = file
|
||||
|
||||
self.imageNode = TransformImageNode()
|
||||
|
||||
if file.isPremiumSticker {
|
||||
if file.isPremiumSticker || forceIsPremium {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
animationNode.automaticallyLoadFirstFrame = true
|
||||
self.animationNode = animationNode
|
||||
@ -124,8 +124,11 @@ private class StickerNode: ASDisplayNode {
|
||||
let source = AnimatedStickerResourceSource(account: self.context.account, resource: effect.resource, fitzModifier: nil)
|
||||
let additionalAnimationNode = AnimatedStickerNode()
|
||||
|
||||
let pathPrefix = context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(effect.resource.id)
|
||||
additionalAnimationNode.setup(source: source, width: Int(fittedDimensions.width * 1.4), height: Int(fittedDimensions.height * 1.4), playbackMode: .loop, mode: .direct(cachePathPrefix: pathPrefix))
|
||||
var pathPrefix: String?
|
||||
pathPrefix = context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(effect.resource.id)
|
||||
pathPrefix = nil
|
||||
|
||||
additionalAnimationNode.setup(source: source, width: Int(fittedDimensions.width * 1.33), height: Int(fittedDimensions.height * 1.33), playbackMode: .loop, mode: .direct(cachePathPrefix: pathPrefix))
|
||||
self.additionalAnimationNode = additionalAnimationNode
|
||||
}
|
||||
} else {
|
||||
@ -592,7 +595,7 @@ private class StickersCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
if let current = self.itemNodes[i] {
|
||||
itemNode = current
|
||||
} else {
|
||||
itemNode = StickerNode(context: self.context, file: self.stickers[i])
|
||||
itemNode = StickerNode(context: self.context, file: self.stickers[i], forceIsPremium: true)
|
||||
containerNode.addSubnode(itemNode)
|
||||
self.itemNodes[i] = itemNode
|
||||
}
|
||||
|
@ -1076,7 +1076,13 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
||||
additionalAnimation = itemNode.item.applicationAnimation
|
||||
}
|
||||
|
||||
additionalAnimationNode.setup(source: AnimatedStickerResourceSource(account: itemNode.context.account, resource: additionalAnimation.resource), width: Int(effectFrame.width * 2.0), height: Int(effectFrame.height * 2.0), playbackMode: .once, mode: .direct(cachePathPrefix: itemNode.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(additionalAnimation.resource.id)))
|
||||
var additionalCachePathPrefix: String?
|
||||
additionalCachePathPrefix = itemNode.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(additionalAnimation.resource.id)
|
||||
//#if DEBUG
|
||||
additionalCachePathPrefix = nil
|
||||
//#endif
|
||||
|
||||
additionalAnimationNode.setup(source: AnimatedStickerResourceSource(account: itemNode.context.account, resource: additionalAnimation.resource), width: Int(effectFrame.width * 1.33), height: Int(effectFrame.height * 1.33), playbackMode: .once, mode: .direct(cachePathPrefix: additionalCachePathPrefix))
|
||||
additionalAnimationNode.frame = effectFrame
|
||||
additionalAnimationNode.updateLayout(size: effectFrame.size)
|
||||
self.addSubnode(additionalAnimationNode)
|
||||
|
@ -777,6 +777,132 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if context.sharedContext.immediateExperimentalUISettings.enableReactionOverrides {
|
||||
for media in message.media {
|
||||
if let file = media as? TelegramMediaFile, file.isAnimatedSticker {
|
||||
actions.append(.action(ContextMenuActionItem(text: "Set as Reaction Effect", icon: { _ in
|
||||
return nil
|
||||
}, action: { c, _ in
|
||||
let subItems: Signal<ContextController.Items, NoError> = context.engine.stickers.availableReactions()
|
||||
|> map { reactions -> ContextController.Items in
|
||||
var subActions: [ContextMenuItem] = []
|
||||
|
||||
if let reactions = reactions {
|
||||
for reaction in reactions.reactions {
|
||||
if !reaction.isEnabled || !reaction.isPremium {
|
||||
continue
|
||||
}
|
||||
|
||||
subActions.append(.action(ContextMenuActionItem(text: reaction.value, icon: { _ in
|
||||
return nil
|
||||
}, action: { _, f in
|
||||
let _ = updateExperimentalUISettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
|
||||
var settings = settings
|
||||
|
||||
var currentItems: [ExperimentalUISettings.AccountReactionOverrides.Item]
|
||||
if let value = settings.accountReactionEffectOverrides.first(where: { $0.accountId == context.account.id.int64 }) {
|
||||
currentItems = value.items
|
||||
} else {
|
||||
currentItems = []
|
||||
}
|
||||
|
||||
currentItems.removeAll(where: { $0.key == reaction.value })
|
||||
currentItems.append(ExperimentalUISettings.AccountReactionOverrides.Item(
|
||||
key: reaction.value,
|
||||
messageId: message.id,
|
||||
mediaId: file.fileId
|
||||
))
|
||||
|
||||
settings.accountReactionEffectOverrides.removeAll(where: { $0.accountId == context.account.id.int64 })
|
||||
settings.accountReactionEffectOverrides.append(ExperimentalUISettings.AccountReactionOverrides(accountId: context.account.id.int64, items: currentItems))
|
||||
|
||||
return settings
|
||||
}).start()
|
||||
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
return ContextController.Items(content: .list(subActions), disablePositionLock: true, tip: nil)
|
||||
}
|
||||
|
||||
c.pushItems(items: subItems)
|
||||
})))
|
||||
|
||||
actions.append(.action(ContextMenuActionItem(text: "Set as Sticker Effect", icon: { _ in
|
||||
return nil
|
||||
}, action: { c, _ in
|
||||
let stickersKey: PostboxViewKey = .orderedItemList(id: Namespaces.OrderedItemList.CloudPremiumStickers)
|
||||
let subItems: Signal<ContextController.Items, NoError> = context.account.postbox.combinedView(keys: [stickersKey])
|
||||
|> map { views -> [String] in
|
||||
if let view = views.views[stickersKey] as? OrderedItemListView, !view.items.isEmpty {
|
||||
return view.items.compactMap { item -> String? in
|
||||
guard let mediaItem = item.contents.get(RecentMediaItem.self) else {
|
||||
return nil
|
||||
}
|
||||
let file = mediaItem.media
|
||||
for attribute in file.attributes {
|
||||
switch attribute {
|
||||
case let .Sticker(text, _, _):
|
||||
return text
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|> map { stickerNames -> ContextController.Items in
|
||||
var subActions: [ContextMenuItem] = []
|
||||
|
||||
for stickerName in stickerNames {
|
||||
subActions.append(.action(ContextMenuActionItem(text: stickerName, icon: { _ in
|
||||
return nil
|
||||
}, action: { _, f in
|
||||
let _ = updateExperimentalUISettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
|
||||
var settings = settings
|
||||
|
||||
var currentItems: [ExperimentalUISettings.AccountReactionOverrides.Item]
|
||||
if let value = settings.accountStickerEffectOverrides.first(where: { $0.accountId == context.account.id.int64 }) {
|
||||
currentItems = value.items
|
||||
} else {
|
||||
currentItems = []
|
||||
}
|
||||
|
||||
currentItems.removeAll(where: { $0.key == stickerName })
|
||||
currentItems.append(ExperimentalUISettings.AccountReactionOverrides.Item(
|
||||
key: stickerName,
|
||||
messageId: message.id,
|
||||
mediaId: file.fileId
|
||||
))
|
||||
|
||||
settings.accountStickerEffectOverrides.removeAll(where: { $0.accountId == context.account.id.int64 })
|
||||
settings.accountStickerEffectOverrides.append(ExperimentalUISettings.AccountReactionOverrides(accountId: context.account.id.int64, items: currentItems))
|
||||
|
||||
return settings
|
||||
}).start()
|
||||
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
|
||||
return ContextController.Items(content: .list(subActions), disablePositionLock: true, tip: nil)
|
||||
}
|
||||
|
||||
c.pushItems(items: subItems)
|
||||
})))
|
||||
|
||||
actions.append(.separator)
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var isReplyThreadHead = false
|
||||
|
@ -4,6 +4,28 @@ import TelegramCore
|
||||
import SwiftSignalKit
|
||||
|
||||
public struct ExperimentalUISettings: Codable, Equatable {
|
||||
public struct AccountReactionOverrides: Equatable, Codable {
|
||||
public struct Item: Equatable, Codable {
|
||||
public var key: String
|
||||
public var messageId: MessageId
|
||||
public var mediaId: MediaId
|
||||
|
||||
public init(key: String, messageId: MessageId, mediaId: MediaId) {
|
||||
self.key = key
|
||||
self.messageId = messageId
|
||||
self.mediaId = mediaId
|
||||
}
|
||||
}
|
||||
|
||||
public var accountId: Int64
|
||||
public var items: [Item]
|
||||
|
||||
public init(accountId: Int64, items: [Item]) {
|
||||
self.accountId = accountId
|
||||
self.items = items
|
||||
}
|
||||
}
|
||||
|
||||
public var keepChatNavigationStack: Bool
|
||||
public var skipReadHistory: Bool
|
||||
public var crashOnLongQueries: Bool
|
||||
@ -22,6 +44,9 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
public var snow: Bool
|
||||
public var inlineStickers: Bool
|
||||
public var localTranscription: Bool
|
||||
public var enableReactionOverrides: Bool
|
||||
public var accountReactionEffectOverrides: [AccountReactionOverrides]
|
||||
public var accountStickerEffectOverrides: [AccountReactionOverrides]
|
||||
|
||||
public static var defaultSettings: ExperimentalUISettings {
|
||||
return ExperimentalUISettings(
|
||||
@ -42,7 +67,10 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
experimentalBackground: false,
|
||||
snow: false,
|
||||
inlineStickers: false,
|
||||
localTranscription: false
|
||||
localTranscription: false,
|
||||
enableReactionOverrides: false,
|
||||
accountReactionEffectOverrides: [],
|
||||
accountStickerEffectOverrides: []
|
||||
)
|
||||
}
|
||||
|
||||
@ -64,7 +92,10 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
experimentalBackground: Bool,
|
||||
snow: Bool,
|
||||
inlineStickers: Bool,
|
||||
localTranscription: Bool
|
||||
localTranscription: Bool,
|
||||
enableReactionOverrides: Bool,
|
||||
accountReactionEffectOverrides: [AccountReactionOverrides],
|
||||
accountStickerEffectOverrides: [AccountReactionOverrides]
|
||||
) {
|
||||
self.keepChatNavigationStack = keepChatNavigationStack
|
||||
self.skipReadHistory = skipReadHistory
|
||||
@ -84,6 +115,9 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
self.snow = snow
|
||||
self.inlineStickers = inlineStickers
|
||||
self.localTranscription = localTranscription
|
||||
self.enableReactionOverrides = enableReactionOverrides
|
||||
self.accountReactionEffectOverrides = accountReactionEffectOverrides
|
||||
self.accountStickerEffectOverrides = accountStickerEffectOverrides
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
@ -107,6 +141,9 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
self.snow = (try container.decodeIfPresent(Int32.self, forKey: "snow") ?? 0) != 0
|
||||
self.inlineStickers = (try container.decodeIfPresent(Int32.self, forKey: "inlineStickers") ?? 0) != 0
|
||||
self.localTranscription = (try container.decodeIfPresent(Int32.self, forKey: "localTranscription") ?? 0) != 0
|
||||
self.enableReactionOverrides = try container.decodeIfPresent(Bool.self, forKey: "enableReactionOverrides") ?? false
|
||||
self.accountReactionEffectOverrides = (try container.decodeIfPresent([AccountReactionOverrides].self, forKey: "accountReactionEffectOverrides")) ?? []
|
||||
self.accountStickerEffectOverrides = (try container.decodeIfPresent([AccountReactionOverrides].self, forKey: "accountStickerEffectOverrides")) ?? []
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -130,6 +167,9 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
try container.encode((self.snow ? 1 : 0) as Int32, forKey: "snow")
|
||||
try container.encode((self.inlineStickers ? 1 : 0) as Int32, forKey: "inlineStickers")
|
||||
try container.encode((self.localTranscription ? 1 : 0) as Int32, forKey: "localTranscription")
|
||||
try container.encode(self.enableReactionOverrides, forKey: "enableReactionOverrides")
|
||||
try container.encode(self.accountReactionEffectOverrides, forKey: "accountReactionEffectOverrides")
|
||||
try container.encode(self.accountStickerEffectOverrides, forKey: "accountStickerEffectOverrides")
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user