Various Improvements

This commit is contained in:
Ilya Laktyushin 2021-09-06 01:15:43 +03:00
parent 6f2c7cf03b
commit 4393227307
58 changed files with 304 additions and 211 deletions

View File

@ -775,24 +775,6 @@ public protocol AnimatedStickerNodeSource {
func directDataPath() -> Signal<String, NoError> func directDataPath() -> Signal<String, NoError>
} }
public final class AnimatedStickerNodeLocalFileSource: AnimatedStickerNodeSource {
public var fitzModifier: EmojiFitzModifier? = nil
public let path: String
public init(path: String) {
self.path = path
}
public func directDataPath() -> Signal<String, NoError> {
return .single(self.path)
}
public func cachedDataPath(width: Int, height: Int) -> Signal<(String, Bool), NoError> {
return .never()
}
}
public final class AnimatedStickerNode: ASDisplayNode { public final class AnimatedStickerNode: ASDisplayNode {
private let queue: Queue private let queue: Queue
private let disposable = MetaDisposable() private let disposable = MetaDisposable()

View File

@ -29,6 +29,7 @@ swift_library(
"//submodules/ContextUI:ContextUI", "//submodules/ContextUI:ContextUI",
"//submodules/TelegramBaseController:TelegramBaseController", "//submodules/TelegramBaseController:TelegramBaseController",
"//submodules/AnimatedStickerNode:AnimatedStickerNode", "//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -12,6 +12,7 @@ import AccountContext
import TelegramNotices import TelegramNotices
import ChatListSearchItemHeader import ChatListSearchItemHeader
import AnimatedStickerNode import AnimatedStickerNode
import TelegramAnimatedStickerNode
import AppBundle import AppBundle
private struct CallListNodeListViewTransition { private struct CallListNodeListViewTransition {
@ -281,11 +282,8 @@ final class CallListControllerNode: ASDisplayNode {
self.listNode.backgroundColor = presentationData.theme.list.blocksBackgroundColor self.listNode.backgroundColor = presentationData.theme.list.blocksBackgroundColor
} }
self.emptyAnimationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "CallsPlaceholder"), width: 256, height: 256, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
if let path = getAppBundle().path(forResource: "CallsPlaceholder", ofType: "tgs") {
self.emptyAnimationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 256, height: 256, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
self.emptyAnimationSize = CGSize(width: 148.0, height: 148.0) self.emptyAnimationSize = CGSize(width: 148.0, height: 148.0)
}
self.emptyButtonIconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Call List/CallIcon"), color: presentationData.theme.list.itemAccentColor) self.emptyButtonIconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Call List/CallIcon"), color: presentationData.theme.list.itemAccentColor)

View File

@ -9,6 +9,7 @@ import AccountContext
import PresentationDataUtils import PresentationDataUtils
import RadialStatusNode import RadialStatusNode
import AnimatedStickerNode import AnimatedStickerNode
import TelegramAnimatedStickerNode
import AppBundle import AppBundle
import ZipArchive import ZipArchive
import MimeTypes import MimeTypes
@ -380,12 +381,10 @@ public final class ChatImportActivityScreen: ViewController {
self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
if let path = getAppBundle().path(forResource: "HistoryImport", ofType: "tgs") { self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "HistoryImport"), width: 190 * 2, height: 190 * 2, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 190 * 2, height: 190 * 2, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
self.animationNode.visibility = true self.animationNode.visibility = true
}
if let path = getAppBundle().path(forResource: "HistoryImportDone", ofType: "tgs") { self.doneAnimationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "HistoryImportDone"), width: 190 * 2, height: 190 * 2, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.doneAnimationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 190 * 2, height: 190 * 2, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.doneAnimationNode.started = { [weak self] in self.doneAnimationNode.started = { [weak self] in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
@ -393,7 +392,6 @@ public final class ChatImportActivityScreen: ViewController {
strongSelf.animationNode.isHidden = true strongSelf.animationNode.isHidden = true
} }
self.doneAnimationNode.visibility = false self.doneAnimationNode.visibility = false
}
self.addSubnode(self.animationNode) self.addSubnode(self.animationNode)
self.addSubnode(self.doneAnimationNode) self.addSubnode(self.doneAnimationNode)

View File

@ -13,11 +13,12 @@ swift_library(
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
"//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit",
"//submodules/Display:Display", "//submodules/Display:Display",
"//submodules/TelegramCore:TelegramCore",
"//submodules/TelegramPresentationData:TelegramPresentationData", "//submodules/TelegramPresentationData:TelegramPresentationData",
"//submodules/ItemListUI:ItemListUI", "//submodules/ItemListUI:ItemListUI",
"//submodules/PresentationDataUtils:PresentationDataUtils", "//submodules/PresentationDataUtils:PresentationDataUtils",
"//submodules/AnimatedStickerNode:AnimatedStickerNode", "//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/AppBundle:AppBundle", "//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -3,11 +3,13 @@ import UIKit
import Display import Display
import AsyncDisplayKit import AsyncDisplayKit
import SwiftSignalKit import SwiftSignalKit
import TelegramCore
import TelegramPresentationData import TelegramPresentationData
import ItemListUI import ItemListUI
import PresentationDataUtils import PresentationDataUtils
import AnimatedStickerNode import AnimatedStickerNode
import AppBundle import TelegramAnimatedStickerNode
import AccountContext
public enum ChatListFilterSettingsHeaderAnimation { public enum ChatListFilterSettingsHeaderAnimation {
case folders case folders
@ -17,12 +19,14 @@ public enum ChatListFilterSettingsHeaderAnimation {
} }
public class ChatListFilterSettingsHeaderItem: ListViewItem, ItemListItem { public class ChatListFilterSettingsHeaderItem: ListViewItem, ItemListItem {
let context: AccountContext
let theme: PresentationTheme let theme: PresentationTheme
let text: String let text: String
let animation: ChatListFilterSettingsHeaderAnimation let animation: ChatListFilterSettingsHeaderAnimation
public let sectionId: ItemListSectionId public let sectionId: ItemListSectionId
public init(theme: PresentationTheme, text: String, animation: ChatListFilterSettingsHeaderAnimation, sectionId: ItemListSectionId) { public init(context: AccountContext, theme: PresentationTheme, text: String, animation: ChatListFilterSettingsHeaderAnimation, sectionId: ItemListSectionId) {
self.context = context
self.theme = theme self.theme = theme
self.text = text self.text = text
self.animation = animation self.animation = animation
@ -148,11 +152,9 @@ class ChatListFilterSettingsHeaderItemNode: ListViewItemNode {
return (layout, { [weak self] in return (layout, { [weak self] in
if let strongSelf = self { if let strongSelf = self {
if strongSelf.item == nil { if strongSelf.item == nil {
if let path = getAppBundle().path(forResource: animationName, ofType: "tgs") { strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: animationName), width: size, height: size, playbackMode: playbackMode, mode: .direct(cachePathPrefix: nil))
strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: size, height: size, playbackMode: playbackMode, mode: .direct(cachePathPrefix: nil))
strongSelf.animationNode.visibility = true strongSelf.animationNode.visibility = true
} }
}
strongSelf.item = item strongSelf.item = item
strongSelf.accessibilityLabel = attributedText.string strongSelf.accessibilityLabel = attributedText.string

View File

@ -1343,7 +1343,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let location = CGRect(origin: CGPoint(x: absoluteFrame.midX, y: absoluteFrame.minY - 8.0), size: CGSize()) let location = CGRect(origin: CGPoint(x: absoluteFrame.midX, y: absoluteFrame.minY - 8.0), size: CGSize())
parentController.present(TooltipScreen(text: text, icon: .chatListPress, location: .point(location, .bottom), shouldDismissOnTouch: { point in parentController.present(TooltipScreen(account: strongSelf.context.account, text: text, icon: .chatListPress, location: .point(location, .bottom), shouldDismissOnTouch: { point in
guard let strongSelf = self, let parentController = strongSelf.parent as? TabBarController else { guard let strongSelf = self, let parentController = strongSelf.parent as? TabBarController else {
return .dismiss(consume: false) return .dismiss(consume: false)
} }

View File

@ -304,7 +304,7 @@ private final class ChatListContainerItemNode: ASDisplayNode {
if let currentNode = strongSelf.emptyNode { if let currentNode = strongSelf.emptyNode {
currentNode.updateIsLoading(isLoading) currentNode.updateIsLoading(isLoading)
} else { } else {
let emptyNode = ChatListEmptyNode(isFilter: filter != nil, isLoading: isLoading, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, action: { let emptyNode = ChatListEmptyNode(context: context, isFilter: filter != nil, isLoading: isLoading, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, action: {
self?.emptyAction(filter) self?.emptyAction(filter)
}) })
strongSelf.emptyNode = emptyNode strongSelf.emptyNode = emptyNode

View File

@ -4,9 +4,11 @@ import AsyncDisplayKit
import Display import Display
import TelegramPresentationData import TelegramPresentationData
import AnimatedStickerNode import AnimatedStickerNode
import TelegramAnimatedStickerNode
import AppBundle import AppBundle
import SolidRoundedButtonNode import SolidRoundedButtonNode
import ActivityIndicator import ActivityIndicator
import AccountContext
final class ChatListEmptyNode: ASDisplayNode { final class ChatListEmptyNode: ASDisplayNode {
private let action: () -> Void private let action: () -> Void
@ -24,7 +26,7 @@ final class ChatListEmptyNode: ASDisplayNode {
private var validLayout: CGSize? private var validLayout: CGSize?
init(isFilter: Bool, isLoading: Bool, theme: PresentationTheme, strings: PresentationStrings, action: @escaping () -> Void) { init(context: AccountContext, isFilter: Bool, isLoading: Bool, theme: PresentationTheme, strings: PresentationStrings, action: @escaping () -> Void) {
self.action = action self.action = action
self.isFilter = isFilter self.isFilter = isFilter
self.isLoading = isLoading self.isLoading = isLoading
@ -67,11 +69,10 @@ final class ChatListEmptyNode: ASDisplayNode {
} else { } else {
animationName = "ChatListEmpty" animationName = "ChatListEmpty"
} }
if let path = getAppBundle().path(forResource: animationName, ofType: "tgs") {
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 248, height: 248, playbackMode: .once, mode: .direct(cachePathPrefix: nil)) self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: animationName), width: 248, height: 248, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.animationSize = CGSize(width: 124.0, height: 124.0) self.animationSize = CGSize(width: 124.0, height: 124.0)
self.animationNode.visibility = true self.animationNode.visibility = true
}
self.animationNode.isHidden = self.isLoading self.animationNode.isHidden = self.isLoading
self.textNode.isHidden = self.isLoading self.textNode.isHidden = self.isLoading

View File

@ -326,7 +326,7 @@ private enum ChatListFilterPresetEntry: ItemListNodeEntry {
let arguments = arguments as! ChatListFilterPresetControllerArguments let arguments = arguments as! ChatListFilterPresetControllerArguments
switch self { switch self {
case .screenHeader: case .screenHeader:
return ChatListFilterSettingsHeaderItem(theme: presentationData.theme, text: "", animation: .newFolder, sectionId: self.section) return ChatListFilterSettingsHeaderItem(context: arguments.context, theme: presentationData.theme, text: "", animation: .newFolder, sectionId: self.section)
case let .nameHeader(title): case let .nameHeader(title):
return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section) return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section)
case let .name(placeholder, value): case let .name(placeholder, value):

View File

@ -138,7 +138,7 @@ private enum ChatListFilterPresetListEntry: ItemListNodeEntry {
let arguments = arguments as! ChatListFilterPresetListControllerArguments let arguments = arguments as! ChatListFilterPresetListControllerArguments
switch self { switch self {
case let .screenHeader(text): case let .screenHeader(text):
return ChatListFilterSettingsHeaderItem(theme: presentationData.theme, text: text, animation: .folders, sectionId: self.section) return ChatListFilterSettingsHeaderItem(context: arguments.context, theme: presentationData.theme, text: text, animation: .folders, sectionId: self.section)
case let .suggestedListHeader(text): case let .suggestedListHeader(text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, multiline: true, sectionId: self.section) return ItemListSectionHeaderItem(presentationData: presentationData, text: text, multiline: true, sectionId: self.section)
case let .suggestedPreset(_, title, label, preset): case let .suggestedPreset(_, title, label, preset):

View File

@ -18,6 +18,7 @@ import TelegramBaseController
import OverlayStatusController import OverlayStatusController
import ListMessageItem import ListMessageItem
import AnimatedStickerNode import AnimatedStickerNode
import TelegramAnimatedStickerNode
import ChatListSearchItemHeader import ChatListSearchItemHeader
import PhoneNumberFormat import PhoneNumberFormat
import InstantPageUI import InstantPageUI
@ -794,10 +795,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
super.init() super.init()
if let path = getAppBundle().path(forResource: "ChatListNoResults", ofType: "tgs") { self.emptyResultsAnimationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "ChatListNoResults"), width: 256, height: 256, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.emptyResultsAnimationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 256, height: 256, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.emptyResultsAnimationSize = CGSize(width: 148.0, height: 148.0) self.emptyResultsAnimationSize = CGSize(width: 148.0, height: 148.0)
}
self.addSubnode(self.recentListNode) self.addSubnode(self.recentListNode)
self.addSubnode(self.listNode) self.addSubnode(self.listNode)

View File

@ -920,7 +920,7 @@ public final class ContactListNode: ASDisplayNode {
var authorizeImpl: (() -> Void)? var authorizeImpl: (() -> Void)?
var openPrivacyPolicyImpl: (() -> Void)? var openPrivacyPolicyImpl: (() -> Void)?
self.authorizationNode = PermissionContentNode(theme: self.presentationData.theme, strings: self.presentationData.strings, kind: PermissionKind.contacts.rawValue, icon: .image(UIImage(bundleImageName: "Settings/Permissions/Contacts")), title: self.presentationData.strings.Contacts_PermissionsTitle, text: self.presentationData.strings.Contacts_PermissionsText, buttonTitle: self.presentationData.strings.Contacts_PermissionsAllow, buttonAction: { self.authorizationNode = PermissionContentNode(context: self.context, theme: self.presentationData.theme, strings: self.presentationData.strings, kind: PermissionKind.contacts.rawValue, icon: .image(UIImage(bundleImageName: "Settings/Permissions/Contacts")), title: self.presentationData.strings.Contacts_PermissionsTitle, text: self.presentationData.strings.Contacts_PermissionsText, buttonTitle: self.presentationData.strings.Contacts_PermissionsAllow, buttonAction: {
authorizeImpl?() authorizeImpl?()
}, openPrivacyPolicy: { }, openPrivacyPolicy: {
openPrivacyPolicyImpl?() openPrivacyPolicyImpl?()
@ -1376,7 +1376,7 @@ public final class ContactListNode: ASDisplayNode {
let authorizationPreviousHidden = strongSelf.authorizationNode.isHidden let authorizationPreviousHidden = strongSelf.authorizationNode.isHidden
strongSelf.authorizationNode.removeFromSupernode() strongSelf.authorizationNode.removeFromSupernode()
strongSelf.authorizationNode = PermissionContentNode(theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, kind: PermissionKind.contacts.rawValue, icon: .image(UIImage(bundleImageName: "Settings/Permissions/Contacts")), title: strongSelf.presentationData.strings.Contacts_PermissionsTitle, text: strongSelf.presentationData.strings.Contacts_PermissionsText, buttonTitle: strongSelf.presentationData.strings.Contacts_PermissionsAllow, buttonAction: { strongSelf.authorizationNode = PermissionContentNode(context: strongSelf.context, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, kind: PermissionKind.contacts.rawValue, icon: .image(UIImage(bundleImageName: "Settings/Permissions/Contacts")), title: strongSelf.presentationData.strings.Contacts_PermissionsTitle, text: strongSelf.presentationData.strings.Contacts_PermissionsText, buttonTitle: strongSelf.presentationData.strings.Contacts_PermissionsAllow, buttonAction: {
authorizeImpl?() authorizeImpl?()
}, openPrivacyPolicy: { }, openPrivacyPolicy: {
openPrivacyPolicyImpl?() openPrivacyPolicyImpl?()

View File

@ -52,6 +52,8 @@ swift_library(
"//submodules/SectionHeaderItem:SectionHeaderItem", "//submodules/SectionHeaderItem:SectionHeaderItem",
"//submodules/DirectionalPanGesture:DirectionalPanGesture", "//submodules/DirectionalPanGesture:DirectionalPanGesture",
"//submodules/ShimmerEffect:ShimmerEffect", "//submodules/ShimmerEffect:ShimmerEffect",
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -7,14 +7,17 @@ import TelegramPresentationData
import ItemListUI import ItemListUI
import PresentationDataUtils import PresentationDataUtils
import AnimatedStickerNode import AnimatedStickerNode
import AppBundle import TelegramAnimatedStickerNode
import AccountContext
class InviteLinkHeaderItem: ListViewItem, ItemListItem { class InviteLinkHeaderItem: ListViewItem, ItemListItem {
let context: AccountContext
let theme: PresentationTheme let theme: PresentationTheme
let text: String let text: String
let sectionId: ItemListSectionId let sectionId: ItemListSectionId
init(theme: PresentationTheme, text: String, sectionId: ItemListSectionId) { init(context: AccountContext, theme: PresentationTheme, text: String, sectionId: ItemListSectionId) {
self.context = context
self.theme = theme self.theme = theme
self.text = text self.text = text
self.sectionId = sectionId self.sectionId = sectionId
@ -72,10 +75,6 @@ class InviteLinkHeaderItemNode: ListViewItemNode {
self.titleNode.contentsScale = UIScreen.main.scale self.titleNode.contentsScale = UIScreen.main.scale
self.animationNode = AnimatedStickerNode() self.animationNode = AnimatedStickerNode()
if let path = getAppBundle().path(forResource: "Invite", ofType: "tgs") {
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 192, height: 192, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
self.animationNode.visibility = true
}
super.init(layerBacked: false, dynamicBounce: false) super.init(layerBacked: false, dynamicBounce: false)
@ -100,6 +99,10 @@ class InviteLinkHeaderItemNode: ListViewItemNode {
return (layout, { [weak self] in return (layout, { [weak self] in
if let strongSelf = self { if let strongSelf = self {
if strongSelf.item == nil {
strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "Invite"), width: 192, height: 192, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
strongSelf.animationNode.visibility = true
}
strongSelf.item = item strongSelf.item = item
strongSelf.accessibilityLabel = attributedText.string strongSelf.accessibilityLabel = attributedText.string

View File

@ -211,7 +211,7 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
let arguments = arguments as! InviteLinkListControllerArguments let arguments = arguments as! InviteLinkListControllerArguments
switch self { switch self {
case let .header(theme, text): case let .header(theme, text):
return InviteLinkHeaderItem(theme: theme, text: text, sectionId: self.section) return InviteLinkHeaderItem(context: arguments.context, theme: theme, text: text, sectionId: self.section)
case let .mainLinkHeader(_, text): case let .mainLinkHeader(_, text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .mainLink(_, invite, peers, importersCount, isPublic): case let .mainLink(_, invite, peers, importersCount, isPublic):

View File

@ -9,6 +9,7 @@ import QrCode
import AccountContext import AccountContext
import SolidRoundedButtonNode import SolidRoundedButtonNode
import AnimatedStickerNode import AnimatedStickerNode
import TelegramAnimatedStickerNode
import TelegramCore import TelegramCore
private func shareQrCode(context: AccountContext, link: String, view: UIView) { private func shareQrCode(context: AccountContext, link: String, view: UIView) {
@ -226,10 +227,9 @@ public final class InviteLinkQRCodeController: ViewController {
self.qrImageNode.cornerRadius = 16.0 self.qrImageNode.cornerRadius = 16.0
self.qrIconNode = AnimatedStickerNode() self.qrIconNode = AnimatedStickerNode()
if let path = getAppBundle().path(forResource: "PlaneLogo", ofType: "tgs") {
self.qrIconNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 240, height: 240, mode: .direct(cachePathPrefix: nil)) self.qrIconNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "PlaneLogo"), width: 240, height: 240, mode: .direct(cachePathPrefix: nil))
self.qrIconNode.visibility = true self.qrIconNode.visibility = true
}
super.init() super.init()

View File

@ -14,6 +14,7 @@ swift_library(
"//submodules/Postbox:Postbox", "//submodules/Postbox:Postbox",
"//submodules/TelegramCore:TelegramCore", "//submodules/TelegramCore:TelegramCore",
"//submodules/ImageCompression:ImageCompression", "//submodules/ImageCompression:ImageCompression",
"//submodules/PersistentStringHash:PersistentStringHash",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -2,6 +2,7 @@ import Foundation
import UIKit import UIKit
import Postbox import Postbox
import TelegramCore import TelegramCore
import PersistentStringHash
public final class VideoMediaResourceAdjustments: PostboxCoding, Equatable { public final class VideoMediaResourceAdjustments: PostboxCoding, Equatable {
public let data: MemoryBuffer public let data: MemoryBuffer
@ -318,3 +319,56 @@ public final class LocalFileGifMediaResource: TelegramMediaResource {
} }
} }
} }
public struct BundleResourceId: MediaResourceId {
public let nameHash: Int64
public var uniqueId: String {
return "bundle-\(nameHash)"
}
public var hashValue: Int {
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 let nameHash: Int64
public let path: String
public init(name: String, path: String) {
self.nameHash = Int64(bitPattern: name.persistentHashValue)
self.path = path
}
public required init(decoder: PostboxDecoder) {
self.nameHash = decoder.decodeInt64ForKey("h", orElse: 0)
self.path = decoder.decodeStringForKey("p", orElse: "")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt64(self.nameHash, forKey: "h")
encoder.encodeString(self.path, forKey: "p")
}
public var id: MediaResourceId {
return BundleResourceId(nameHash: self.nameHash)
}
public func isEqual(to: MediaResource) -> Bool {
if let to = to as? BundleResource {
return self.nameHash == to.nameHash
} else {
return false
}
}
}

View File

@ -723,7 +723,7 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
text = strongSelf.presentationData.strings.Location_ProximityTip(peer.compactDisplayTitle).string text = strongSelf.presentationData.strings.Location_ProximityTip(peer.compactDisplayTitle).string
} }
strongSelf.interaction.present(TooltipScreen(text: text, icon: nil, location: .point(location.offsetBy(dx: -9.0, dy: 0.0), .right), displayDuration: .custom(3.0), shouldDismissOnTouch: { _ in strongSelf.interaction.present(TooltipScreen(account: strongSelf.context.account, text: text, icon: nil, location: .point(location.offsetBy(dx: -9.0, dy: 0.0), .right), displayDuration: .custom(3.0), shouldDismissOnTouch: { _ in
return .dismiss(consume: false) return .dismiss(consume: false)
})) }))
}) })

View File

@ -37,6 +37,7 @@ swift_library(
"//submodules/PresentationDataUtils:PresentationDataUtils", "//submodules/PresentationDataUtils:PresentationDataUtils",
"//submodules/ItemListUI:ItemListUI", "//submodules/ItemListUI:ItemListUI",
"//submodules/AnimatedStickerNode:AnimatedStickerNode", "//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
"//submodules/AppBundle:AppBundle", "//submodules/AppBundle:AppBundle",
"//submodules/SolidRoundedButtonNode:SolidRoundedButtonNode", "//submodules/SolidRoundedButtonNode:SolidRoundedButtonNode",
"//submodules/OverlayStatusController:OverlayStatusController", "//submodules/OverlayStatusController:OverlayStatusController",

View File

@ -11,6 +11,7 @@ import TelegramPresentationData
import PresentationDataUtils import PresentationDataUtils
import TelegramCore import TelegramCore
import AnimatedStickerNode import AnimatedStickerNode
import TelegramAnimatedStickerNode
import ActivityIndicator import ActivityIndicator
public enum TwoFactorDataInputMode { public enum TwoFactorDataInputMode {
@ -104,7 +105,7 @@ public final class TwoFactorDataInputScreen: ViewController {
} }
override public func loadDisplayNode() { override public func loadDisplayNode() {
self.displayNode = TwoFactorDataInputScreenNode(presentationData: self.presentationData, mode: self.mode, action: { [weak self] in self.displayNode = TwoFactorDataInputScreenNode(sharedContext: self.sharedContext, presentationData: self.presentationData, mode: self.mode, action: { [weak self] in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
@ -1247,7 +1248,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
} }
} }
init(presentationData: PresentationData, mode: TwoFactorDataInputMode, action: @escaping () -> Void, skipAction: @escaping () -> Void, changeEmailAction: @escaping () -> Void, resendCodeAction: @escaping () -> Void) { init(sharedContext: SharedAccountContext, presentationData: PresentationData, mode: TwoFactorDataInputMode, action: @escaping () -> Void, skipAction: @escaping () -> Void, changeEmailAction: @escaping () -> Void, resendCodeAction: @escaping () -> Void) {
self.presentationData = presentationData self.presentationData = presentationData
self.mode = mode self.mode = mode
self.action = action self.action = action
@ -1268,27 +1269,21 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
case .password, .passwordRecovery, .emailAddress, .updateEmailAddress: case .password, .passwordRecovery, .emailAddress, .updateEmailAddress:
self.monkeyNode = ManagedMonkeyAnimationNode() self.monkeyNode = ManagedMonkeyAnimationNode()
case .emailConfirmation, .passwordRecoveryEmail: case .emailConfirmation, .passwordRecoveryEmail:
if let path = getAppBundle().path(forResource: "TwoFactorSetupMail", ofType: "tgs") {
let animatedStickerNode = AnimatedStickerNode() let animatedStickerNode = AnimatedStickerNode()
animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 272, height: 272, playbackMode: .once, mode: .direct(cachePathPrefix: nil)) animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupMail"), width: 272, height: 272, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
animatedStickerNode.visibility = true animatedStickerNode.visibility = true
self.animatedStickerNode = animatedStickerNode self.animatedStickerNode = animatedStickerNode
}
case .passwordHint: case .passwordHint:
if let path = getAppBundle().path(forResource: "TwoFactorSetupHint", ofType: "tgs") {
let animatedStickerNode = AnimatedStickerNode() let animatedStickerNode = AnimatedStickerNode()
animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 272, height: 272, playbackMode: .once, mode: .direct(cachePathPrefix: nil)) animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupHint"), width: 272, height: 272, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
animatedStickerNode.visibility = true animatedStickerNode.visibility = true
self.animatedStickerNode = animatedStickerNode self.animatedStickerNode = animatedStickerNode
}
case .rememberPassword: case .rememberPassword:
if let path = getAppBundle().path(forResource: "TwoFactorSetupRemember", ofType: "tgs") {
let animatedStickerNode = AnimatedStickerNode() let animatedStickerNode = AnimatedStickerNode()
animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 272, height: 272, playbackMode: .count(3), mode: .direct(cachePathPrefix: nil)) animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupRemember"), width: 272, height: 272, playbackMode: .count(3), mode: .direct(cachePathPrefix: nil))
animatedStickerNode.visibility = true animatedStickerNode.visibility = true
self.animatedStickerNode = animatedStickerNode self.animatedStickerNode = animatedStickerNode
} }
}
let title: String let title: String
let text: NSAttributedString let text: NSAttributedString

View File

@ -1,12 +1,12 @@
import Foundation import Foundation
import UIKit import UIKit
import AppBundle
import AsyncDisplayKit import AsyncDisplayKit
import Display import Display
import SolidRoundedButtonNode import SolidRoundedButtonNode
import SwiftSignalKit import SwiftSignalKit
import OverlayStatusController import OverlayStatusController
import AnimatedStickerNode import AnimatedStickerNode
import TelegramAnimatedStickerNode
import AccountContext import AccountContext
import TelegramPresentationData import TelegramPresentationData
import PresentationDataUtils import PresentationDataUtils
@ -141,21 +141,17 @@ private final class TwoFactorAuthSplashScreenNode: ViewControllerTracingNode {
texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Intro_Text, font: textFont, textColor: textColor)] texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Intro_Text, font: textFont, textColor: textColor)]
buttonText = self.presentationData.strings.TwoFactorSetup_Intro_Action buttonText = self.presentationData.strings.TwoFactorSetup_Intro_Action
if let path = getAppBundle().path(forResource: "TwoFactorSetupIntro", ofType: "tgs") { self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupIntro"), width: 248, height: 248, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 248, height: 248, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.animationSize = CGSize(width: 124.0, height: 124.0) self.animationSize = CGSize(width: 124.0, height: 124.0)
self.animationNode.visibility = true self.animationNode.visibility = true
}
case .done: case .done:
title = self.presentationData.strings.TwoFactorSetup_Done_Title title = self.presentationData.strings.TwoFactorSetup_Done_Title
texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Done_Text, font: textFont, textColor: textColor)] texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Done_Text, font: textFont, textColor: textColor)]
buttonText = self.presentationData.strings.TwoFactorSetup_Done_Action buttonText = self.presentationData.strings.TwoFactorSetup_Done_Action
if let path = getAppBundle().path(forResource: "TwoFactorSetupDone", ofType: "tgs") { self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupDone"), width: 248, height: 248, mode: .direct(cachePathPrefix: nil))
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 248, height: 248, mode: .direct(cachePathPrefix: nil))
self.animationSize = CGSize(width: 124.0, height: 124.0) self.animationSize = CGSize(width: 124.0, height: 124.0)
self.animationNode.visibility = true self.animationNode.visibility = true
}
case let .recoveryDone(_, _, isPasswordSet): case let .recoveryDone(_, _, isPasswordSet):
title = isPasswordSet ? self.presentationData.strings.TwoFactorSetup_ResetDone_Title : self.presentationData.strings.TwoFactorSetup_ResetDone_TitleNoPassword title = isPasswordSet ? self.presentationData.strings.TwoFactorSetup_ResetDone_Title : self.presentationData.strings.TwoFactorSetup_ResetDone_TitleNoPassword
@ -176,22 +172,18 @@ private final class TwoFactorAuthSplashScreenNode: ViewControllerTracingNode {
texts = splitTexts.map { NSAttributedString(string: $0, font: textFont, textColor: textColor) } texts = splitTexts.map { NSAttributedString(string: $0, font: textFont, textColor: textColor) }
buttonText = self.presentationData.strings.TwoFactorSetup_ResetDone_Action buttonText = self.presentationData.strings.TwoFactorSetup_ResetDone_Action
if let path = getAppBundle().path(forResource: isPasswordSet ? "TwoFactorSetupDone" : "TwoFactorRemovePasswordDone", ofType: "tgs") { self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: isPasswordSet ? "TwoFactorSetupDone" : "TwoFactorRemovePasswordDone"), width: 248, height: 248, playbackMode: isPasswordSet ? .loop : .once, mode: .direct(cachePathPrefix: nil))
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 248, height: 248, playbackMode: isPasswordSet ? .loop : .once, mode: .direct(cachePathPrefix: nil))
self.animationSize = CGSize(width: 124.0, height: 124.0) self.animationSize = CGSize(width: 124.0, height: 124.0)
self.animationNode.visibility = true self.animationNode.visibility = true
}
case .remember: case .remember:
title = self.presentationData.strings.TwoFactorRemember_Done_Title title = self.presentationData.strings.TwoFactorRemember_Done_Title
texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorRemember_Done_Text, font: textFont, textColor: textColor)] texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorRemember_Done_Text, font: textFont, textColor: textColor)]
buttonText = self.presentationData.strings.TwoFactorRemember_Done_Action buttonText = self.presentationData.strings.TwoFactorRemember_Done_Action
if let path = getAppBundle().path(forResource: "TwoFactorSetupRememberSuccess", ofType: "tgs") { self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupRememberSuccess"), width: 248, height: 248, mode: .direct(cachePathPrefix: nil))
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 248, height: 248, mode: .direct(cachePathPrefix: nil))
self.animationSize = CGSize(width: 124.0, height: 124.0) self.animationSize = CGSize(width: 124.0, height: 124.0)
self.animationNode.visibility = true self.animationNode.visibility = true
} }
}
self.titleNode = ImmediateTextNode() self.titleNode = ImmediateTextNode()
self.titleNode.displaysAsynchronously = false self.titleNode.displaysAsynchronously = false

View File

@ -71,6 +71,8 @@ swift_library(
"//submodules/ChatListFilterSettingsHeaderItem:ChatListFilterSettingsHeaderItem", "//submodules/ChatListFilterSettingsHeaderItem:ChatListFilterSettingsHeaderItem",
"//submodules/InviteLinksUI:InviteLinksUI", "//submodules/InviteLinksUI:InviteLinksUI",
"//submodules/UIKitRuntimeUtils:UIKitRuntimeUtils", "//submodules/UIKitRuntimeUtils:UIKitRuntimeUtils",
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -142,7 +142,7 @@ private enum ChannelDiscussionGroupSetupControllerEntry: ItemListNodeEntry {
} else { } else {
text = presentationData.strings.Channel_CommentsGroup_Header text = presentationData.strings.Channel_CommentsGroup_Header
} }
return ChatListFilterSettingsHeaderItem(theme: presentationData.theme, text: text, animation: .discussionGroupSetup, sectionId: self.section) return ChatListFilterSettingsHeaderItem(context: arguments.context, theme: presentationData.theme, text: text, animation: .discussionGroupSetup, sectionId: self.section)
case let .create(theme, text): case let .create(theme, text):
return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.plusIconImage(theme), title: text, sectionId: self.section, editing: false, action: { return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.plusIconImage(theme), title: text, sectionId: self.section, editing: false, action: {
arguments.createGroup() arguments.createGroup()

View File

@ -11,9 +11,11 @@ import AccountContext
import ChatListFilterSettingsHeaderItem import ChatListFilterSettingsHeaderItem
private final class PeerAutoremoveSetupArguments { private final class PeerAutoremoveSetupArguments {
let context: AccountContext
let updateValue: (Int32) -> Void let updateValue: (Int32) -> Void
init(updateValue: @escaping (Int32) -> Void) { init(context: AccountContext, updateValue: @escaping (Int32) -> Void) {
self.context = context
self.updateValue = updateValue self.updateValue = updateValue
} }
} }
@ -86,7 +88,7 @@ private enum PeerAutoremoveSetupEntry: ItemListNodeEntry {
let arguments = arguments as! PeerAutoremoveSetupArguments let arguments = arguments as! PeerAutoremoveSetupArguments
switch self { switch self {
case .header: case .header:
return ChatListFilterSettingsHeaderItem(theme: presentationData.theme, text: "", animation: .autoRemove, sectionId: self.section) return ChatListFilterSettingsHeaderItem(context: arguments.context, theme: presentationData.theme, text: "", animation: .autoRemove, sectionId: self.section)
case let .timeHeader(text): case let .timeHeader(text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .timeValue(value, availableValues): case let .timeValue(value, availableValues):
@ -157,7 +159,7 @@ public func peerAutoremoveSetupScreen(context: AccountContext, updatedPresentati
let applyDisposable = MetaDisposable() let applyDisposable = MetaDisposable()
actionsDisposable.add(applyDisposable) actionsDisposable.add(applyDisposable)
let arguments = PeerAutoremoveSetupArguments(updateValue: { value in let arguments = PeerAutoremoveSetupArguments(context: context, updateValue: { value in
updateState { state in updateState { state in
var state = state var state = state
state.changedValue = value state.changedValue = value

View File

@ -92,9 +92,7 @@ public func presentPeerReportOptions(context: AccountContext, parent: ViewContro
} }
let displaySuccess = { let displaySuccess = {
if let path = getAppBundle().path(forResource: "PoliceCar", ofType: "tgs") { parent?.present(UndoOverlayController(presentationData: presentationData, content: .emoji(name: "PoliceCar", text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current)
parent?.present(UndoOverlayController(presentationData: presentationData, content: .emoji(path: path, text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current)
}
} }
if passthrough { if passthrough {
@ -221,9 +219,7 @@ public func peerReportOptionsController(context: AccountContext, subject: PeerRe
} }
let displaySuccess = { let displaySuccess = {
if let path = getAppBundle().path(forResource: "PoliceCar", ofType: "tgs") { present(UndoOverlayController(presentationData: presentationData, content: .emoji(name: "PoliceCar", text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), nil)
present(UndoOverlayController(presentationData: presentationData, content: .emoji(path: path, text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), nil)
}
} }
let action: (String) -> Void = { message in let action: (String) -> Void = { message in

View File

@ -7,7 +7,7 @@ import TelegramPresentationData
import TelegramUIPreferences import TelegramUIPreferences
import AccountContext import AccountContext
import AnimatedStickerNode import AnimatedStickerNode
import AppBundle import TelegramAnimatedStickerNode
public final class ReportPeerHeaderActionSheetItem: ActionSheetItem { public final class ReportPeerHeaderActionSheetItem: ActionSheetItem {
let context: AccountContext let context: AccountContext
@ -40,10 +40,8 @@ private final class ReportPeerHeaderActionSheetItemNode: ActionSheetItemNode {
let textFont = Font.regular(floor(theme.baseFontSize * 13.0 / 17.0)) let textFont = Font.regular(floor(theme.baseFontSize * 13.0 / 17.0))
self.animationNode = AnimatedStickerNode() self.animationNode = AnimatedStickerNode()
if let path = getAppBundle().path(forResource: "Cop", ofType: "tgs") { self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "Cop"), width: 192, height: 192, playbackMode: .count(2), mode: .direct(cachePathPrefix: nil))
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 192, height: 192, playbackMode: .count(2), mode: .direct(cachePathPrefix: nil))
self.animationNode.visibility = true self.animationNode.visibility = true
}
self.textNode = ImmediateTextNode() self.textNode = ImmediateTextNode()
self.textNode.displaysAsynchronously = false self.textNode.displaysAsynchronously = false

View File

@ -30,6 +30,7 @@ swift_library(
"//submodules/Geocoding:Geocoding", "//submodules/Geocoding:Geocoding",
"//submodules/AppBundle:AppBundle", "//submodules/AppBundle:AppBundle",
"//submodules/AnimatedStickerNode:AnimatedStickerNode", "//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
"//submodules/TelegramStringFormatting:TelegramStringFormatting", "//submodules/TelegramStringFormatting:TelegramStringFormatting",
"//submodules/TelegramNotices:TelegramNotices", "//submodules/TelegramNotices:TelegramNotices",
], ],

View File

@ -215,7 +215,7 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
let arguments = arguments as! PeersNearbyControllerArguments let arguments = arguments as! PeersNearbyControllerArguments
switch self { switch self {
case let .header(theme, text): case let .header(theme, text):
return PeersNearbyHeaderItem(theme: theme, text: text, sectionId: self.section) return PeersNearbyHeaderItem(context: arguments.context, theme: theme, text: text, sectionId: self.section)
case let .usersHeader(_, text, loading): case let .usersHeader(_, text, loading):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, activityIndicator: loading ? .left : .none, sectionId: self.section) return ItemListSectionHeaderItem(presentationData: presentationData, text: text, activityIndicator: loading ? .left : .none, sectionId: self.section)
case let .empty(theme, text): case let .empty(theme, text):

View File

@ -7,14 +7,17 @@ import TelegramPresentationData
import ItemListUI import ItemListUI
import PresentationDataUtils import PresentationDataUtils
import AnimatedStickerNode import AnimatedStickerNode
import AppBundle import TelegramAnimatedStickerNode
import AccountContext
class PeersNearbyHeaderItem: ListViewItem, ItemListItem { class PeersNearbyHeaderItem: ListViewItem, ItemListItem {
let context: AccountContext
let theme: PresentationTheme let theme: PresentationTheme
let text: String let text: String
let sectionId: ItemListSectionId let sectionId: ItemListSectionId
init(theme: PresentationTheme, text: String, sectionId: ItemListSectionId) { init(context: AccountContext, theme: PresentationTheme, text: String, sectionId: ItemListSectionId) {
self.context = context
self.theme = theme self.theme = theme
self.text = text self.text = text
self.sectionId = sectionId self.sectionId = sectionId
@ -72,10 +75,6 @@ class PeersNearbyHeaderItemNode: ListViewItemNode {
self.titleNode.contentsScale = UIScreen.main.scale self.titleNode.contentsScale = UIScreen.main.scale
self.animationNode = AnimatedStickerNode() self.animationNode = AnimatedStickerNode()
if let path = getAppBundle().path(forResource: "Compass", ofType: "tgs") {
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 192, height: 192, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.animationNode.visibility = true
}
super.init(layerBacked: false, dynamicBounce: false) super.init(layerBacked: false, dynamicBounce: false)
@ -100,6 +99,10 @@ class PeersNearbyHeaderItemNode: ListViewItemNode {
return (layout, { [weak self] in return (layout, { [weak self] in
if let strongSelf = self { if let strongSelf = self {
if strongSelf.item == nil {
strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "Compass"), width: 192, height: 192, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
strongSelf.animationNode.visibility = true
}
strongSelf.item = item strongSelf.item = item
strongSelf.accessibilityLabel = attributedText.string strongSelf.accessibilityLabel = attributedText.string

View File

@ -228,6 +228,7 @@ private struct EditThemeControllerState: Equatable {
var slug: String var slug: String
var updatedTheme: PresentationTheme? var updatedTheme: PresentationTheme?
var updating: Bool var updating: Bool
var converting: Bool
} }
private func editThemeControllerEntries(presentationData: PresentationData, state: EditThemeControllerState, previewTheme: PresentationTheme, hasSettings: Bool) -> [EditThemeControllerEntry] { private func editThemeControllerEntries(presentationData: PresentationData, state: EditThemeControllerState, previewTheme: PresentationTheme, hasSettings: Bool) -> [EditThemeControllerEntry] {
@ -326,7 +327,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
settingsPromise.set(.single(nil)) settingsPromise.set(.single(nil))
hasSettings = false hasSettings = false
} }
initialState = EditThemeControllerState(mode: mode, title: generateThemeName(accentColor: theme.rootController.navigationBar.buttonColor), slug: "", updatedTheme: nil, updating: false) initialState = EditThemeControllerState(mode: mode, title: generateThemeName(accentColor: theme.rootController.navigationBar.buttonColor), slug: "", updatedTheme: nil, updating: false, converting: false)
previewThemePromise.set(.single(theme.withUpdated(name: "", defaultWallpaper: wallpaper))) previewThemePromise.set(.single(theme.withUpdated(name: "", defaultWallpaper: wallpaper)))
case let .edit(info): case let .edit(info):
hasSettings = info.theme.settings != nil hasSettings = info.theme.settings != nil
@ -348,7 +349,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
previewThemePromise.set(.single(presentationData.theme.withUpdated(name: "", defaultWallpaper: presentationData.chatWallpaper))) previewThemePromise.set(.single(presentationData.theme.withUpdated(name: "", defaultWallpaper: presentationData.chatWallpaper)))
} }
initialState = EditThemeControllerState(mode: mode, title: info.theme.title, slug: info.theme.slug, updatedTheme: nil, updating: false) initialState = EditThemeControllerState(mode: mode, title: info.theme.title, slug: info.theme.slug, updatedTheme: nil, updating: false, converting: false)
} }
let statePromise = ValuePromise(initialState, ignoreRepeated: true) let statePromise = ValuePromise(initialState, ignoreRepeated: true)
let stateValue = Atomic(value: initialState) let stateValue = Atomic(value: initialState)
@ -484,6 +485,11 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
} }
let settings = TelegramThemeSettings(baseTheme: theme.referenceTheme.baseTheme, accentColor: theme.rootController.navigationBar.accentTextColor, outgoingAccentColor: outgoingAccentColor, messageColors: theme.chat.message.outgoing.bubble.withWallpaper.fill.map { $0.argb }, animateMessageColors: theme.chat.animateMessageColors, wallpaper: theme.chat.defaultWallpaper) let settings = TelegramThemeSettings(baseTheme: theme.referenceTheme.baseTheme, accentColor: theme.rootController.navigationBar.accentTextColor, outgoingAccentColor: outgoingAccentColor, messageColors: theme.chat.message.outgoing.bubble.withWallpaper.fill.map { $0.argb }, animateMessageColors: theme.chat.animateMessageColors, wallpaper: theme.chat.defaultWallpaper)
settingsPromise.set(.single(settings)) settingsPromise.set(.single(settings))
updateState { current in
var state = current
state.converting = true
return state
}
}) })
}) })
@ -657,7 +663,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
}) })
} }
case let .edit(info): case let .edit(info):
let _ = (prepare |> then(updateTheme(account: context.account, accountManager: context.sharedContext.accountManager, theme: info.theme, title: state.title, slug: state.slug, resource: themeResource, settings: settings) let _ = (prepare |> then(updateTheme(account: context.account, accountManager: context.sharedContext.accountManager, theme: info.theme, title: state.title, slug: state.slug, resource: state.converting ? nil : themeResource, settings: settings, resetFile: state.converting ? true : false)
|> deliverOnMainQueue)).start(next: { next in |> deliverOnMainQueue)).start(next: { next in
if case let .result(resultTheme) = next { if case let .result(resultTheme) = next {
let _ = applyTheme(accountManager: context.sharedContext.accountManager, account: context.account, theme: resultTheme).start() let _ = applyTheme(accountManager: context.sharedContext.accountManager, account: context.account, theme: resultTheme).start()

View File

@ -157,13 +157,13 @@ public final class SlotMachineAnimationNode: ASDisplayNode {
public var success: ((Bool) -> Void)? public var success: ((Bool) -> Void)?
public init(size: CGSize = CGSize(width: 184.0, height: 184.0)) { public init(account: Account, size: CGSize = CGSize(width: 184.0, height: 184.0)) {
self.animationSize = size self.animationSize = size
self.backNode = ManagedAnimationNode(size: self.animationSize) self.backNode = ManagedAnimationNode(size: self.animationSize)
let reelSize = CGSize(width: 384.0, height: 384.0) let reelSize = CGSize(width: 384.0, height: 384.0)
self.leftReelNode = DiceAnimatedStickerNode(size: reelSize) self.leftReelNode = DiceAnimatedStickerNode(account: account, size: reelSize)
self.centerReelNode = DiceAnimatedStickerNode(size: reelSize) self.centerReelNode = DiceAnimatedStickerNode(account: account,size: reelSize)
self.rightReelNode = DiceAnimatedStickerNode(size: reelSize) self.rightReelNode = DiceAnimatedStickerNode(account: account,size: reelSize)
self.frontNode = ManagedAnimationNode(size: self.animationSize) self.frontNode = ManagedAnimationNode(size: self.animationSize)
super.init() super.init()
@ -252,6 +252,7 @@ public final class SlotMachineAnimationNode: ASDisplayNode {
} }
class DiceAnimatedStickerNode: ASDisplayNode { class DiceAnimatedStickerNode: ASDisplayNode {
private let account: Account
public let intrinsicSize: CGSize public let intrinsicSize: CGSize
private let animationNode: AnimatedStickerNode private let animationNode: AnimatedStickerNode
@ -260,7 +261,8 @@ class DiceAnimatedStickerNode: ASDisplayNode {
public var trackStack: [ManagedAnimationItem] = [] public var trackStack: [ManagedAnimationItem] = []
public var didTryAdvancingState = false public var didTryAdvancingState = false
init(size: CGSize) { init(account: Account, size: CGSize) {
self.account = account
self.intrinsicSize = size self.intrinsicSize = size
self.animationNode = AnimatedStickerNode() self.animationNode = AnimatedStickerNode()
@ -309,9 +311,7 @@ class DiceAnimatedStickerNode: ASDisplayNode {
var source: AnimatedStickerNodeSource? var source: AnimatedStickerNodeSource?
switch item.source { switch item.source {
case let .local(animationName): case let .local(animationName):
if let path = getAppBundle().path(forResource: animationName, ofType: "tgs") { source = AnimatedStickerNodeLocalFileSource(name: animationName)
source = AnimatedStickerNodeLocalFileSource(path: path)
}
case let .resource(account, resource): case let .resource(account, resource):
source = AnimatedStickerResourceSource(account: account, resource: resource) source = AnimatedStickerResourceSource(account: account, resource: resource)
} }

View File

@ -28,6 +28,7 @@ swift_library(
"//submodules/GraphCore:GraphCore", "//submodules/GraphCore:GraphCore",
"//submodules/GraphUI:GraphUI", "//submodules/GraphUI:GraphUI",
"//submodules/AnimatedStickerNode:AnimatedStickerNode", "//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
"//submodules/ItemListPeerItem:ItemListPeerItem", "//submodules/ItemListPeerItem:ItemListPeerItem",
"//submodules/ItemListPeerActionItem:ItemListPeerActionItem", "//submodules/ItemListPeerActionItem:ItemListPeerActionItem",
"//submodules/ContextUI:ContextUI", "//submodules/ContextUI:ContextUI",

View File

@ -468,7 +468,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
var emptyStateItem: ItemListControllerEmptyStateItem? var emptyStateItem: ItemListControllerEmptyStateItem?
if data == nil { if data == nil {
if longLoading { if longLoading {
emptyStateItem = StatsEmptyStateItem(theme: presentationData.theme, strings: presentationData.strings) emptyStateItem = StatsEmptyStateItem(context: context, theme: presentationData.theme, strings: presentationData.strings)
} else { } else {
emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme) emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme)
} }

View File

@ -841,7 +841,7 @@ public func groupStatsController(context: AccountContext, updatedPresentationDat
var emptyStateItem: ItemListControllerEmptyStateItem? var emptyStateItem: ItemListControllerEmptyStateItem?
if data == nil { if data == nil {
if longLoading { if longLoading {
emptyStateItem = StatsEmptyStateItem(theme: presentationData.theme, strings: presentationData.strings) emptyStateItem = StatsEmptyStateItem(context: context, theme: presentationData.theme, strings: presentationData.strings)
} else { } else {
emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme) emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme)
} }

View File

@ -234,7 +234,7 @@ public func messageStatsController(context: AccountContext, messageId: MessageId
var emptyStateItem: ItemListControllerEmptyStateItem? var emptyStateItem: ItemListControllerEmptyStateItem?
if data == nil { if data == nil {
if longLoading { if longLoading {
emptyStateItem = StatsEmptyStateItem(theme: presentationData.theme, strings: presentationData.strings) emptyStateItem = StatsEmptyStateItem(context: context, theme: presentationData.theme, strings: presentationData.strings)
} else { } else {
emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme) emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme)
} }

View File

@ -6,13 +6,16 @@ import TelegramPresentationData
import ItemListUI import ItemListUI
import PresentationDataUtils import PresentationDataUtils
import AnimatedStickerNode import AnimatedStickerNode
import AppBundle import TelegramAnimatedStickerNode
import AccountContext
final class StatsEmptyStateItem: ItemListControllerEmptyStateItem { final class StatsEmptyStateItem: ItemListControllerEmptyStateItem {
let context: AccountContext
let theme: PresentationTheme let theme: PresentationTheme
let strings: PresentationStrings let strings: PresentationStrings
init(theme: PresentationTheme, strings: PresentationStrings) { init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) {
self.context = context
self.theme = theme self.theme = theme
self.strings = strings self.strings = strings
} }
@ -54,10 +57,8 @@ final class StatsEmptyStateItemNode: ItemListControllerEmptyStateItemNode {
self.item = item self.item = item
self.animationNode = AnimatedStickerNode() self.animationNode = AnimatedStickerNode()
if let path = getAppBundle().path(forResource: "Charts", ofType: "tgs") { self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "Charts"), width: 192, height: 192, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 192, height: 192, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
self.animationNode.visibility = true self.animationNode.visibility = true
}
self.titleNode = ASTextNode() self.titleNode = ASTextNode()
self.titleNode.isUserInteractionEnabled = false self.titleNode.isUserInteractionEnabled = false

View File

@ -292,7 +292,7 @@ public func preloadedStickerPackThumbnail(account: Account, info: StickerPackCol
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)).start() let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)).start()
let dataDisposable: Disposable let dataDisposable: Disposable
if info.flags.contains(.isAnimated) { if info.flags.contains(.isAnimated) {
dataDisposable = chatMessageAnimationData(postbox: account.postbox, resource: thumbnail.resource, width: 80, height: 80, synchronousLoad: false).start(next: { data in dataDisposable = chatMessageAnimationData(mediaBox: account.postbox.mediaBox, resource: thumbnail.resource, width: 80, height: 80, synchronousLoad: false).start(next: { data in
if data.complete { if data.complete {
subscriber.putNext(true) subscriber.putNext(true)
subscriber.putCompletion() subscriber.putCompletion()

View File

@ -225,9 +225,9 @@ private func chatMessageStickerPackThumbnailData(postbox: Postbox, resource: Med
} }
} }
public func chatMessageAnimationData(postbox: Postbox, resource: MediaResource, fitzModifier: EmojiFitzModifier? = nil, width: Int, height: Int, synchronousLoad: Bool) -> Signal<MediaResourceData, NoError> { public func chatMessageAnimationData(mediaBox: MediaBox, resource: MediaResource, fitzModifier: EmojiFitzModifier? = nil, width: Int, height: Int, synchronousLoad: Bool) -> Signal<MediaResourceData, NoError> {
let representation = CachedAnimatedStickerRepresentation(width: Int32(width), height: Int32(height), fitzModifier: fitzModifier) let representation = CachedAnimatedStickerRepresentation(width: Int32(width), height: Int32(height), fitzModifier: fitzModifier)
let maybeFetched = postbox.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: false, fetch: false, attemptSynchronously: synchronousLoad) let maybeFetched = mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: false, fetch: false, attemptSynchronously: synchronousLoad)
return maybeFetched return maybeFetched
|> take(1) |> take(1)
@ -235,7 +235,7 @@ public func chatMessageAnimationData(postbox: Postbox, resource: MediaResource,
if maybeData.complete { if maybeData.complete {
return .single(maybeData) return .single(maybeData)
} else { } else {
return postbox.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: false) return mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: false)
} }
} }
} }

View File

@ -14,6 +14,7 @@ swift_library(
"//submodules/TelegramCore:TelegramCore", "//submodules/TelegramCore:TelegramCore",
"//submodules/StickerResources:StickerResources", "//submodules/StickerResources:StickerResources",
"//submodules/MediaResources:MediaResources", "//submodules/MediaResources:MediaResources",
"//submodules/LocalMediaResources:LocalMediaResources",
"//submodules/Tuples:Tuples", "//submodules/Tuples:Tuples",
"//submodules/AnimatedStickerNode:AnimatedStickerNode", "//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/rlottie:RLottieBinding", "//submodules/rlottie:RLottieBinding",

View File

@ -5,6 +5,40 @@ import Postbox
import TelegramCore import TelegramCore
import MediaResources import MediaResources
import StickerResources import StickerResources
import LocalMediaResources
import AppBundle
public final class AnimatedStickerNodeLocalFileSource: AnimatedStickerNodeSource {
public var fitzModifier: EmojiFitzModifier? = nil
public let name: String
public init(name: String) {
self.name = name
}
public func directDataPath() -> Signal<String, NoError> {
if let path = self.path {
return .single(path)
} else {
return .never()
}
}
public func cachedDataPath(width: Int, height: Int) -> Signal<(String, Bool), NoError> {
return .never()
}
public var path: String? {
if let path = getAppBundle().path(forResource: self.name, ofType: "tgs") {
return path
} else if let path = getAppBundle().path(forResource: self.name, ofType: "json") {
return path
} else {
return nil
}
}
}
public final class AnimatedStickerResourceSource: AnimatedStickerNodeSource { public final class AnimatedStickerResourceSource: AnimatedStickerNodeSource {
public let account: Account public let account: Account
@ -18,7 +52,7 @@ public final class AnimatedStickerResourceSource: AnimatedStickerNodeSource {
} }
public func cachedDataPath(width: Int, height: Int) -> Signal<(String, Bool), NoError> { public func cachedDataPath(width: Int, height: Int) -> Signal<(String, Bool), NoError> {
return chatMessageAnimationData(postbox: self.account.postbox, resource: self.resource, fitzModifier: self.fitzModifier, width: width, height: height, synchronousLoad: false) return chatMessageAnimationData(mediaBox: self.account.postbox.mediaBox, resource: self.resource, fitzModifier: self.fitzModifier, width: width, height: height, synchronousLoad: false)
|> filter { data in |> filter { data in
return data.size != 0 return data.size != 0
} }

View File

@ -726,7 +726,7 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro
return return
} }
self.present?(TooltipScreen(text: self.presentationData.strings.Call_CameraOrScreenTooltip, style: .light, icon: nil, location: .point(location.offsetBy(dx: 0.0, dy: -14.0), .bottom), displayDuration: .custom(5.0), shouldDismissOnTouch: { _ in self.present?(TooltipScreen(account: self.account, text: self.presentationData.strings.Call_CameraOrScreenTooltip, style: .light, icon: nil, location: .point(location.offsetBy(dx: 0.0, dy: -14.0), .bottom), displayDuration: .custom(5.0), shouldDismissOnTouch: { _ in
return .dismiss(consume: false) return .dismiss(consume: false)
})) }))
} }

View File

@ -2264,7 +2264,7 @@ public final class VoiceChatController: ViewController {
} else { } else {
text = presentationData.strings.VoiceChat_RecordingInProgress text = presentationData.strings.VoiceChat_RecordingInProgress
} }
strongSelf.controller?.present(TooltipScreen(text: text, icon: nil, location: .point(location.offsetBy(dx: 1.0, dy: 0.0), .top), displayDuration: .custom(3.0), shouldDismissOnTouch: { _ in strongSelf.controller?.present(TooltipScreen(account: strongSelf.context.account, text: text, icon: nil, location: .point(location.offsetBy(dx: 1.0, dy: 0.0), .top), displayDuration: .custom(3.0), shouldDismissOnTouch: { _ in
return .dismiss(consume: true) return .dismiss(consume: true)
}), in: .window(.root)) }), in: .window(.root))
} }
@ -3437,7 +3437,7 @@ public final class VoiceChatController: ViewController {
if !callState.subscribedToScheduled { if !callState.subscribedToScheduled {
let location = self.actionButton.view.convert(self.actionButton.bounds, to: self.view).center let location = self.actionButton.view.convert(self.actionButton.bounds, to: self.view).center
let point = CGRect(origin: CGPoint(x: location.x - 5.0, y: location.y - 5.0 - 68.0), size: CGSize(width: 10.0, height: 10.0)) let point = CGRect(origin: CGPoint(x: location.x - 5.0, y: location.y - 5.0 - 68.0), size: CGSize(width: 10.0, height: 10.0))
self.controller?.present(TooltipScreen(text: self.presentationData.strings.VoiceChat_ReminderNotify, style: .gradient(UIColor(rgb: 0x262c5a), UIColor(rgb: 0x5d2835)), icon: nil, location: .point(point, .bottom), displayDuration: .custom(3.0), shouldDismissOnTouch: { _ in self.controller?.present(TooltipScreen(account: self.context.account, text: self.presentationData.strings.VoiceChat_ReminderNotify, style: .gradient(UIColor(rgb: 0x262c5a), UIColor(rgb: 0x5d2835)), icon: nil, location: .point(point, .bottom), displayDuration: .custom(3.0), shouldDismissOnTouch: { _ in
return .dismiss(consume: false) return .dismiss(consume: false)
}), in: .window(.root)) }), in: .window(.root))
} }
@ -6323,7 +6323,7 @@ public final class VoiceChatController: ViewController {
point.origin.y += 32.0 point.origin.y += 32.0
} }
} }
self.controller?.present(TooltipScreen(text: self.presentationData.strings.VoiceChat_UnmuteSuggestion, style: .gradient(UIColor(rgb: 0x1d446c), UIColor(rgb: 0x193e63)), icon: nil, location: .point(point, position), displayDuration: .custom(8.0), shouldDismissOnTouch: { _ in self.controller?.present(TooltipScreen(account: self.context.account, text: self.presentationData.strings.VoiceChat_UnmuteSuggestion, style: .gradient(UIColor(rgb: 0x1d446c), UIColor(rgb: 0x193e63)), icon: nil, location: .point(point, position), displayDuration: .custom(8.0), shouldDismissOnTouch: { _ in
return .dismiss(consume: false) return .dismiss(consume: false)
}), in: .window(.root)) }), in: .window(.root))
} }

View File

@ -357,7 +357,7 @@ public func createTheme(account: Account, title: String, resource: MediaResource
} }
} }
public func updateTheme(account: Account, accountManager: AccountManager<TelegramAccountManagerTypes>, theme: TelegramTheme, title: String?, slug: String?, resource: MediaResource?, thumbnailData: Data? = nil, settings: TelegramThemeSettings?) -> Signal<CreateThemeResult, CreateThemeError> { public func updateTheme(account: Account, accountManager: AccountManager<TelegramAccountManagerTypes>, theme: TelegramTheme, title: String?, slug: String?, resource: MediaResource?, thumbnailData: Data? = nil, settings: TelegramThemeSettings?, resetFile: Bool = false) -> Signal<CreateThemeResult, CreateThemeError> {
guard title != nil || slug != nil || resource != nil else { guard title != nil || slug != nil || resource != nil else {
return .complete() return .complete()
} }
@ -370,6 +370,8 @@ public func updateTheme(account: Account, accountManager: AccountManager<Telegra
} }
if let _ = resource { if let _ = resource {
flags |= 1 << 2 flags |= 1 << 2
} else if resetFile {
flags |= 1 << 2
} }
var inputSettings: Api.InputThemeSettings? var inputSettings: Api.InputThemeSettings?
if let settings = settings { if let settings = settings {
@ -389,7 +391,9 @@ public func updateTheme(account: Account, accountManager: AccountManager<Telegra
} }
|> mapToSignal { result -> Signal<CreateThemeResult, CreateThemeError> in |> mapToSignal { result -> Signal<CreateThemeResult, CreateThemeError> in
let inputDocument: Api.InputDocument? let inputDocument: Api.InputDocument?
if let status = result { if resetFile {
inputDocument = .inputDocumentEmpty
} else if let status = result {
switch status { switch status {
case let .complete(file): case let .complete(file):
if let resource = file.resource as? CloudDocumentMediaResource { if let resource = file.resource as? CloudDocumentMediaResource {

View File

@ -26,6 +26,7 @@ swift_library(
"//submodules/AppBundle:AppBundle", "//submodules/AppBundle:AppBundle",
"//submodules/PresentationDataUtils:PresentationDataUtils", "//submodules/PresentationDataUtils:PresentationDataUtils",
"//submodules/AnimatedStickerNode:AnimatedStickerNode", "//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -2,6 +2,7 @@ import Foundation
import UIKit import UIKit
import Display import Display
import AsyncDisplayKit import AsyncDisplayKit
import TelegramCore
import TelegramPresentationData import TelegramPresentationData
import TextFormat import TextFormat
import TelegramPermissions import TelegramPermissions
@ -10,7 +11,9 @@ import SolidRoundedButtonNode
import PresentationDataUtils import PresentationDataUtils
import Markdown import Markdown
import AnimatedStickerNode import AnimatedStickerNode
import TelegramAnimatedStickerNode
import AppBundle import AppBundle
import AccountContext
public enum PermissionContentIcon: Equatable { public enum PermissionContentIcon: Equatable {
case image(UIImage?) case image(UIImage?)
@ -52,7 +55,7 @@ public final class PermissionContentNode: ASDisplayNode {
public var validLayout: (CGSize, UIEdgeInsets)? public var validLayout: (CGSize, UIEdgeInsets)?
public init(theme: PresentationTheme, strings: PresentationStrings, kind: Int32, icon: PermissionContentIcon, title: String, subtitle: String? = nil, text: String, buttonTitle: String, secondaryButtonTitle: String? = nil, footerText: String? = nil, buttonAction: @escaping () -> Void, openPrivacyPolicy: (() -> Void)?) { public init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, kind: Int32, icon: PermissionContentIcon, title: String, subtitle: String? = nil, text: String, buttonTitle: String, secondaryButtonTitle: String? = nil, footerText: String? = nil, buttonAction: @escaping () -> Void, openPrivacyPolicy: (() -> Void)?) {
self.theme = theme self.theme = theme
self.kind = kind self.kind = kind
@ -70,10 +73,10 @@ public final class PermissionContentNode: ASDisplayNode {
if case let .animation(animation) = icon { if case let .animation(animation) = icon {
self.animationNode = AnimatedStickerNode() self.animationNode = AnimatedStickerNode()
if let path = getAppBundle().path(forResource: animation, ofType: "tgs") {
self.animationNode?.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 320, height: 320, playbackMode: .once, mode: .direct(cachePathPrefix: nil)) self.animationNode?.setup(source: AnimatedStickerNodeLocalFileSource(name: animation), width: 320, height: 320, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.animationNode?.visibility = true self.animationNode?.visibility = true
}
self.nearbyIconNode = nil self.nearbyIconNode = nil
} else if kind == PermissionKind.nearbyLocation.rawValue { } else if kind == PermissionKind.nearbyLocation.rawValue {
self.nearbyIconNode = PeersNearbyIconNode(theme: theme) self.nearbyIconNode = PeersNearbyIconNode(theme: theme)

View File

@ -207,7 +207,7 @@ final class PermissionControllerNode: ASDisplayNode {
hasPrivacyPolicy = false hasPrivacyPolicy = false
} }
let contentNode = PermissionContentNode(theme: self.presentationData.theme, strings: self.presentationData.strings, kind: dataState.kind.rawValue, icon: .image(icon), title: title, text: text, buttonTitle: buttonTitle, secondaryButtonTitle: nil, buttonAction: { [weak self] in let contentNode = PermissionContentNode(context: self.context, theme: self.presentationData.theme, strings: self.presentationData.strings, kind: dataState.kind.rawValue, icon: .image(icon), title: title, text: text, buttonTitle: buttonTitle, secondaryButtonTitle: nil, buttonAction: { [weak self] in
self?.allow?() self?.allow?()
}, openPrivacyPolicy: hasPrivacyPolicy ? self.openPrivacyPolicy : nil) }, openPrivacyPolicy: hasPrivacyPolicy ? self.openPrivacyPolicy : nil)
self.insertSubnode(contentNode, at: 0) self.insertSubnode(contentNode, at: 0)
@ -237,7 +237,7 @@ final class PermissionControllerNode: ASDisplayNode {
transition.updateFrame(node: contentNode, frame: contentFrame) transition.updateFrame(node: contentNode, frame: contentFrame)
contentNode.updateLayout(size: contentFrame.size, insets: insets, transition: transition) contentNode.updateLayout(size: contentFrame.size, insets: insets, transition: transition)
} else { } else {
let contentNode = PermissionContentNode(theme: self.presentationData.theme, strings: self.presentationData.strings, kind: 0, icon: icon, title: title, subtitle: subtitle, text: text, buttonTitle: buttonTitle, secondaryButtonTitle: secondaryButtonTitle, footerText: footerText, buttonAction: { [weak self] in let contentNode = PermissionContentNode(context: self.context, theme: self.presentationData.theme, strings: self.presentationData.strings, kind: 0, icon: icon, title: title, subtitle: subtitle, text: text, buttonTitle: buttonTitle, secondaryButtonTitle: secondaryButtonTitle, footerText: footerText, buttonAction: { [weak self] in
self?.allow?() self?.allow?()
}, openPrivacyPolicy: secondaryButtonTitle != nil ? { [weak self] in }, openPrivacyPolicy: secondaryButtonTitle != nil ? { [weak self] in
self?.dismiss?() self?.dismiss?()

View File

@ -5416,9 +5416,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }, completion: { _ in strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }, completion: { _ in
let _ = (strongSelf.context.engine.peers.reportPeerMessages(messageIds: Array(messageIds), reason: reportReason, message: message) let _ = (strongSelf.context.engine.peers.reportPeerMessages(messageIds: Array(messageIds), reason: reportReason, message: message)
|> deliverOnMainQueue).start(completed: { [weak self] in |> deliverOnMainQueue).start(completed: { [weak self] in
if let strongSelf = self, let path = getAppBundle().path(forResource: "PoliceCar", ofType: "tgs") { strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .emoji(name: "PoliceCar", text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current)
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .emoji(path: path, text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current)
}
}) })
}) })
})) }))
@ -7080,9 +7078,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
strongSelf.reportIrrelvantGeoNoticePromise.set(.single(true)) strongSelf.reportIrrelvantGeoNoticePromise.set(.single(true))
let _ = ApplicationSpecificNotice.setIrrelevantPeerGeoReport(postbox: strongSelf.context.account.postbox, peerId: peerId).start() let _ = ApplicationSpecificNotice.setIrrelevantPeerGeoReport(postbox: strongSelf.context.account.postbox, peerId: peerId).start()
if let path = getAppBundle().path(forResource: "PoliceCar", ofType: "tgs") { strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .emoji(name: "PoliceCar", text: strongSelf.presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current)
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .emoji(path: path, text: strongSelf.presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current)
}
} }
}) })
})] })]
@ -9918,7 +9914,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return return
} }
let tooltipScreen = TooltipScreen(text: solution.text, textEntities: solution.entities, icon: .info, location: .top, shouldDismissOnTouch: { point in let tooltipScreen = TooltipScreen(account: self.context.account, text: solution.text, textEntities: solution.entities, icon: .info, location: .top, shouldDismissOnTouch: { point in
return .ignore return .ignore
}, openActiveTextItem: { [weak self] item, action in }, openActiveTextItem: { [weak self] item, action in
guard let strongSelf = self else { guard let strongSelf = self else {
@ -10006,7 +10002,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return return
} }
let tooltipScreen = TooltipScreen(text: psaText, textEntities: psaEntities, icon: .info, location: .top, displayDuration: .custom(10.0), shouldDismissOnTouch: { point in let tooltipScreen = TooltipScreen(account: self.context.account, text: psaText, textEntities: psaEntities, icon: .info, location: .top, displayDuration: .custom(10.0), shouldDismissOnTouch: { point in
return .ignore return .ignore
}, openActiveTextItem: { [weak self] item, action in }, openActiveTextItem: { [weak self] item, action in
guard let strongSelf = self else { guard let strongSelf = self else {
@ -10115,7 +10111,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return return
} }
let tooltipScreen = TooltipScreen(text: psaText, textEntities: psaEntities, icon: .info, location: .top, displayDuration: .custom(10.0), shouldDismissOnTouch: { point in let tooltipScreen = TooltipScreen(account: self.context.account, text: psaText, textEntities: psaEntities, icon: .info, location: .top, displayDuration: .custom(10.0), shouldDismissOnTouch: { point in
return .ignore return .ignore
}, openActiveTextItem: { [weak self] item, action in }, openActiveTextItem: { [weak self] item, action in
guard let strongSelf = self else { guard let strongSelf = self else {

View File

@ -22,6 +22,7 @@ import SlotMachineAnimationNode
import UniversalMediaPlayer import UniversalMediaPlayer
import ShimmerEffect import ShimmerEffect
import WallpaperBackgroundNode import WallpaperBackgroundNode
import LocalMediaResources
import AppBundle import AppBundle
private let nameFont = Font.medium(14.0) private let nameFont = Font.medium(14.0)
@ -407,7 +408,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if let telegramDice = self.telegramDice { if let telegramDice = self.telegramDice {
if telegramDice.emoji == "🎰" { if telegramDice.emoji == "🎰" {
let animationNode = SlotMachineAnimationNode() let animationNode = SlotMachineAnimationNode(account: item.context.account)
if !item.message.effectivelyIncoming(item.context.account.peerId) { if !item.message.effectivelyIncoming(item.context.account.peerId) {
animationNode.success = { [weak self] onlyHaptic in animationNode.success = { [weak self] onlyHaptic in
if let strongSelf = self, let item = strongSelf.item { if let strongSelf = self, let item = strongSelf.item {
@ -1290,20 +1291,28 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
} }
private func playAdditionalAnimation(_ name: String) { private func playAdditionalAnimation(_ name: String) {
guard let path = getAppBundle().path(forResource: name, ofType: "tgs"), let animationSize = self.animationSize, let animationNode = self.animationNode, self.additionalAnimationNodes.count < 4 else { let source = AnimatedStickerNodeLocalFileSource(name: name)
guard let item = self.item, let path = source.path, let animationSize = self.animationSize, let animationNode = self.animationNode, self.additionalAnimationNodes.count < 4 else {
return return
} }
let incoming = item.message.effectivelyIncoming(item.context.account.peerId)
self.supernode?.view.bringSubviewToFront(self.view) self.supernode?.view.bringSubviewToFront(self.view)
let source = AnimatedStickerNodeLocalFileSource(path: path) let resource = BundleResource(name: name, path: path)
let pathPrefix = item.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(resource.id)
let additionalAnimationNode = AnimatedStickerNode() let additionalAnimationNode = AnimatedStickerNode()
additionalAnimationNode.setup(source: source, width: Int(animationSize.width * 3.0), height: Int(animationSize.height * 3.0), playbackMode: .once, mode: .direct(cachePathPrefix: nil)) additionalAnimationNode.setup(source: source, width: Int(animationSize.width * 3.0), height: Int(animationSize.height * 3.0), playbackMode: .once, mode: .direct(cachePathPrefix: pathPrefix))
additionalAnimationNode.completed = { [weak self, weak additionalAnimationNode] _ in additionalAnimationNode.completed = { [weak self, weak additionalAnimationNode] _ in
self?.additionalAnimationNodes.removeAll(where: { $0 === additionalAnimationNode }) self?.additionalAnimationNodes.removeAll(where: { $0 === additionalAnimationNode })
additionalAnimationNode?.removeFromSupernode() additionalAnimationNode?.removeFromSupernode()
} }
additionalAnimationNode.frame = animationNode.frame.insetBy(dx: -animationNode.frame.width, dy: -animationNode.frame.height) additionalAnimationNode.frame = animationNode.frame.insetBy(dx: -animationNode.frame.width, dy: -animationNode.frame.height)
// .offsetBy(dx: incoming ? animationNode.frame.width : -animationNode.frame.width, dy: 0.0)
if incoming {
additionalAnimationNode.transform = CATransform3DMakeScale(-1.0, 1.0, 1.0)
}
self.addSubnode(additionalAnimationNode) self.addSubnode(additionalAnimationNode)
self.additionalAnimationNodes.append(additionalAnimationNode) self.additionalAnimationNodes.append(additionalAnimationNode)
@ -1638,11 +1647,8 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
} }
if let selectionState = item.controllerInteraction.selectionState { if let selectionState = item.controllerInteraction.selectionState {
var selected = false let selected = selectionState.selectedIds.contains(item.message.id)
var incoming = true let incoming = item.message.effectivelyIncoming(item.context.account.peerId)
selected = selectionState.selectedIds.contains(item.message.id)
incoming = item.message.effectivelyIncoming(item.context.account.peerId)
let offset: CGFloat = incoming ? 42.0 : 0.0 let offset: CGFloat = incoming ? 42.0 : 0.0

View File

@ -895,7 +895,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
if let strongSelf = self, count < 3 { if let strongSelf = self, count < 3 {
Queue.mainQueue().after(1.0) { Queue.mainQueue().after(1.0) {
if !strongSelf.animatedOut { if !strongSelf.animatedOut {
strongSelf.present?(TooltipScreen(text: strongSelf.presentationData.theme.overallDarkAppearance ? strongSelf.presentationData.strings.Conversation_Theme_SwitchToLight : strongSelf.presentationData.strings.Conversation_Theme_SwitchToDark, style: .default, icon: nil, location: .point(frame.offsetBy(dx: 3.0, dy: 6.0), .bottom), displayDuration: .custom(3.0), inset: 3.0, shouldDismissOnTouch: { _ in strongSelf.present?(TooltipScreen(account: strongSelf.context.account, text: strongSelf.presentationData.theme.overallDarkAppearance ? strongSelf.presentationData.strings.Conversation_Theme_SwitchToLight : strongSelf.presentationData.strings.Conversation_Theme_SwitchToDark, style: .default, icon: nil, location: .point(frame.offsetBy(dx: 3.0, dy: 6.0), .bottom), displayDuration: .custom(3.0), inset: 3.0, shouldDismissOnTouch: { _ in
return .dismiss(consume: false) return .dismiss(consume: false)
})) }))

View File

@ -40,7 +40,7 @@ private func animationItem(account: Account, emojis: Signal<[TelegramMediaFile],
let fetched = freeMediaFileInteractiveFetched(account: account, fileReference: .standalone(media: file)) let fetched = freeMediaFileInteractiveFetched(account: account, fileReference: .standalone(media: file))
let animationItem = Signal<ManagedAnimationItem?, NoError> { subscriber in let animationItem = Signal<ManagedAnimationItem?, NoError> { subscriber in
let fetchedDisposable = fetched.start() let fetchedDisposable = fetched.start()
let resourceDisposable = (chatMessageAnimationData(postbox: account.postbox, resource: file.resource, fitzModifier: nil, width: Int(fittedSize.width), height: Int(fittedSize.height), synchronousLoad: false) let resourceDisposable = (chatMessageAnimationData(mediaBox: account.postbox.mediaBox, resource: file.resource, fitzModifier: nil, width: Int(fittedSize.width), height: Int(fittedSize.height), synchronousLoad: false)
|> filter { data in |> filter { data in
return data.complete return data.complete
}).start(next: { next in }).start(next: { next in

View File

@ -245,7 +245,7 @@ private final class PrefetchManagerInnerImpl {
|> mapToSignal { sticker -> Signal<Void, NoError> in |> mapToSignal { sticker -> Signal<Void, NoError> in
if let sticker = sticker { if let sticker = sticker {
let _ = freeMediaFileInteractiveFetched(account: account, fileReference: .standalone(media: sticker)).start() let _ = freeMediaFileInteractiveFetched(account: account, fileReference: .standalone(media: sticker)).start()
return chatMessageAnimationData(postbox: account.postbox, resource: sticker.resource, fitzModifier: nil, width: 384, height: 384, synchronousLoad: false) return chatMessageAnimationData(mediaBox: account.postbox.mediaBox, resource: sticker.resource, fitzModifier: nil, width: 384, height: 384, synchronousLoad: false)
|> mapToSignal { _ -> Signal<Void, NoError> in |> mapToSignal { _ -> Signal<Void, NoError> in
return .complete() return .complete()
} }

View File

@ -33,6 +33,14 @@ public let telegramAccountAuxiliaryMethods = AccountAuxiliaryMethods(fetchResour
return fetchEmojiSpriteResource(account: account, resource: resource) return fetchEmojiSpriteResource(account: account, resource: resource)
} else if let resource = resource as? VenueIconResource { } else if let resource = resource as? VenueIconResource {
return fetchVenueIconResource(account: account, resource: resource) return fetchVenueIconResource(account: account, resource: resource)
} else if let resource = resource as? BundleResource {
return Signal { subscriber in
subscriber.putNext(.reset)
if let data = try? Data(contentsOf: URL(fileURLWithPath: resource.path), options: .mappedRead) {
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< data.count, complete: true))
}
return EmptyDisposable
}
} else if let wallpaperResource = resource as? WallpaperDataResource { } else if let wallpaperResource = resource as? WallpaperDataResource {
let builtinWallpapers: [String] = [ let builtinWallpapers: [String] = [
"fqv01SQemVIBAAAApND8LDRUhRU" "fqv01SQemVIBAAAApND8LDRUhRU"

View File

@ -15,9 +15,11 @@ swift_library(
"//submodules/TelegramPresentationData:TelegramPresentationData", "//submodules/TelegramPresentationData:TelegramPresentationData",
"//submodules/AppBundle:AppBundle", "//submodules/AppBundle:AppBundle",
"//submodules/AnimatedStickerNode:AnimatedStickerNode", "//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
"//submodules/TelegramCore:TelegramCore", "//submodules/TelegramCore:TelegramCore",
"//submodules/TextFormat:TextFormat", "//submodules/TextFormat:TextFormat",
"//submodules/UrlEscaping:UrlEscaping", "//submodules/UrlEscaping:UrlEscaping",
"//submodules/AccountContext:AccountContext",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -4,6 +4,7 @@ import AsyncDisplayKit
import Display import Display
import TelegramPresentationData import TelegramPresentationData
import AnimatedStickerNode import AnimatedStickerNode
import TelegramAnimatedStickerNode
import AppBundle import AppBundle
import TelegramCore import TelegramCore
import TextFormat import TextFormat
@ -57,7 +58,7 @@ private final class TooltipScreenNode: ViewControllerTracingNode {
private var validLayout: ContainerViewLayout? private var validLayout: ContainerViewLayout?
init(text: String, textEntities: [MessageTextEntity], style: TooltipScreen.Style, icon: TooltipScreen.Icon?, customContentNode: TooltipCustomContentNode? = nil, location: TooltipScreen.Location, displayDuration: TooltipScreen.DisplayDuration, inset: CGFloat = 13.0, shouldDismissOnTouch: @escaping (CGPoint) -> TooltipScreen.DismissOnTouch, requestDismiss: @escaping () -> Void, openActiveTextItem: ((TooltipActiveTextItem, TooltipActiveTextAction) -> Void)?) { init(account: Account, text: String, textEntities: [MessageTextEntity], style: TooltipScreen.Style, icon: TooltipScreen.Icon?, customContentNode: TooltipCustomContentNode? = nil, location: TooltipScreen.Location, displayDuration: TooltipScreen.DisplayDuration, inset: CGFloat = 13.0, shouldDismissOnTouch: @escaping (CGPoint) -> TooltipScreen.DismissOnTouch, requestDismiss: @escaping () -> Void, openActiveTextItem: ((TooltipActiveTextItem, TooltipActiveTextAction) -> Void)?) {
self.tooltipStyle = style self.tooltipStyle = style
self.icon = icon self.icon = icon
self.customContentNode = customContentNode self.customContentNode = customContentNode
@ -198,16 +199,12 @@ private final class TooltipScreenNode: ViewControllerTracingNode {
case .none: case .none:
break break
case .chatListPress: case .chatListPress:
if let path = getAppBundle().path(forResource: "ChatListFoldersTooltip", ofType: "json") { self.animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "ChatListFoldersTooltip"), width: Int(70 * UIScreenScale), height: Int(70 * UIScreenScale), playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: Int(70 * UIScreenScale), height: Int(70 * UIScreenScale), playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.animatedStickerNode.automaticallyLoadFirstFrame = true self.animatedStickerNode.automaticallyLoadFirstFrame = true
}
case .info: case .info:
if let path = getAppBundle().path(forResource: "anim_infotip", ofType: "json") { self.animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "anim_infotip"), width: Int(70 * UIScreenScale), height: Int(70 * UIScreenScale), playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: Int(70 * UIScreenScale), height: Int(70 * UIScreenScale), playbackMode: .once, mode: .direct(cachePathPrefix: nil))
self.animatedStickerNode.automaticallyLoadFirstFrame = true self.animatedStickerNode.automaticallyLoadFirstFrame = true
} }
}
super.init() super.init()
@ -559,6 +556,7 @@ public final class TooltipScreen: ViewController {
case gradient(UIColor, UIColor) case gradient(UIColor, UIColor)
} }
private let account: Account
public let text: String public let text: String
public let textEntities: [MessageTextEntity] public let textEntities: [MessageTextEntity]
private let style: TooltipScreen.Style private let style: TooltipScreen.Style
@ -582,7 +580,8 @@ public final class TooltipScreen: ViewController {
private var dismissTimer: Foundation.Timer? private var dismissTimer: Foundation.Timer?
public init(text: String, textEntities: [MessageTextEntity] = [], style: TooltipScreen.Style = .default, icon: TooltipScreen.Icon?, customContentNode: TooltipCustomContentNode? = nil, location: TooltipScreen.Location, displayDuration: DisplayDuration = .default, inset: CGFloat = 13.0, shouldDismissOnTouch: @escaping (CGPoint) -> TooltipScreen.DismissOnTouch, openActiveTextItem: ((TooltipActiveTextItem, TooltipActiveTextAction) -> Void)? = nil) { public init(account: Account, text: String, textEntities: [MessageTextEntity] = [], style: TooltipScreen.Style = .default, icon: TooltipScreen.Icon?, customContentNode: TooltipCustomContentNode? = nil, location: TooltipScreen.Location, displayDuration: DisplayDuration = .default, inset: CGFloat = 13.0, shouldDismissOnTouch: @escaping (CGPoint) -> TooltipScreen.DismissOnTouch, openActiveTextItem: ((TooltipActiveTextItem, TooltipActiveTextAction) -> Void)? = nil) {
self.account = account
self.text = text self.text = text
self.textEntities = textEntities self.textEntities = textEntities
self.style = style self.style = style
@ -647,7 +646,7 @@ public final class TooltipScreen: ViewController {
} }
override public func loadDisplayNode() { override public func loadDisplayNode() {
self.displayNode = TooltipScreenNode(text: self.text, textEntities: self.textEntities, style: self.style, icon: self.icon, customContentNode: self.customContentNode, location: self.location, displayDuration: self.displayDuration, inset: self.inset, shouldDismissOnTouch: self.shouldDismissOnTouch, requestDismiss: { [weak self] in self.displayNode = TooltipScreenNode(account: self.account, text: self.text, textEntities: self.textEntities, style: self.style, icon: self.icon, customContentNode: self.customContentNode, location: self.location, displayDuration: self.displayDuration, inset: self.inset, shouldDismissOnTouch: self.shouldDismissOnTouch, requestDismiss: { [weak self] in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }

View File

@ -13,7 +13,7 @@ public enum UndoOverlayContent {
case revealedArchive(title: String, text: String, undo: Bool) case revealedArchive(title: String, text: String, undo: Bool)
case succeed(text: String) case succeed(text: String)
case info(text: String) case info(text: String)
case emoji(path: String, text: String) case emoji(name: String, text: String)
case swipeToReply(title: String, text: String) case swipeToReply(title: String, text: String)
case actionSucceeded(title: String, text: String, cancel: String) case actionSucceeded(title: String, text: String, cancel: String)
case stickersModified(title: String, text: String, undo: Bool, info: StickerPackCollectionInfo, topItem: ItemCollectionItem?, context: AccountContext) case stickersModified(title: String, text: String, undo: Bool, info: StickerPackCollectionInfo, topItem: ItemCollectionItem?, context: AccountContext)

View File

@ -303,14 +303,14 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
displayUndo = undo displayUndo = undo
self.originalRemainingSeconds = 5 self.originalRemainingSeconds = 5
case let .emoji(path, text): case let .emoji(name, text):
self.avatarNode = nil self.avatarNode = nil
self.iconNode = nil self.iconNode = nil
self.iconCheckNode = nil self.iconCheckNode = nil
self.animationNode = nil self.animationNode = nil
self.animatedStickerNode = AnimatedStickerNode() self.animatedStickerNode = AnimatedStickerNode()
self.animatedStickerNode?.visibility = true self.animatedStickerNode?.visibility = true
self.animatedStickerNode?.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 100, height: 100, playbackMode: .once, mode: .direct(cachePathPrefix: nil)) self.animatedStickerNode?.setup(source: AnimatedStickerNodeLocalFileSource(name: name), width: 100, height: 100, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white) let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white)
let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white) let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white)
@ -447,7 +447,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
} }
if dice.emoji == "🎰" { if dice.emoji == "🎰" {
let slotMachineNode = SlotMachineAnimationNode(size: CGSize(width: 42.0, height: 42.0)) let slotMachineNode = SlotMachineAnimationNode(account: context.account, size: CGSize(width: 42.0, height: 42.0))
self.slotMachineNode = slotMachineNode self.slotMachineNode = slotMachineNode
slotMachineNode.setState(.rolling) slotMachineNode.setState(.rolling)
@ -714,10 +714,9 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
let animatedStickerNode = AnimatedStickerNode() let animatedStickerNode = AnimatedStickerNode()
self.animatedStickerNode = animatedStickerNode self.animatedStickerNode = animatedStickerNode
if let path = getAppBundle().path(forResource: "anim_savemedia", ofType: "tgs") {
animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 80, height: 80, playbackMode: .once, mode: .direct(cachePathPrefix: nil)) animatedStickerNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "anim_savemedia"), width: 80, height: 80, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
animatedStickerNode.visibility = true animatedStickerNode.visibility = true
}
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white) let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white)
let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white) let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white)