mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 17:30:12 +00:00
Refactoring [skip ci]
This commit is contained in:
parent
00b6826303
commit
94380c546b
@ -13,7 +13,6 @@ swift_library(
|
|||||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||||
"//submodules/Display:Display",
|
"//submodules/Display:Display",
|
||||||
"//submodules/Postbox:Postbox",
|
|
||||||
"//submodules/TelegramCore:TelegramCore",
|
"//submodules/TelegramCore:TelegramCore",
|
||||||
"//submodules/AccountContext:AccountContext",
|
"//submodules/AccountContext:AccountContext",
|
||||||
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import UIKit
|
|||||||
import Display
|
import Display
|
||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import Postbox
|
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
import MapKit
|
import MapKit
|
||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
@ -71,7 +70,7 @@ public final class OpenInActionSheetController: ActionSheetController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var items: [ActionSheetItem] = []
|
var items: [ActionSheetItem] = []
|
||||||
items.append(OpenInActionSheetItem(postbox: context.account.postbox, context: context, strings: strings, options: availableOpenInOptions(context: context, item: item), invokeAction: invokeActionImpl))
|
items.append(OpenInActionSheetItem(context: context, strings: strings, options: availableOpenInOptions(context: context, item: item), invokeAction: invokeActionImpl))
|
||||||
|
|
||||||
if let action = additionalAction {
|
if let action = additionalAction {
|
||||||
items.append(ActionSheetButtonItem(title: action.title, action: { [weak self] in
|
items.append(ActionSheetButtonItem(title: action.title, action: { [weak self] in
|
||||||
@ -100,14 +99,12 @@ public final class OpenInActionSheetController: ActionSheetController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class OpenInActionSheetItem: ActionSheetItem {
|
private final class OpenInActionSheetItem: ActionSheetItem {
|
||||||
let postbox: Postbox
|
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
let strings: PresentationStrings
|
let strings: PresentationStrings
|
||||||
let options: [OpenInOption]
|
let options: [OpenInOption]
|
||||||
let invokeAction: (OpenInAction) -> Void
|
let invokeAction: (OpenInAction) -> Void
|
||||||
|
|
||||||
init(postbox: Postbox, context: AccountContext, strings: PresentationStrings, options: [OpenInOption], invokeAction: @escaping (OpenInAction) -> Void) {
|
init(context: AccountContext, strings: PresentationStrings, options: [OpenInOption], invokeAction: @escaping (OpenInAction) -> Void) {
|
||||||
self.postbox = postbox
|
|
||||||
self.context = context
|
self.context = context
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.options = options
|
self.options = options
|
||||||
@ -115,7 +112,7 @@ private final class OpenInActionSheetItem: ActionSheetItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func node(theme: ActionSheetControllerTheme) -> ActionSheetItemNode {
|
func node(theme: ActionSheetControllerTheme) -> ActionSheetItemNode {
|
||||||
return OpenInActionSheetItemNode(postbox: self.postbox, context: self.context, theme: theme, strings: self.strings, options: self.options, invokeAction: self.invokeAction)
|
return OpenInActionSheetItemNode(context: self.context, theme: theme, strings: self.strings, options: self.options, invokeAction: self.invokeAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateNode(_ node: ActionSheetItemNode) {
|
func updateNode(_ node: ActionSheetItemNode) {
|
||||||
@ -131,7 +128,7 @@ private final class OpenInActionSheetItemNode: ActionSheetItemNode {
|
|||||||
|
|
||||||
let openInNodes: [OpenInAppNode]
|
let openInNodes: [OpenInAppNode]
|
||||||
|
|
||||||
init(postbox: Postbox, context: AccountContext, theme: ActionSheetControllerTheme, strings: PresentationStrings, options: [OpenInOption], invokeAction: @escaping (OpenInAction) -> Void) {
|
init(context: AccountContext, theme: ActionSheetControllerTheme, strings: PresentationStrings, options: [OpenInOption], invokeAction: @escaping (OpenInAction) -> Void) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
|
|
||||||
@ -152,7 +149,7 @@ private final class OpenInActionSheetItemNode: ActionSheetItemNode {
|
|||||||
|
|
||||||
self.openInNodes = options.map { option in
|
self.openInNodes = options.map { option in
|
||||||
let node = OpenInAppNode()
|
let node = OpenInAppNode()
|
||||||
node.setup(postbox: postbox, context: context, theme: theme, option: option, invokeAction: invokeAction)
|
node.setup(context: context, theme: theme, option: option, invokeAction: invokeAction)
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +214,7 @@ private final class OpenInAppNode : ASDisplayNode {
|
|||||||
self.addSubnode(self.textNode)
|
self.addSubnode(self.textNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setup(postbox: Postbox, context: AccountContext, theme: ActionSheetControllerTheme, option: OpenInOption, invokeAction: @escaping (OpenInAction) -> Void) {
|
func setup(context: AccountContext, theme: ActionSheetControllerTheme, option: OpenInOption, invokeAction: @escaping (OpenInAction) -> Void) {
|
||||||
let textFont = Font.regular(floor(theme.baseFontSize * 11.0 / 17.0))
|
let textFont = Font.regular(floor(theme.baseFontSize * 11.0 / 17.0))
|
||||||
self.textNode.attributedText = NSAttributedString(string: option.title, font: textFont, textColor: theme.primaryTextColor, paragraphAlignment: .center)
|
self.textNode.attributedText = NSAttributedString(string: option.title, font: textFont, textColor: theme.primaryTextColor, paragraphAlignment: .center)
|
||||||
|
|
||||||
@ -229,14 +226,14 @@ private final class OpenInAppNode : ASDisplayNode {
|
|||||||
switch option.application {
|
switch option.application {
|
||||||
case .safari:
|
case .safari:
|
||||||
if let image = UIImage(bundleImageName: "Open In/Safari") {
|
if let image = UIImage(bundleImageName: "Open In/Safari") {
|
||||||
self.iconNode.setSignal(openInAppIcon(postbox: postbox, appIcon: .image(image: image)))
|
self.iconNode.setSignal(openInAppIcon(engine: context.engine, appIcon: .image(image: image)))
|
||||||
}
|
}
|
||||||
case .maps:
|
case .maps:
|
||||||
if let image = UIImage(bundleImageName: "Open In/Maps") {
|
if let image = UIImage(bundleImageName: "Open In/Maps") {
|
||||||
self.iconNode.setSignal(openInAppIcon(postbox: postbox, appIcon: .image(image: image)))
|
self.iconNode.setSignal(openInAppIcon(engine: context.engine, appIcon: .image(image: image)))
|
||||||
}
|
}
|
||||||
case let .other(_, identifier, _, store):
|
case let .other(_, identifier, _, store):
|
||||||
self.iconNode.setSignal(openInAppIcon(postbox: postbox, appIcon: .resource(resource: OpenInAppIconResource(appStoreId: identifier, store: store))))
|
self.iconNode.setSignal(openInAppIcon(engine: context.engine, appIcon: .resource(resource: OpenInAppIconResource(appStoreId: identifier, store: store))))
|
||||||
}
|
}
|
||||||
|
|
||||||
self.action = {
|
self.action = {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import Postbox
|
import Display
|
||||||
|
|
||||||
public struct OpenInAppIconResourceId {
|
public struct OpenInAppIconResourceId {
|
||||||
public let appStoreId: Int64
|
public let appStoreId: Int64
|
||||||
@ -16,7 +16,7 @@ public struct OpenInAppIconResourceId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OpenInAppIconResource: TelegramMediaResource {
|
public class OpenInAppIconResource {
|
||||||
public let appStoreId: Int64
|
public let appStoreId: Int64
|
||||||
public let store: String?
|
public let store: String?
|
||||||
|
|
||||||
@ -25,37 +25,13 @@ public class OpenInAppIconResource: TelegramMediaResource {
|
|||||||
self.store = store
|
self.store = store
|
||||||
}
|
}
|
||||||
|
|
||||||
public required init(decoder: PostboxDecoder) {
|
public var id: EngineMediaResource.Id {
|
||||||
self.appStoreId = decoder.decodeInt64ForKey("i", orElse: 0)
|
return EngineMediaResource.Id(OpenInAppIconResourceId(appStoreId: self.appStoreId).uniqueId)
|
||||||
self.store = decoder.decodeOptionalStringForKey("s")
|
|
||||||
}
|
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
|
||||||
encoder.encodeInt64(self.appStoreId, forKey: "i")
|
|
||||||
if let store = self.store {
|
|
||||||
encoder.encodeString(store, forKey: "s")
|
|
||||||
} else {
|
|
||||||
encoder.encodeNil(forKey: "s")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public var id: MediaResourceId {
|
|
||||||
return MediaResourceId(OpenInAppIconResourceId(appStoreId: self.appStoreId).uniqueId)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func isEqual(to: MediaResource) -> Bool {
|
|
||||||
if let to = to as? OpenInAppIconResource {
|
|
||||||
return self.appStoreId == to.appStoreId
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchOpenInAppIconResource(resource: OpenInAppIconResource) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
|
public func fetchOpenInAppIconResource(engine: TelegramEngine, resource: OpenInAppIconResource) -> Signal<EngineMediaResource.Fetch.Result, EngineMediaResource.Fetch.Error> {
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
subscriber.putNext(.reset)
|
|
||||||
|
|
||||||
let metaUrl: String
|
let metaUrl: String
|
||||||
if let store = resource.store {
|
if let store = resource.store {
|
||||||
metaUrl = "https://itunes.apple.com/\(store)/lookup?id=\(resource.appStoreId)"
|
metaUrl = "https://itunes.apple.com/\(store)/lookup?id=\(resource.appStoreId)"
|
||||||
@ -68,36 +44,33 @@ public func fetchOpenInAppIconResource(resource: OpenInAppIconResource) -> Signa
|
|||||||
let disposable = fetchHttpResource(url: metaUrl).start(next: { result in
|
let disposable = fetchHttpResource(url: metaUrl).start(next: { result in
|
||||||
if case let .dataPart(_, data, _, complete) = result, complete {
|
if case let .dataPart(_, data, _, complete) = result, complete {
|
||||||
guard let dict = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any] else {
|
guard let dict = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any] else {
|
||||||
subscriber.putNext(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: true))
|
subscriber.putError(.generic)
|
||||||
subscriber.putCompletion()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let results = dict["results"] as? [Any] else {
|
guard let results = dict["results"] as? [Any] else {
|
||||||
subscriber.putNext(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: true))
|
subscriber.putError(.generic)
|
||||||
subscriber.putCompletion()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let result = results.first as? [String: Any] else {
|
guard let result = results.first as? [String: Any] else {
|
||||||
subscriber.putNext(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: true))
|
subscriber.putError(.generic)
|
||||||
subscriber.putCompletion()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let artworkUrl = result["artworkUrl100"] as? String else {
|
guard let artworkUrl = result["artworkUrl100"] as? String else {
|
||||||
subscriber.putNext(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: true))
|
subscriber.putError(.generic)
|
||||||
subscriber.putCompletion()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if artworkUrl.isEmpty {
|
if artworkUrl.isEmpty {
|
||||||
subscriber.putNext(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: true))
|
subscriber.putError(.generic)
|
||||||
subscriber.putCompletion()
|
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
fetchDisposable.set(fetchHttpResource(url: artworkUrl).start(next: { next in
|
fetchDisposable.set(engine.resources.httpData(url: artworkUrl).start(next: { data in
|
||||||
subscriber.putNext(next)
|
let file = EngineTempBox.shared.tempFile(fileName: "image.jpg")
|
||||||
|
let _ = try? data.write(to: URL(fileURLWithPath: file.path))
|
||||||
|
subscriber.putNext(.moveTempFile(file: file))
|
||||||
}, completed: {
|
}, completed: {
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
}))
|
}))
|
||||||
@ -111,3 +84,93 @@ public func fetchOpenInAppIconResource(resource: OpenInAppIconResource) -> Signa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func openInAppIconData(engine: TelegramEngine, appIcon: OpenInAppIconResource) -> Signal<Data?, NoError> {
|
||||||
|
let appIconResource = engine.resources.custom(
|
||||||
|
id: appIcon.id.stringRepresentation,
|
||||||
|
fetch: EngineMediaResource.Fetch {
|
||||||
|
return fetchOpenInAppIconResource(engine: engine, resource: appIcon)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return appIconResource
|
||||||
|
|> map { data -> Data? in
|
||||||
|
if data.isComplete {
|
||||||
|
let loadedData: Data? = try? Data(contentsOf: URL(fileURLWithPath: data.path), options: [])
|
||||||
|
return loadedData
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum OpenInAppIcon {
|
||||||
|
case resource(resource: OpenInAppIconResource)
|
||||||
|
case image(image: UIImage)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func drawOpenInAppIconBorder(into c: CGContext, arguments: TransformImageArguments) {
|
||||||
|
c.setBlendMode(.normal)
|
||||||
|
c.setStrokeColor(UIColor(rgb: 0xe5e5e5).cgColor)
|
||||||
|
|
||||||
|
let lineWidth: CGFloat = arguments.drawingRect.size.width < 30.0 ? 1.0 - UIScreenPixel : 1.0
|
||||||
|
c.setLineWidth(lineWidth)
|
||||||
|
|
||||||
|
var radius: CGFloat = 0.0
|
||||||
|
if case let .Corner(cornerRadius) = arguments.corners.topLeft, cornerRadius > CGFloat.ulpOfOne {
|
||||||
|
radius = max(0, cornerRadius - 0.5)
|
||||||
|
}
|
||||||
|
|
||||||
|
let rect = arguments.drawingRect.insetBy(dx: lineWidth / 2.0, dy: lineWidth / 2.0)
|
||||||
|
c.move(to: CGPoint(x: rect.minX, y: rect.midY))
|
||||||
|
c.addArc(tangent1End: CGPoint(x: rect.minX, y: rect.minY), tangent2End: CGPoint(x: rect.midX, y: rect.minY), radius: radius)
|
||||||
|
c.addArc(tangent1End: CGPoint(x: rect.maxX, y: rect.minY), tangent2End: CGPoint(x: rect.maxX, y: rect.midY), radius: radius)
|
||||||
|
c.addArc(tangent1End: CGPoint(x: rect.maxX, y: rect.maxY), tangent2End: CGPoint(x: rect.midX, y: rect.maxY), radius: radius)
|
||||||
|
c.addArc(tangent1End: CGPoint(x: rect.minX, y: rect.maxY), tangent2End: CGPoint(x: rect.minX, y: rect.midY), radius: radius)
|
||||||
|
c.closePath()
|
||||||
|
c.strokePath()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func openInAppIcon(engine: TelegramEngine, appIcon: OpenInAppIcon) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||||
|
switch appIcon {
|
||||||
|
case let .resource(resource):
|
||||||
|
return openInAppIconData(engine: engine, appIcon: resource) |> map { data in
|
||||||
|
return { arguments in
|
||||||
|
let context = DrawingContext(size: arguments.drawingSize, clear: true)
|
||||||
|
|
||||||
|
var sourceImage: UIImage?
|
||||||
|
if let data = data, let image = UIImage(data: data) {
|
||||||
|
sourceImage = image
|
||||||
|
}
|
||||||
|
|
||||||
|
if let sourceImage = sourceImage, let cgImage = sourceImage.cgImage {
|
||||||
|
context.withFlippedContext { c in
|
||||||
|
c.draw(cgImage, in: CGRect(origin: CGPoint(), size: arguments.drawingRect.size))
|
||||||
|
drawOpenInAppIconBorder(into: c, arguments: arguments)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
context.withFlippedContext { c in
|
||||||
|
drawOpenInAppIconBorder(into: c, arguments: arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addCorners(context, arguments: arguments)
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case let .image(image):
|
||||||
|
return .single({ arguments in
|
||||||
|
let context = DrawingContext(size: arguments.drawingSize, clear: true)
|
||||||
|
|
||||||
|
context.withFlippedContext { c in
|
||||||
|
c.draw(image.cgImage!, in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: arguments.drawingSize))
|
||||||
|
drawOpenInAppIconBorder(into: c, arguments: arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
addCorners(context, arguments: arguments)
|
||||||
|
|
||||||
|
return context
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -321,7 +321,7 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres
|
|||||||
case .fetching:
|
case .fetching:
|
||||||
return nil
|
return nil
|
||||||
case let .result(info, items, _):
|
case let .result(info, items, _):
|
||||||
return InitialStickerPackData.data(StickerPackData(info: info, item: items.first as? StickerPackItem))
|
return InitialStickerPackData.data(StickerPackData(info: info, item: items.first))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -361,7 +361,7 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres
|
|||||||
case .none:
|
case .none:
|
||||||
return .single((searchText, .notFound))
|
return .single((searchText, .notFound))
|
||||||
case let .result(info, items, _):
|
case let .result(info, items, _):
|
||||||
return .single((searchText, .found(StickerPackData(info: info, item: items.first as? StickerPackItem))))
|
return .single((searchText, .found(StickerPackData(info: info, item: items.first))))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2792,112 +2792,6 @@ public func securePhotoInternal(account: Account, resource: TelegramMediaResourc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func openInAppIconData(postbox: Postbox, appIcon: MediaResource) -> Signal<Data?, NoError> {
|
|
||||||
let appIconResource = postbox.mediaBox.resourceData(appIcon)
|
|
||||||
|
|
||||||
let signal = appIconResource |> take(1) |> mapToSignal { maybeData -> Signal<Data?, NoError> in
|
|
||||||
if maybeData.complete {
|
|
||||||
let loadedData: Data? = try? Data(contentsOf: URL(fileURLWithPath: maybeData.path), options: [])
|
|
||||||
return .single((loadedData))
|
|
||||||
} else {
|
|
||||||
let fetchedAppIcon = postbox.mediaBox.fetchedResource(appIcon, parameters: nil)
|
|
||||||
|
|
||||||
let appIcon = Signal<Data?, NoError> { subscriber in
|
|
||||||
let fetchedDisposable = fetchedAppIcon.start()
|
|
||||||
let appIconDisposable = appIconResource.start(next: { next in
|
|
||||||
subscriber.putNext(next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []))
|
|
||||||
}, error: subscriber.putError, completed: subscriber.putCompletion)
|
|
||||||
|
|
||||||
return ActionDisposable {
|
|
||||||
fetchedDisposable.dispose()
|
|
||||||
appIconDisposable.dispose()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return appIcon
|
|
||||||
}
|
|
||||||
} |> distinctUntilChanged(isEqual: { lhs, rhs in
|
|
||||||
if lhs == nil && rhs == nil {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return signal
|
|
||||||
}
|
|
||||||
|
|
||||||
private func drawOpenInAppIconBorder(into c: CGContext, arguments: TransformImageArguments) {
|
|
||||||
c.setBlendMode(.normal)
|
|
||||||
c.setStrokeColor(UIColor(rgb: 0xe5e5e5).cgColor)
|
|
||||||
|
|
||||||
let lineWidth: CGFloat = arguments.drawingRect.size.width < 30.0 ? 1.0 - UIScreenPixel : 1.0
|
|
||||||
c.setLineWidth(lineWidth)
|
|
||||||
|
|
||||||
var radius: CGFloat = 0.0
|
|
||||||
if case let .Corner(cornerRadius) = arguments.corners.topLeft, cornerRadius > CGFloat.ulpOfOne {
|
|
||||||
radius = max(0, cornerRadius - 0.5)
|
|
||||||
}
|
|
||||||
|
|
||||||
let rect = arguments.drawingRect.insetBy(dx: lineWidth / 2.0, dy: lineWidth / 2.0)
|
|
||||||
c.move(to: CGPoint(x: rect.minX, y: rect.midY))
|
|
||||||
c.addArc(tangent1End: CGPoint(x: rect.minX, y: rect.minY), tangent2End: CGPoint(x: rect.midX, y: rect.minY), radius: radius)
|
|
||||||
c.addArc(tangent1End: CGPoint(x: rect.maxX, y: rect.minY), tangent2End: CGPoint(x: rect.maxX, y: rect.midY), radius: radius)
|
|
||||||
c.addArc(tangent1End: CGPoint(x: rect.maxX, y: rect.maxY), tangent2End: CGPoint(x: rect.midX, y: rect.maxY), radius: radius)
|
|
||||||
c.addArc(tangent1End: CGPoint(x: rect.minX, y: rect.maxY), tangent2End: CGPoint(x: rect.minX, y: rect.midY), radius: radius)
|
|
||||||
c.closePath()
|
|
||||||
c.strokePath()
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum OpenInAppIcon {
|
|
||||||
case resource(resource: TelegramMediaResource)
|
|
||||||
case image(image: UIImage)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func openInAppIcon(postbox: Postbox, appIcon: OpenInAppIcon) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
|
||||||
switch appIcon {
|
|
||||||
case let .resource(resource):
|
|
||||||
return openInAppIconData(postbox: postbox, appIcon: resource) |> map { data in
|
|
||||||
return { arguments in
|
|
||||||
let context = DrawingContext(size: arguments.drawingSize, clear: true)
|
|
||||||
|
|
||||||
var sourceImage: UIImage?
|
|
||||||
if let data = data, let image = UIImage(data: data) {
|
|
||||||
sourceImage = image
|
|
||||||
}
|
|
||||||
|
|
||||||
if let sourceImage = sourceImage, let cgImage = sourceImage.cgImage {
|
|
||||||
context.withFlippedContext { c in
|
|
||||||
c.draw(cgImage, in: CGRect(origin: CGPoint(), size: arguments.drawingRect.size))
|
|
||||||
drawOpenInAppIconBorder(into: c, arguments: arguments)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
context.withFlippedContext { c in
|
|
||||||
drawOpenInAppIconBorder(into: c, arguments: arguments)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addCorners(context, arguments: arguments)
|
|
||||||
|
|
||||||
return context
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case let .image(image):
|
|
||||||
return .single({ arguments in
|
|
||||||
let context = DrawingContext(size: arguments.drawingSize, clear: true)
|
|
||||||
|
|
||||||
context.withFlippedContext { c in
|
|
||||||
c.draw(image.cgImage!, in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: arguments.drawingSize))
|
|
||||||
drawOpenInAppIconBorder(into: c, arguments: arguments)
|
|
||||||
}
|
|
||||||
|
|
||||||
addCorners(context, arguments: arguments)
|
|
||||||
|
|
||||||
return context
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func callDefaultBackground() -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
public func callDefaultBackground() -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||||
return .single({ arguments in
|
return .single({ arguments in
|
||||||
let context = DrawingContext(size: arguments.drawingSize, clear: true)
|
let context = DrawingContext(size: arguments.drawingSize, clear: true)
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import PhotoResources
|
|||||||
import OpenInExternalAppUI
|
import OpenInExternalAppUI
|
||||||
|
|
||||||
class WebBrowserItem: ListViewItem, ItemListItem {
|
class WebBrowserItem: ListViewItem, ItemListItem {
|
||||||
let account: Account
|
let engine: TelegramEngine
|
||||||
let presentationData: ItemListPresentationData
|
let presentationData: ItemListPresentationData
|
||||||
let title: String
|
let title: String
|
||||||
let application: OpenInApplication
|
let application: OpenInApplication
|
||||||
@ -18,8 +18,8 @@ class WebBrowserItem: ListViewItem, ItemListItem {
|
|||||||
public let sectionId: ItemListSectionId
|
public let sectionId: ItemListSectionId
|
||||||
let action: () -> Void
|
let action: () -> Void
|
||||||
|
|
||||||
public init(account: Account, presentationData: ItemListPresentationData, title: String, application: OpenInApplication, checked: Bool, sectionId: ItemListSectionId, action: @escaping () -> Void) {
|
public init(engine: TelegramEngine, presentationData: ItemListPresentationData, title: String, application: OpenInApplication, checked: Bool, sectionId: ItemListSectionId, action: @escaping () -> Void) {
|
||||||
self.account = account
|
self.engine = engine
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
self.title = title
|
self.title = title
|
||||||
self.application = application
|
self.application = application
|
||||||
@ -144,14 +144,14 @@ private final class WebBrowserItemNode: ListViewItemNode {
|
|||||||
switch item.application {
|
switch item.application {
|
||||||
case .safari:
|
case .safari:
|
||||||
if let image = UIImage(bundleImageName: "Open In/Safari") {
|
if let image = UIImage(bundleImageName: "Open In/Safari") {
|
||||||
updatedIconSignal = openInAppIcon(postbox: item.account.postbox, appIcon: .image(image: image))
|
updatedIconSignal = openInAppIcon(engine: item.engine, appIcon: .image(image: image))
|
||||||
}
|
}
|
||||||
case .maps:
|
case .maps:
|
||||||
if let image = UIImage(bundleImageName: "Open In/Maps") {
|
if let image = UIImage(bundleImageName: "Open In/Maps") {
|
||||||
updatedIconSignal = openInAppIcon(postbox: item.account.postbox, appIcon: .image(image: image))
|
updatedIconSignal = openInAppIcon(engine: item.engine, appIcon: .image(image: image))
|
||||||
}
|
}
|
||||||
case let .other(_, identifier, _, store):
|
case let .other(_, identifier, _, store):
|
||||||
updatedIconSignal = openInAppIcon(postbox: item.account.postbox, appIcon: .resource(resource: OpenInAppIconResource(appStoreId: identifier, store: store)))
|
updatedIconSignal = openInAppIcon(engine: item.engine, appIcon: .resource(resource: OpenInAppIconResource(appStoreId: identifier, store: store)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,7 @@ private enum WebBrowserSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
case let .browserHeader(_, text):
|
case let .browserHeader(_, text):
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||||
case let .browser(_, title, application, identifier, selected, _):
|
case let .browser(_, title, application, identifier, selected, _):
|
||||||
return WebBrowserItem(account: arguments.context.account, presentationData: presentationData, title: title, application: application, checked: selected, sectionId: self.section) {
|
return WebBrowserItem(engine: arguments.context.engine, presentationData: presentationData, title: title, application: application, checked: selected, sectionId: self.section) {
|
||||||
arguments.updateDefaultBrowser(identifier)
|
arguments.updateDefaultBrowser(identifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -276,7 +276,7 @@ public func archivedStickerPacksController(context: AccountContext, mode: Archiv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
let _ = (context.engine.stickers.loadedStickerPack(reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
|
let _ = (context.engine.stickers.loadedStickerPack(reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
|
||||||
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), NoError> in
|
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [StickerPackItem]), NoError> in
|
||||||
switch result {
|
switch result {
|
||||||
case let .result(info, items, installed):
|
case let .result(info, items, installed):
|
||||||
if installed {
|
if installed {
|
||||||
@ -284,7 +284,7 @@ public func archivedStickerPacksController(context: AccountContext, mode: Archiv
|
|||||||
} else {
|
} else {
|
||||||
return context.engine.stickers.addStickerPackInteractively(info: info, items: items)
|
return context.engine.stickers.addStickerPackInteractively(info: info, items: items)
|
||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
|> mapToSignal { _ -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), NoError> in
|
|> mapToSignal { _ -> Signal<(StickerPackCollectionInfo, [StickerPackItem]), NoError> in
|
||||||
}
|
}
|
||||||
|> then(.single((info, items)))
|
|> then(.single((info, items)))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,9 +67,9 @@ public final class StickerPackPreviewController: ViewController, StandalonePrese
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private let actionPerformed: ((StickerPackCollectionInfo, [ItemCollectionItem], StickerPackScreenPerformedAction) -> Void)?
|
private let actionPerformed: ((StickerPackCollectionInfo, [StickerPackItem], StickerPackScreenPerformedAction) -> Void)?
|
||||||
|
|
||||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, stickerPack: StickerPackReference, mode: StickerPackPreviewControllerMode = .default, parentNavigationController: NavigationController?, actionPerformed: ((StickerPackCollectionInfo, [ItemCollectionItem], StickerPackScreenPerformedAction) -> Void)? = nil) {
|
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, stickerPack: StickerPackReference, mode: StickerPackPreviewControllerMode = .default, parentNavigationController: NavigationController?, actionPerformed: ((StickerPackCollectionInfo, [StickerPackItem], StickerPackScreenPerformedAction) -> Void)? = nil) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.parentNavigationController = parentNavigationController
|
self.parentNavigationController = parentNavigationController
|
||||||
@ -207,7 +207,7 @@ public final class StickerPackPreviewController: ViewController, StandalonePrese
|
|||||||
|
|
||||||
let topItems = items.prefix(16)
|
let topItems = items.prefix(16)
|
||||||
for item in topItems {
|
for item in topItems {
|
||||||
if let item = item as? StickerPackItem, item.file.isAnimatedSticker {
|
if item.file.isAnimatedSticker {
|
||||||
let signal = Signal<Bool, NoError> { subscriber in
|
let signal = Signal<Bool, NoError> { subscriber in
|
||||||
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: FileMediaReference.standalone(media: item.file).resourceReference(item.file.resource)).start()
|
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: FileMediaReference.standalone(media: item.file).resourceReference(item.file.resource)).start()
|
||||||
let data = account.postbox.mediaBox.resourceData(item.file.resource).start()
|
let data = account.postbox.mediaBox.resourceData(item.file.resource).start()
|
||||||
|
|||||||
@ -74,7 +74,7 @@ final class StickerPackPreviewControllerNode: ViewControllerTracingNode, UIScrol
|
|||||||
var dismiss: (() -> Void)?
|
var dismiss: (() -> Void)?
|
||||||
var cancel: (() -> Void)?
|
var cancel: (() -> Void)?
|
||||||
var sendSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)?
|
var sendSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)?
|
||||||
private let actionPerformed: ((StickerPackCollectionInfo, [ItemCollectionItem], StickerPackScreenPerformedAction) -> Void)?
|
private let actionPerformed: ((StickerPackCollectionInfo, [StickerPackItem], StickerPackScreenPerformedAction) -> Void)?
|
||||||
|
|
||||||
let ready = Promise<Bool>()
|
let ready = Promise<Bool>()
|
||||||
private var didSetReady = false
|
private var didSetReady = false
|
||||||
@ -90,7 +90,7 @@ final class StickerPackPreviewControllerNode: ViewControllerTracingNode, UIScrol
|
|||||||
|
|
||||||
private weak var peekController: PeekController?
|
private weak var peekController: PeekController?
|
||||||
|
|
||||||
init(context: AccountContext, presentationData: PresentationData, openShare: (() -> Void)?, openMention: @escaping (String) -> Void, actionPerformed: ((StickerPackCollectionInfo, [ItemCollectionItem], StickerPackScreenPerformedAction) -> Void)?) {
|
init(context: AccountContext, presentationData: PresentationData, openShare: (() -> Void)?, openMention: @escaping (String) -> Void, actionPerformed: ((StickerPackCollectionInfo, [StickerPackItem], StickerPackScreenPerformedAction) -> Void)?) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.openShare = openShare
|
self.openShare = openShare
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
@ -385,10 +385,8 @@ final class StickerPackPreviewControllerNode: ViewControllerTracingNode, UIScrol
|
|||||||
|
|
||||||
var updatedItems: [StickerPackPreviewGridEntry] = []
|
var updatedItems: [StickerPackPreviewGridEntry] = []
|
||||||
for item in items {
|
for item in items {
|
||||||
if let item = item as? StickerPackItem {
|
|
||||||
updatedItems.append(StickerPackPreviewGridEntry(index: updatedItems.count, stickerItem: item))
|
updatedItems.append(StickerPackPreviewGridEntry(index: updatedItems.count, stickerItem: item))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if self.currentItems.isEmpty && !updatedItems.isEmpty {
|
if self.currentItems.isEmpty && !updatedItems.isEmpty {
|
||||||
let entities = generateTextEntities(info.title, enabledTypes: [.mention])
|
let entities = generateTextEntities(info.title, enabledTypes: [.mention])
|
||||||
|
|||||||
@ -81,7 +81,7 @@ private final class StickerPackContainer: ASDisplayNode {
|
|||||||
private var enqueuedTransactions: [StickerPackPreviewGridTransaction] = []
|
private var enqueuedTransactions: [StickerPackPreviewGridTransaction] = []
|
||||||
|
|
||||||
private var itemsDisposable: Disposable?
|
private var itemsDisposable: Disposable?
|
||||||
private(set) var currentStickerPack: (StickerPackCollectionInfo, [ItemCollectionItem], Bool)?
|
private(set) var currentStickerPack: (StickerPackCollectionInfo, [StickerPackItem], Bool)?
|
||||||
private var didReceiveStickerPackResult = false
|
private var didReceiveStickerPackResult = false
|
||||||
|
|
||||||
private let isReadyValue = Promise<Bool>()
|
private let isReadyValue = Promise<Bool>()
|
||||||
@ -455,9 +455,6 @@ private final class StickerPackContainer: ASDisplayNode {
|
|||||||
updateLayout = true
|
updateLayout = true
|
||||||
|
|
||||||
for item in items {
|
for item in items {
|
||||||
guard let item = item as? StickerPackItem else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var stableId: Int?
|
var stableId: Int?
|
||||||
inner: for entry in self.currentEntries {
|
inner: for entry in self.currentEntries {
|
||||||
if let stickerItem = entry.stickerItem, stickerItem.file.fileId == item.file.fileId {
|
if let stickerItem = entry.stickerItem, stickerItem.file.fileId == item.file.fileId {
|
||||||
@ -1065,7 +1062,7 @@ public enum StickerPackScreenPerformedAction {
|
|||||||
case remove(positionInList: Int)
|
case remove(positionInList: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func StickerPackScreen(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, mode: StickerPackPreviewControllerMode = .default, mainStickerPack: StickerPackReference, stickerPacks: [StickerPackReference], parentNavigationController: NavigationController? = nil, sendSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)? = nil, actionPerformed: ((StickerPackCollectionInfo, [ItemCollectionItem], StickerPackScreenPerformedAction) -> Void)? = nil, dismissed: (() -> Void)? = nil) -> ViewController {
|
public func StickerPackScreen(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, mode: StickerPackPreviewControllerMode = .default, mainStickerPack: StickerPackReference, stickerPacks: [StickerPackReference], parentNavigationController: NavigationController? = nil, sendSticker: ((FileMediaReference, ASDisplayNode, CGRect) -> Bool)? = nil, actionPerformed: ((StickerPackCollectionInfo, [StickerPackItem], StickerPackScreenPerformedAction) -> Void)? = nil, dismissed: (() -> Void)? = nil) -> ViewController {
|
||||||
//return StickerPackScreenImpl(context: context, stickerPacks: stickerPacks, selectedStickerPackIndex: stickerPacks.firstIndex(of: mainStickerPack) ?? 0, parentNavigationController: parentNavigationController, sendSticker: sendSticker)
|
//return StickerPackScreenImpl(context: context, stickerPacks: stickerPacks, selectedStickerPackIndex: stickerPacks.firstIndex(of: mainStickerPack) ?? 0, parentNavigationController: parentNavigationController, sendSticker: sendSticker)
|
||||||
|
|
||||||
let controller = StickerPackPreviewController(context: context, updatedPresentationData: updatedPresentationData, stickerPack: mainStickerPack, mode: mode, parentNavigationController: parentNavigationController, actionPerformed: actionPerformed)
|
let controller = StickerPackPreviewController(context: context, updatedPresentationData: updatedPresentationData, stickerPack: mainStickerPack, mode: mode, parentNavigationController: parentNavigationController, actionPerformed: actionPerformed)
|
||||||
|
|||||||
@ -1248,7 +1248,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
} else {
|
} else {
|
||||||
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
|
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
|
||||||
}
|
}
|
||||||
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: participant.peer, text: text), action: { _ in return false })
|
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: EnginePeer(participant.peer), text: text), action: { _ in return false })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let groupPeer = groupPeer as? TelegramChannel, let listenerLink = inviteLinks?.listenerLink, !groupPeer.hasPermission(.inviteMembers) {
|
if let groupPeer = groupPeer as? TelegramChannel, let listenerLink = inviteLinks?.listenerLink, !groupPeer.hasPermission(.inviteMembers) {
|
||||||
@ -1354,7 +1354,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
} else {
|
} else {
|
||||||
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
|
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
|
||||||
}
|
}
|
||||||
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: text), action: { _ in return false })
|
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: EnginePeer(peer), text: text), action: { _ in return false })
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
} else if let groupPeer = groupPeer as? TelegramGroup {
|
} else if let groupPeer = groupPeer as? TelegramGroup {
|
||||||
@ -1422,7 +1422,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
} else {
|
} else {
|
||||||
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
|
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
|
||||||
}
|
}
|
||||||
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: text), action: { _ in return false })
|
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: EnginePeer(peer), text: text), action: { _ in return false })
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -2236,7 +2236,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
let text = strongSelf.presentationData.strings.VoiceChat_PeerJoinedText(EnginePeer(event.peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
|
let text = strongSelf.presentationData.strings.VoiceChat_PeerJoinedText(EnginePeer(event.peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
|
||||||
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: event.peer, text: text), action: { _ in return false })
|
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: EnginePeer(event.peer), text: text), action: { _ in return false })
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -2251,7 +2251,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
} else {
|
} else {
|
||||||
text = strongSelf.presentationData.strings.VoiceChat_DisplayAsSuccess(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
|
text = strongSelf.presentationData.strings.VoiceChat_DisplayAsSuccess(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
|
||||||
}
|
}
|
||||||
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: text), action: { _ in return false })
|
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: EnginePeer(peer), text: text), action: { _ in return false })
|
||||||
}))
|
}))
|
||||||
|
|
||||||
self.stateVersionDisposable.set((self.call.stateVersion
|
self.stateVersionDisposable.set((self.call.stateVersion
|
||||||
|
|||||||
@ -9,14 +9,14 @@ private let collectionSpec = ItemCacheCollectionSpec(lowWaterItemCount: 100, hig
|
|||||||
public enum CachedStickerPackResult {
|
public enum CachedStickerPackResult {
|
||||||
case none
|
case none
|
||||||
case fetching
|
case fetching
|
||||||
case result(StickerPackCollectionInfo, [ItemCollectionItem], Bool)
|
case result(StickerPackCollectionInfo, [StickerPackItem], Bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cacheStickerPack(transaction: Transaction, info: StickerPackCollectionInfo, items: [ItemCollectionItem], reference: StickerPackReference? = nil) {
|
func cacheStickerPack(transaction: Transaction, info: StickerPackCollectionInfo, items: [StickerPackItem], reference: StickerPackReference? = nil) {
|
||||||
if let entry = CodableEntry(CachedStickerPack(info: info, items: items.map { $0 as! StickerPackItem }, hash: info.hash)) {
|
if let entry = CodableEntry(CachedStickerPack(info: info, items: items, hash: info.hash)) {
|
||||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(info.id)), entry: entry, collectionSpec: collectionSpec)
|
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(info.id)), entry: entry, collectionSpec: collectionSpec)
|
||||||
}
|
}
|
||||||
if let entry = CodableEntry(CachedStickerPack(info: info, items: items.map { $0 as! StickerPackItem }, hash: info.hash)) {
|
if let entry = CodableEntry(CachedStickerPack(info: info, items: items, hash: info.hash)) {
|
||||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(shortName: info.shortName.lowercased())), entry: entry, collectionSpec: collectionSpec)
|
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(shortName: info.shortName.lowercased())), entry: entry, collectionSpec: collectionSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ func cacheStickerPack(transaction: Transaction, info: StickerPackCollectionInfo,
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if let namespace = namespace, let id = id {
|
if let namespace = namespace, let id = id {
|
||||||
if let entry = CodableEntry(CachedStickerPack(info: info, items: items.map { $0 as! StickerPackItem }, hash: info.hash)) {
|
if let entry = CodableEntry(CachedStickerPack(info: info, items: items, hash: info.hash)) {
|
||||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))), entry: entry, collectionSpec: collectionSpec)
|
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))), entry: entry, collectionSpec: collectionSpec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ func _internal_cachedStickerPack(postbox: Postbox, network: Network, reference:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cachedStickerPack(transaction: Transaction, reference: StickerPackReference) -> (StickerPackCollectionInfo, [ItemCollectionItem], Bool)? {
|
func cachedStickerPack(transaction: Transaction, reference: StickerPackReference) -> (StickerPackCollectionInfo, [StickerPackItem], Bool)? {
|
||||||
let namespaces: [Int32] = [Namespaces.ItemCollection.CloudStickerPacks, Namespaces.ItemCollection.CloudMaskPacks]
|
let namespaces: [Int32] = [Namespaces.ItemCollection.CloudStickerPacks, Namespaces.ItemCollection.CloudMaskPacks]
|
||||||
switch reference {
|
switch reference {
|
||||||
case let .id(id, _):
|
case let .id(id, _):
|
||||||
@ -164,7 +164,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference
|
|||||||
if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo {
|
if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo {
|
||||||
let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id))
|
let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id))
|
||||||
if !items.isEmpty {
|
if !items.isEmpty {
|
||||||
return (currentInfo, items, true)
|
return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
|
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
|
||||||
@ -178,7 +178,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference
|
|||||||
if info.shortName == shortName {
|
if info.shortName == shortName {
|
||||||
let items = transaction.getItemCollectionItems(collectionId: info.id)
|
let items = transaction.getItemCollectionItems(collectionId: info.id)
|
||||||
if !items.isEmpty {
|
if !items.isEmpty {
|
||||||
return (info, items, true)
|
return (info, items.compactMap { $0 as? StickerPackItem }, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference
|
|||||||
if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo {
|
if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo {
|
||||||
let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id))
|
let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id))
|
||||||
if !items.isEmpty {
|
if !items.isEmpty {
|
||||||
return (currentInfo, items, true)
|
return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
|
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
|
||||||
@ -205,7 +205,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference
|
|||||||
if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo {
|
if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo {
|
||||||
let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id))
|
let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id))
|
||||||
if !items.isEmpty {
|
if !items.isEmpty {
|
||||||
return (currentInfo, items, true)
|
return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
|
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
|
||||||
@ -217,7 +217,7 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference
|
|||||||
if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo {
|
if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo {
|
||||||
let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id))
|
let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id))
|
||||||
if !items.isEmpty {
|
if !items.isEmpty {
|
||||||
return (currentInfo, items, true)
|
return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
|
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
|
||||||
|
|||||||
@ -91,7 +91,7 @@ public struct ImportSticker {
|
|||||||
|
|
||||||
public enum CreateStickerSetStatus {
|
public enum CreateStickerSetStatus {
|
||||||
case progress(Float, Int32, Int32)
|
case progress(Float, Int32, Int32)
|
||||||
case complete(StickerPackCollectionInfo, [ItemCollectionItem])
|
case complete(StickerPackCollectionInfo, [StickerPackItem])
|
||||||
}
|
}
|
||||||
|
|
||||||
func _internal_createStickerSet(account: Account, title: String, shortName: String, stickers: [ImportSticker], thumbnail: ImportSticker?, isAnimated: Bool, software: String?) -> Signal<CreateStickerSetStatus, CreateStickerSetError> {
|
func _internal_createStickerSet(account: Account, title: String, shortName: String, stickers: [ImportSticker], thumbnail: ImportSticker?, isAnimated: Bool, software: String?) -> Signal<CreateStickerSetStatus, CreateStickerSetError> {
|
||||||
@ -150,7 +150,7 @@ func _internal_createStickerSet(account: Account, title: String, shortName: Stri
|
|||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<CreateStickerSetStatus, CreateStickerSetError> in
|
|> mapToSignal { result -> Signal<CreateStickerSetStatus, CreateStickerSetError> in
|
||||||
let info: StickerPackCollectionInfo
|
let info: StickerPackCollectionInfo
|
||||||
var items: [ItemCollectionItem] = []
|
var items: [StickerPackItem] = []
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case let .stickerSet(set, packs, documents):
|
case let .stickerSet(set, packs, documents):
|
||||||
|
|||||||
@ -28,22 +28,22 @@ extension StickerPackReference {
|
|||||||
public enum LoadedStickerPack {
|
public enum LoadedStickerPack {
|
||||||
case fetching
|
case fetching
|
||||||
case none
|
case none
|
||||||
case result(info: StickerPackCollectionInfo, items: [ItemCollectionItem], installed: Bool)
|
case result(info: StickerPackCollectionInfo, items: [StickerPackItem], installed: Bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedRemoteStickerPack(postbox: Postbox, network: Network, reference: StickerPackReference) -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem])?, NoError> {
|
func updatedRemoteStickerPack(postbox: Postbox, network: Network, reference: StickerPackReference) -> Signal<(StickerPackCollectionInfo, [StickerPackItem])?, NoError> {
|
||||||
return network.request(Api.functions.messages.getStickerSet(stickerset: reference.apiInputStickerSet))
|
return network.request(Api.functions.messages.getStickerSet(stickerset: reference.apiInputStickerSet))
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { _ -> Signal<Api.messages.StickerSet?, NoError> in
|
|> `catch` { _ -> Signal<Api.messages.StickerSet?, NoError> in
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem])?, NoError> in
|
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [StickerPackItem])?, NoError> in
|
||||||
guard let result = result else {
|
guard let result = result else {
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
let info: StickerPackCollectionInfo
|
let info: StickerPackCollectionInfo
|
||||||
var items: [ItemCollectionItem] = []
|
var items: [StickerPackItem] = []
|
||||||
switch result {
|
switch result {
|
||||||
case let .stickerSet(set, packs, documents):
|
case let .stickerSet(set, packs, documents):
|
||||||
let namespace: ItemCollectionId.Namespace
|
let namespace: ItemCollectionId.Namespace
|
||||||
@ -85,7 +85,7 @@ func updatedRemoteStickerPack(postbox: Postbox, network: Network, reference: Sti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return postbox.transaction { transaction -> (StickerPackCollectionInfo, [ItemCollectionItem])? in
|
return postbox.transaction { transaction -> (StickerPackCollectionInfo, [StickerPackItem])? in
|
||||||
if transaction.getItemCollectionInfo(collectionId: info.id) != nil {
|
if transaction.getItemCollectionInfo(collectionId: info.id) != nil {
|
||||||
transaction.replaceItemCollectionItems(collectionId: info.id, items: items)
|
transaction.replaceItemCollectionItems(collectionId: info.id, items: items)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13383,7 +13383,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
||||||
switch animatedEmoji {
|
switch animatedEmoji {
|
||||||
case let .result(_, items, _):
|
case let .result(_, items, _):
|
||||||
for case let item as StickerPackItem in items {
|
for item in items {
|
||||||
if let emoji = item.getStringRepresentationsOfIndexKeys().first {
|
if let emoji = item.getStringRepresentationsOfIndexKeys().first {
|
||||||
animatedEmojiStickers[emoji.basicEmoji.0] = [item]
|
animatedEmojiStickers[emoji.basicEmoji.0] = [item]
|
||||||
let strippedEmoji = emoji.basicEmoji.0.strippedEmoji
|
let strippedEmoji = emoji.basicEmoji.0.strippedEmoji
|
||||||
|
|||||||
@ -769,7 +769,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
||||||
switch animatedEmoji {
|
switch animatedEmoji {
|
||||||
case let .result(_, items, _):
|
case let .result(_, items, _):
|
||||||
for case let item as StickerPackItem in items {
|
for item in items {
|
||||||
if let emoji = item.getStringRepresentationsOfIndexKeys().first {
|
if let emoji = item.getStringRepresentationsOfIndexKeys().first {
|
||||||
animatedEmojiStickers[emoji.basicEmoji.0] = [item]
|
animatedEmojiStickers[emoji.basicEmoji.0] = [item]
|
||||||
let strippedEmoji = emoji.basicEmoji.0.strippedEmoji
|
let strippedEmoji = emoji.basicEmoji.0.strippedEmoji
|
||||||
@ -790,7 +790,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
var animatedEmojiStickers: [String: [Int: StickerPackItem]] = [:]
|
var animatedEmojiStickers: [String: [Int: StickerPackItem]] = [:]
|
||||||
switch animatedEmoji {
|
switch animatedEmoji {
|
||||||
case let .result(_, items, _):
|
case let .result(_, items, _):
|
||||||
for case let item as StickerPackItem in items {
|
for item in items {
|
||||||
let indexKeys = item.getStringRepresentationsOfIndexKeys()
|
let indexKeys = item.getStringRepresentationsOfIndexKeys()
|
||||||
if indexKeys.count > 1, let first = indexKeys.first, let last = indexKeys.last {
|
if indexKeys.count > 1, let first = indexKeys.first, let last = indexKeys.last {
|
||||||
let emoji: String?
|
let emoji: String?
|
||||||
|
|||||||
@ -1091,7 +1091,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
|||||||
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
||||||
switch animatedEmoji {
|
switch animatedEmoji {
|
||||||
case let .result(_, items, _):
|
case let .result(_, items, _):
|
||||||
for case let item as StickerPackItem in items {
|
for item in items {
|
||||||
if let emoji = item.getStringRepresentationsOfIndexKeys().first {
|
if let emoji = item.getStringRepresentationsOfIndexKeys().first {
|
||||||
animatedEmojiStickers[emoji.basicEmoji.0] = [item]
|
animatedEmojiStickers[emoji.basicEmoji.0] = [item]
|
||||||
let strippedEmoji = emoji.basicEmoji.0.strippedEmoji
|
let strippedEmoji = emoji.basicEmoji.0.strippedEmoji
|
||||||
|
|||||||
@ -246,7 +246,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
|||||||
if let strongSelf = self, let info = info as? StickerPackCollectionInfo {
|
if let strongSelf = self, let info = info as? StickerPackCollectionInfo {
|
||||||
let context = strongSelf.context
|
let context = strongSelf.context
|
||||||
var installSignal = context.engine.stickers.loadedStickerPack(reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
|
var installSignal = context.engine.stickers.loadedStickerPack(reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
|
||||||
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), NoError> in
|
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [StickerPackItem]), NoError> in
|
||||||
switch result {
|
switch result {
|
||||||
case let .result(info, items, installed):
|
case let .result(info, items, installed):
|
||||||
if installed {
|
if installed {
|
||||||
@ -259,7 +259,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
|||||||
context.engine.stickers.addStickerPackInteractively(info: info, items: items)
|
context.engine.stickers.addStickerPackInteractively(info: info, items: items)
|
||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
)
|
)
|
||||||
|> mapToSignal { _ -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), NoError> in
|
|> mapToSignal { _ -> Signal<(StickerPackCollectionInfo, [StickerPackItem]), NoError> in
|
||||||
}
|
}
|
||||||
|> then(.single((info, items)))
|
|> then(.single((info, items)))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -276,7 +276,8 @@ func fetchEmojiSpriteResource(account: Account, resource: EmojiSpriteResource) -
|
|||||||
|> mapToSignal { result -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> in
|
|> mapToSignal { result -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> in
|
||||||
switch result {
|
switch result {
|
||||||
case let .result(_, items, _):
|
case let .result(_, items, _):
|
||||||
if let sticker = items[Int(resource.stickerId)] as? StickerPackItem {
|
let sticker = items[Int(resource.stickerId)]
|
||||||
|
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
guard let fetchResource = account.postbox.mediaBox.fetchResource else {
|
guard let fetchResource = account.postbox.mediaBox.fetchResource else {
|
||||||
return EmptyDisposable
|
return EmptyDisposable
|
||||||
@ -350,9 +351,6 @@ func fetchEmojiSpriteResource(account: Account, resource: EmojiSpriteResource) -
|
|||||||
disposable.dispose()
|
disposable.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return .complete()
|
return .complete()
|
||||||
|
|||||||
@ -141,7 +141,7 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
|||||||
switch stickerPack {
|
switch stickerPack {
|
||||||
case let .result(_, items, _):
|
case let .result(_, items, _):
|
||||||
var emojiStickers: [TelegramMediaFile] = []
|
var emojiStickers: [TelegramMediaFile] = []
|
||||||
for case let item as StickerPackItem in items {
|
for item in items {
|
||||||
emojiStickers.append(item.file)
|
emojiStickers.append(item.file)
|
||||||
}
|
}
|
||||||
return .single(emojiStickers)
|
return .single(emojiStickers)
|
||||||
|
|||||||
@ -65,7 +65,7 @@ private final class PrefetchManagerInnerImpl {
|
|||||||
switch stickerPack {
|
switch stickerPack {
|
||||||
case let .result(_, items, _):
|
case let .result(_, items, _):
|
||||||
var animatedEmojiStickers: [String: StickerPackItem] = [:]
|
var animatedEmojiStickers: [String: StickerPackItem] = [:]
|
||||||
for case let item as StickerPackItem in items {
|
for item in items {
|
||||||
if let emoji = item.getStringRepresentationsOfIndexKeys().first {
|
if let emoji = item.getStringRepresentationsOfIndexKeys().first {
|
||||||
animatedEmojiStickers[emoji.basicEmoji.0] = item
|
animatedEmojiStickers[emoji.basicEmoji.0] = item
|
||||||
}
|
}
|
||||||
|
|||||||
@ -240,7 +240,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
|
|||||||
let context = strongSelf.context
|
let context = strongSelf.context
|
||||||
if install {
|
if install {
|
||||||
var installSignal = strongSelf.context.engine.stickers.loadedStickerPack(reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
|
var installSignal = strongSelf.context.engine.stickers.loadedStickerPack(reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
|
||||||
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), NoError> in
|
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [StickerPackItem]), NoError> in
|
||||||
switch result {
|
switch result {
|
||||||
case let .result(info, items, installed):
|
case let .result(info, items, installed):
|
||||||
if installed {
|
if installed {
|
||||||
@ -253,7 +253,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
|
|||||||
context.engine.stickers.addStickerPackInteractively(info: info, items: items)
|
context.engine.stickers.addStickerPackInteractively(info: info, items: items)
|
||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
)
|
)
|
||||||
|> mapToSignal { _ -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), NoError> in
|
|> mapToSignal { _ -> Signal<(StickerPackCollectionInfo, [StickerPackItem]), NoError> in
|
||||||
}
|
}
|
||||||
|> then(.single((info, items)))
|
|> then(.single((info, items)))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,8 +27,6 @@ public let telegramAccountAuxiliaryMethods = AccountAuxiliaryMethods(fetchResour
|
|||||||
return fetchICloudFileResource(resource: resource)
|
return fetchICloudFileResource(resource: resource)
|
||||||
} else if let resource = resource as? SecureIdLocalImageResource {
|
} else if let resource = resource as? SecureIdLocalImageResource {
|
||||||
return fetchSecureIdLocalImageResource(postbox: account.postbox, resource: resource)
|
return fetchSecureIdLocalImageResource(postbox: account.postbox, resource: resource)
|
||||||
} else if let resource = resource as? OpenInAppIconResource {
|
|
||||||
return fetchOpenInAppIconResource(resource: resource)
|
|
||||||
} else if let resource = resource as? EmojiSpriteResource {
|
} else if let resource = resource as? EmojiSpriteResource {
|
||||||
return fetchEmojiSpriteResource(account: account, resource: resource)
|
return fetchEmojiSpriteResource(account: account, resource: resource)
|
||||||
} else if let resource = resource as? BundleResource {
|
} else if let resource = resource as? BundleResource {
|
||||||
|
|||||||
@ -12,7 +12,6 @@ swift_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||||
"//submodules/TelegramCore:TelegramCore",
|
"//submodules/TelegramCore:TelegramCore",
|
||||||
"//submodules/Postbox:Postbox",
|
|
||||||
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
|
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
|
||||||
"//submodules/TgVoip:TgVoip",
|
"//submodules/TgVoip:TgVoip",
|
||||||
"//submodules/TgVoipWebrtc:TgVoipWebrtc",
|
"//submodules/TgVoipWebrtc:TgVoipWebrtc",
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
import Postbox
|
|
||||||
import TelegramUIPreferences
|
import TelegramUIPreferences
|
||||||
|
|
||||||
import TgVoip
|
import TgVoip
|
||||||
@ -670,8 +669,8 @@ public final class OngoingCallContext {
|
|||||||
return OngoingCallThreadLocalContext.maxLayer()
|
return OngoingCallThreadLocalContext.maxLayer()
|
||||||
}
|
}
|
||||||
|
|
||||||
private let tempLogFile: TempBoxFile
|
private let tempLogFile: EngineTempBoxFile
|
||||||
private let tempStatsLogFile: TempBoxFile
|
private let tempStatsLogFile: EngineTempBoxFile
|
||||||
|
|
||||||
public static func versions(includeExperimental: Bool, includeReference: Bool) -> [(version: String, supportsVideo: Bool)] {
|
public static func versions(includeExperimental: Bool, includeReference: Bool) -> [(version: String, supportsVideo: Bool)] {
|
||||||
var result: [(version: String, supportsVideo: Bool)] = [(OngoingCallThreadLocalContext.version(), false)]
|
var result: [(version: String, supportsVideo: Bool)] = [(OngoingCallThreadLocalContext.version(), false)]
|
||||||
@ -692,10 +691,10 @@ public final class OngoingCallContext {
|
|||||||
self.callSessionManager = callSessionManager
|
self.callSessionManager = callSessionManager
|
||||||
self.logPath = logName.isEmpty ? "" : callLogsPath(account: self.account) + "/" + logName + ".log"
|
self.logPath = logName.isEmpty ? "" : callLogsPath(account: self.account) + "/" + logName + ".log"
|
||||||
let logPath = self.logPath
|
let logPath = self.logPath
|
||||||
self.tempLogFile = TempBox.shared.tempFile(fileName: "CallLog.txt")
|
self.tempLogFile = EngineTempBox.shared.tempFile(fileName: "CallLog.txt")
|
||||||
let tempLogPath = self.tempLogFile.path
|
let tempLogPath = self.tempLogFile.path
|
||||||
|
|
||||||
self.tempStatsLogFile = TempBox.shared.tempFile(fileName: "CallStats.json")
|
self.tempStatsLogFile = EngineTempBox.shared.tempFile(fileName: "CallStats.json")
|
||||||
let tempStatsLogPath = self.tempStatsLogFile.path
|
let tempStatsLogPath = self.tempStatsLogFile.path
|
||||||
|
|
||||||
let queue = self.queue
|
let queue = self.queue
|
||||||
|
|||||||
@ -100,7 +100,7 @@ public func cachedChannelAdminRanksEntryId(peerId: PeerId) -> ItemCacheEntryId {
|
|||||||
return ItemCacheEntryId(collectionId: 100, key: CachedChannelAdminRanks.cacheKey(peerId: peerId))
|
return ItemCacheEntryId(collectionId: 100, key: CachedChannelAdminRanks.cacheKey(peerId: peerId))
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateCachedChannelAdminRanks(postbox: Postbox, peerId: PeerId, ranks: Dictionary<PeerId, CachedChannelAdminRank>) -> Signal<Void, NoError> {
|
func updateCachedChannelAdminRanks(postbox: Postbox, peerId: PeerId, ranks: Dictionary<PeerId, CachedChannelAdminRank>) -> Signal<Void, NoError> {
|
||||||
return postbox.transaction { transaction -> Void in
|
return postbox.transaction { transaction -> Void in
|
||||||
if let entry = CodableEntry(CachedChannelAdminRanks(ranks: ranks)) {
|
if let entry = CodableEntry(CachedChannelAdminRanks(ranks: ranks)) {
|
||||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: 100, key: CachedChannelAdminRanks.cacheKey(peerId: peerId)), entry: entry, collectionSpec: collectionSpec)
|
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: 100, key: CachedChannelAdminRanks.cacheKey(peerId: peerId)), entry: entry, collectionSpec: collectionSpec)
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
import Display
|
import Display
|
||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import Postbox
|
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
import AccountContext
|
import AccountContext
|
||||||
|
|
||||||
@ -16,13 +15,13 @@ public enum UndoOverlayContent {
|
|||||||
case emoji(name: 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: StickerPackItem?, context: AccountContext)
|
||||||
case dice(dice: TelegramMediaDice, context: AccountContext, text: String, action: String?)
|
case dice(dice: TelegramMediaDice, context: AccountContext, text: String, action: String?)
|
||||||
case chatAddedToFolder(chatTitle: String, folderTitle: String)
|
case chatAddedToFolder(chatTitle: String, folderTitle: String)
|
||||||
case chatRemovedFromFolder(chatTitle: String, folderTitle: String)
|
case chatRemovedFromFolder(chatTitle: String, folderTitle: String)
|
||||||
case messagesUnpinned(title: String, text: String, undo: Bool, isHidden: Bool)
|
case messagesUnpinned(title: String, text: String, undo: Bool, isHidden: Bool)
|
||||||
case setProximityAlert(title: String, text: String, cancelled: Bool)
|
case setProximityAlert(title: String, text: String, cancelled: Bool)
|
||||||
case invitedToVoiceChat(context: AccountContext, peer: Peer, text: String)
|
case invitedToVoiceChat(context: AccountContext, peer: EnginePeer, text: String)
|
||||||
case linkCopied(text: String)
|
case linkCopied(text: String)
|
||||||
case banned(text: String)
|
case banned(text: String)
|
||||||
case importedMessage(text: String)
|
case importedMessage(text: String)
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import UIKit
|
|||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
import Display
|
import Display
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import Postbox
|
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import TextFormat
|
import TextFormat
|
||||||
@ -343,7 +342,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
|
|
||||||
enum StickerPackThumbnailItem {
|
enum StickerPackThumbnailItem {
|
||||||
case still(TelegramMediaImageRepresentation)
|
case still(TelegramMediaImageRepresentation)
|
||||||
case animated(MediaResource)
|
case animated(EngineMediaResource)
|
||||||
}
|
}
|
||||||
|
|
||||||
var thumbnailItem: StickerPackThumbnailItem?
|
var thumbnailItem: StickerPackThumbnailItem?
|
||||||
@ -351,15 +350,15 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
|
|
||||||
if let thumbnail = info.thumbnail {
|
if let thumbnail = info.thumbnail {
|
||||||
if info.flags.contains(.isAnimated) {
|
if info.flags.contains(.isAnimated) {
|
||||||
thumbnailItem = .animated(thumbnail.resource)
|
thumbnailItem = .animated(EngineMediaResource(thumbnail.resource))
|
||||||
resourceReference = MediaResourceReference.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)
|
resourceReference = MediaResourceReference.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)
|
||||||
} else {
|
} else {
|
||||||
thumbnailItem = .still(thumbnail)
|
thumbnailItem = .still(thumbnail)
|
||||||
resourceReference = MediaResourceReference.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)
|
resourceReference = MediaResourceReference.stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)
|
||||||
}
|
}
|
||||||
} else if let item = topItem as? StickerPackItem {
|
} else if let item = topItem {
|
||||||
if item.file.isAnimatedSticker {
|
if item.file.isAnimatedSticker {
|
||||||
thumbnailItem = .animated(item.file.resource)
|
thumbnailItem = .animated(EngineMediaResource(item.file.resource))
|
||||||
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource)
|
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource)
|
||||||
} else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource {
|
} else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource {
|
||||||
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
|
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
|
||||||
@ -368,7 +367,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var updatedImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>?
|
var updatedImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>?
|
||||||
var updatedFetchSignal: Signal<FetchResourceSourceType, FetchResourceError>?
|
var updatedFetchSignal: Signal<Never, EngineMediaResource.Fetch.Error>?
|
||||||
|
|
||||||
let imageBoundingSize = CGSize(width: 34.0, height: 34.0)
|
let imageBoundingSize = CGSize(width: 34.0, height: 34.0)
|
||||||
|
|
||||||
@ -382,10 +381,14 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
case let .animated(resource):
|
case let .animated(resource):
|
||||||
self.stickerImageSize = imageBoundingSize
|
self.stickerImageSize = imageBoundingSize
|
||||||
|
|
||||||
updatedImageSignal = chatMessageStickerPackThumbnail(postbox: context.account.postbox, resource: resource, animated: true)
|
updatedImageSignal = chatMessageStickerPackThumbnail(postbox: context.account.postbox, resource: resource._asResource(), animated: true)
|
||||||
}
|
}
|
||||||
if let resourceReference = resourceReference {
|
if let resourceReference = resourceReference {
|
||||||
updatedFetchSignal = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: resourceReference)
|
updatedFetchSignal = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: resourceReference)
|
||||||
|
|> mapError { _ -> EngineMediaResource.Fetch.Error in
|
||||||
|
return .generic
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
updatedImageSignal = .single({ _ in return nil })
|
updatedImageSignal = .single({ _ in return nil })
|
||||||
@ -416,7 +419,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
case let .animated(resource):
|
case let .animated(resource):
|
||||||
let animatedStickerNode = AnimatedStickerNode()
|
let animatedStickerNode = AnimatedStickerNode()
|
||||||
self.animatedStickerNode = animatedStickerNode
|
self.animatedStickerNode = animatedStickerNode
|
||||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: resource), width: 80, height: 80, mode: .cached)
|
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: resource._asResource()), width: 80, height: 80, mode: .cached)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .dice(dice, context, text, action):
|
case let .dice(dice, context, text, action):
|
||||||
@ -465,9 +468,8 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
switch stickerPack {
|
switch stickerPack {
|
||||||
case let .result(_, items, _):
|
case let .result(_, items, _):
|
||||||
let item = items[Int(value)]
|
let item = items[Int(value)]
|
||||||
if let item = item as? StickerPackItem {
|
|
||||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: item.file.resource), width: 120, height: 120, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: item.file.resource), width: 120, height: 120, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -505,7 +507,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: link, linkAttribute: { _ in return nil }), textAlignment: .natural)
|
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: link, linkAttribute: { _ in return nil }), textAlignment: .natural)
|
||||||
self.textNode.attributedText = attributedText
|
self.textNode.attributedText = attributedText
|
||||||
|
|
||||||
self.avatarNode?.setPeer(context: context, theme: presentationData.theme, peer: EnginePeer(peer), overrideImage: nil, emptyColor: presentationData.theme.list.mediaPlaceholderColor, synchronousLoad: true)
|
self.avatarNode?.setPeer(context: context, theme: presentationData.theme, peer: peer, overrideImage: nil, emptyColor: presentationData.theme.list.mediaPlaceholderColor, synchronousLoad: true)
|
||||||
|
|
||||||
displayUndo = false
|
displayUndo = false
|
||||||
self.originalRemainingSeconds = 3
|
self.originalRemainingSeconds = 3
|
||||||
@ -626,14 +628,14 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
|
|
||||||
enum StickerThumbnailItem {
|
enum StickerThumbnailItem {
|
||||||
case still(TelegramMediaImageRepresentation)
|
case still(TelegramMediaImageRepresentation)
|
||||||
case animated(MediaResource)
|
case animated(EngineMediaResource)
|
||||||
}
|
}
|
||||||
|
|
||||||
var thumbnailItem: StickerThumbnailItem?
|
var thumbnailItem: StickerThumbnailItem?
|
||||||
var resourceReference: MediaResourceReference?
|
var resourceReference: MediaResourceReference?
|
||||||
|
|
||||||
if file.isAnimatedSticker {
|
if file.isAnimatedSticker {
|
||||||
thumbnailItem = .animated(file.resource)
|
thumbnailItem = .animated(EngineMediaResource(file.resource))
|
||||||
resourceReference = MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)
|
resourceReference = MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)
|
||||||
} else if let dimensions = file.dimensions, let resource = chatMessageStickerResource(file: file, small: true) as? TelegramMediaResource {
|
} else if let dimensions = file.dimensions, let resource = chatMessageStickerResource(file: file, small: true) as? TelegramMediaResource {
|
||||||
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
|
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
|
||||||
@ -641,7 +643,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var updatedImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>?
|
var updatedImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>?
|
||||||
var updatedFetchSignal: Signal<FetchResourceSourceType, FetchResourceError>?
|
var updatedFetchSignal: Signal<Never, EngineMediaResource.Fetch.Error>?
|
||||||
|
|
||||||
let imageBoundingSize = CGSize(width: 34.0, height: 34.0)
|
let imageBoundingSize = CGSize(width: 34.0, height: 34.0)
|
||||||
|
|
||||||
@ -655,10 +657,14 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
case let .animated(resource):
|
case let .animated(resource):
|
||||||
self.stickerImageSize = imageBoundingSize
|
self.stickerImageSize = imageBoundingSize
|
||||||
|
|
||||||
updatedImageSignal = chatMessageStickerPackThumbnail(postbox: context.account.postbox, resource: resource, animated: true)
|
updatedImageSignal = chatMessageStickerPackThumbnail(postbox: context.account.postbox, resource: resource._asResource(), animated: true)
|
||||||
}
|
}
|
||||||
if let resourceReference = resourceReference {
|
if let resourceReference = resourceReference {
|
||||||
updatedFetchSignal = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: resourceReference)
|
updatedFetchSignal = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: resourceReference)
|
||||||
|
|> mapError { _ -> EngineMediaResource.Fetch.Error in
|
||||||
|
return .generic
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
updatedImageSignal = .single({ _ in return nil })
|
updatedImageSignal = .single({ _ in return nil })
|
||||||
@ -689,7 +695,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
case let .animated(resource):
|
case let .animated(resource):
|
||||||
let animatedStickerNode = AnimatedStickerNode()
|
let animatedStickerNode = AnimatedStickerNode()
|
||||||
self.animatedStickerNode = animatedStickerNode
|
self.animatedStickerNode = animatedStickerNode
|
||||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: resource), width: 80, height: 80, mode: .cached)
|
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: context.account, resource: resource._asResource()), width: 80, height: 80, mode: .cached)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .copy(text):
|
case let .copy(text):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user