mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
70dd6ed1f2
@ -358,6 +358,7 @@ plist_fragment(
|
|||||||
name = "TelegramEntitlements",
|
name = "TelegramEntitlements",
|
||||||
extension = "entitlements",
|
extension = "entitlements",
|
||||||
template = "".join([
|
template = "".join([
|
||||||
|
aps_fragment,
|
||||||
app_groups_fragment,
|
app_groups_fragment,
|
||||||
siri_fragment,
|
siri_fragment,
|
||||||
associated_domains_fragment,
|
associated_domains_fragment,
|
||||||
@ -1338,13 +1339,23 @@ swift_intent_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "IntentsAssets",
|
||||||
|
srcs = glob(["SiriIntents/IntentsImages.xcassets/**"]),
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
swift_library(
|
swift_library(
|
||||||
name = "IntentsExtensionLib",
|
name = "IntentsExtensionLib",
|
||||||
module_name = "IntentsExtensionLib",
|
module_name = "IntentsExtensionLib",
|
||||||
srcs = glob([
|
srcs = glob([
|
||||||
"SiriIntents/**/*.swift",
|
"SiriIntents/**/*.swift",
|
||||||
]),
|
]),
|
||||||
data = glob(["SiriIntents/*.lproj/Intents.intentdefinition"]),
|
data = glob([
|
||||||
|
"SiriIntents/*.lproj/Intents.intentdefinition"
|
||||||
|
]) + [
|
||||||
|
":IntentsAssets"
|
||||||
|
],
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||||
"//submodules/Postbox:Postbox",
|
"//submodules/Postbox:Postbox",
|
||||||
|
@ -1224,6 +1224,74 @@ private func avatarImage(path: String?, peerId: Int64, accountPeerId: Int64, let
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func generateTintedImage(image: UIImage?, color: UIColor, backgroundColor: UIColor? = nil) -> UIImage? {
|
||||||
|
guard let image = image else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let imageSize = image.size
|
||||||
|
|
||||||
|
UIGraphicsBeginImageContextWithOptions(imageSize, backgroundColor != nil, image.scale)
|
||||||
|
if let context = UIGraphicsGetCurrentContext() {
|
||||||
|
if let backgroundColor = backgroundColor {
|
||||||
|
context.setFillColor(backgroundColor.cgColor)
|
||||||
|
context.fill(CGRect(origin: CGPoint(), size: imageSize))
|
||||||
|
}
|
||||||
|
|
||||||
|
let imageRect = CGRect(origin: CGPoint(), size: imageSize)
|
||||||
|
context.saveGState()
|
||||||
|
context.translateBy(x: imageRect.midX, y: imageRect.midY)
|
||||||
|
context.scaleBy(x: 1.0, y: -1.0)
|
||||||
|
context.translateBy(x: -imageRect.midX, y: -imageRect.midY)
|
||||||
|
context.clip(to: imageRect, mask: image.cgImage!)
|
||||||
|
context.setFillColor(color.cgColor)
|
||||||
|
context.fill(imageRect)
|
||||||
|
context.restoreGState()
|
||||||
|
}
|
||||||
|
|
||||||
|
let tintedImage = UIGraphicsGetImageFromCurrentImageContext()!
|
||||||
|
UIGraphicsEndImageContext()
|
||||||
|
|
||||||
|
return tintedImage
|
||||||
|
}
|
||||||
|
|
||||||
|
private let savedMessagesColors: NSArray = [
|
||||||
|
UIColor(rgb: 0x2a9ef1).cgColor, UIColor(rgb: 0x72d5fd).cgColor
|
||||||
|
]
|
||||||
|
|
||||||
|
private func savedMessagesImage(size: CGSize) -> UIImage? {
|
||||||
|
guard let icon = generateTintedImage(image: UIImage(named: "Intents/SavedMessages"), color: .white) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
|
||||||
|
let context = UIGraphicsGetCurrentContext()
|
||||||
|
|
||||||
|
context?.beginPath()
|
||||||
|
context?.addEllipse(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
|
||||||
|
context?.clip()
|
||||||
|
|
||||||
|
let colorsArray = savedMessagesColors
|
||||||
|
var locations: [CGFloat] = [1.0, 0.0]
|
||||||
|
let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray, locations: &locations)!
|
||||||
|
|
||||||
|
context?.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
|
||||||
|
|
||||||
|
context?.setBlendMode(.normal)
|
||||||
|
|
||||||
|
let factor = size.width / 60.0
|
||||||
|
context?.translateBy(x: size.width / 2.0, y: size.height / 2.0)
|
||||||
|
context?.scaleBy(x: factor, y: -factor)
|
||||||
|
context?.translateBy(x: -size.width / 2.0, y: -size.height / 2.0)
|
||||||
|
|
||||||
|
if let context = context {
|
||||||
|
context.draw(icon.cgImage!, in: CGRect(origin: CGPoint(x: floor((size.width - icon.size.width) / 2.0), y: floor((size.height - icon.size.height) / 2.0)), size: icon.size))
|
||||||
|
}
|
||||||
|
|
||||||
|
let image = UIGraphicsGetImageFromCurrentImageContext()
|
||||||
|
UIGraphicsEndImageContext()
|
||||||
|
return image
|
||||||
|
}
|
||||||
|
|
||||||
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
||||||
private func mapPeersToFriends(accountId: AccountRecordId, accountPeerId: PeerId, mediaBox: MediaBox, peers: [Peer]) -> [Friend] {
|
private func mapPeersToFriends(accountId: AccountRecordId, accountPeerId: PeerId, mediaBox: MediaBox, peers: [Peer]) -> [Friend] {
|
||||||
var items: [Friend] = []
|
var items: [Friend] = []
|
||||||
@ -1231,7 +1299,26 @@ private func mapPeersToFriends(accountId: AccountRecordId, accountPeerId: PeerId
|
|||||||
autoreleasepool {
|
autoreleasepool {
|
||||||
var profileImage: INImage?
|
var profileImage: INImage?
|
||||||
|
|
||||||
if let resource = smallestImageRepresentation(peer.profileImageRepresentations)?.resource, let path = mediaBox.completedResourcePath(resource) {
|
if peer.id == accountPeerId {
|
||||||
|
let cachedPath = mediaBox.cachedRepresentationPathForId("savedMessagesAvatar50x50", representationId: "intents.png", keepDuration: .shortLived)
|
||||||
|
if let _ = fileSize(cachedPath) {
|
||||||
|
do {
|
||||||
|
let data = try Data(contentsOf: URL(fileURLWithPath: cachedPath), options: .alwaysMapped)
|
||||||
|
profileImage = INImage(imageData: data)
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let image = savedMessagesImage(size: CGSize(width: 50.0, height: 50.0))
|
||||||
|
if let data = image?.pngData() {
|
||||||
|
let _ = try? data.write(to: URL(fileURLWithPath: cachedPath), options: .atomic)
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
let data = try Data(contentsOf: URL(fileURLWithPath: cachedPath), options: .alwaysMapped)
|
||||||
|
profileImage = INImage(imageData: data)
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let resource = smallestImageRepresentation(peer.profileImageRepresentations)?.resource, let path = mediaBox.completedResourcePath(resource) {
|
||||||
let cachedPath = mediaBox.cachedRepresentationPathForId(resource.id.uniqueId, representationId: "intents.png", keepDuration: .shortLived)
|
let cachedPath = mediaBox.cachedRepresentationPathForId(resource.id.uniqueId, representationId: "intents.png", keepDuration: .shortLived)
|
||||||
if let _ = fileSize(cachedPath) {
|
if let _ = fileSize(cachedPath) {
|
||||||
do {
|
do {
|
||||||
@ -1272,7 +1359,12 @@ private func mapPeersToFriends(accountId: AccountRecordId, accountPeerId: PeerId
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
items.append(Friend(identifier: "\(accountId.int64):\(peer.id.toInt64())", display: peer.debugDisplayTitle, subtitle: nil, image: profileImage))
|
var displayTitle = peer.debugDisplayTitle
|
||||||
|
if peer.id == accountPeerId {
|
||||||
|
displayTitle = WidgetPresentationData.getForExtension().chatSavedMessages
|
||||||
|
}
|
||||||
|
|
||||||
|
items.append(Friend(identifier: "\(accountId.int64):\(peer.id.toInt64())", display: displayTitle, subtitle: nil, image: profileImage))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return items
|
return items
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"provides-namespace" : true
|
||||||
|
}
|
||||||
|
}
|
12
Telegram/SiriIntents/IntentsImages.xcassets/Intents/SavedMessages.imageset/Contents.json
vendored
Normal file
12
Telegram/SiriIntents/IntentsImages.xcassets/Intents/SavedMessages.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "ic_av_savedmessages (2).pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
@ -92,10 +92,77 @@ private func avatarViewLettersImage(size: CGSize, peerId: Int64, accountPeerId:
|
|||||||
return image
|
return image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func generateTintedImage(image: UIImage?, color: UIColor, backgroundColor: UIColor? = nil) -> UIImage? {
|
||||||
|
guard let image = image else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let imageSize = image.size
|
||||||
|
|
||||||
|
UIGraphicsBeginImageContextWithOptions(imageSize, backgroundColor != nil, image.scale)
|
||||||
|
if let context = UIGraphicsGetCurrentContext() {
|
||||||
|
if let backgroundColor = backgroundColor {
|
||||||
|
context.setFillColor(backgroundColor.cgColor)
|
||||||
|
context.fill(CGRect(origin: CGPoint(), size: imageSize))
|
||||||
|
}
|
||||||
|
|
||||||
|
let imageRect = CGRect(origin: CGPoint(), size: imageSize)
|
||||||
|
context.saveGState()
|
||||||
|
context.translateBy(x: imageRect.midX, y: imageRect.midY)
|
||||||
|
context.scaleBy(x: 1.0, y: -1.0)
|
||||||
|
context.translateBy(x: -imageRect.midX, y: -imageRect.midY)
|
||||||
|
context.clip(to: imageRect, mask: image.cgImage!)
|
||||||
|
context.setFillColor(color.cgColor)
|
||||||
|
context.fill(imageRect)
|
||||||
|
context.restoreGState()
|
||||||
|
}
|
||||||
|
|
||||||
|
let tintedImage = UIGraphicsGetImageFromCurrentImageContext()!
|
||||||
|
UIGraphicsEndImageContext()
|
||||||
|
|
||||||
|
return tintedImage
|
||||||
|
}
|
||||||
|
|
||||||
|
private let savedMessagesColors: NSArray = [
|
||||||
|
UIColor(rgb: 0x2a9ef1).cgColor, UIColor(rgb: 0x72d5fd).cgColor
|
||||||
|
]
|
||||||
|
|
||||||
|
private func savedMessagesImage(size: CGSize) -> UIImage? {
|
||||||
|
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
|
||||||
|
let context = UIGraphicsGetCurrentContext()
|
||||||
|
|
||||||
|
context?.beginPath()
|
||||||
|
context?.addEllipse(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
|
||||||
|
context?.clip()
|
||||||
|
|
||||||
|
let colorsArray = savedMessagesColors
|
||||||
|
var locations: [CGFloat] = [1.0, 0.0]
|
||||||
|
let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray, locations: &locations)!
|
||||||
|
|
||||||
|
context?.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
|
||||||
|
|
||||||
|
context?.setBlendMode(.normal)
|
||||||
|
|
||||||
|
let factor = size.width / 60.0
|
||||||
|
context?.translateBy(x: size.width / 2.0, y: size.height / 2.0)
|
||||||
|
context?.scaleBy(x: factor, y: -factor)
|
||||||
|
context?.translateBy(x: -size.width / 2.0, y: -size.height / 2.0)
|
||||||
|
|
||||||
|
if let context = context, let icon = generateTintedImage(image: UIImage(named: "Widget/SavedMessages"), color: .white) {
|
||||||
|
context.draw(icon.cgImage!, in: CGRect(origin: CGPoint(x: floor((size.width - icon.size.width) / 2.0), y: floor((size.height - icon.size.height) / 2.0)), size: icon.size))
|
||||||
|
}
|
||||||
|
|
||||||
|
let image = UIGraphicsGetImageFromCurrentImageContext()
|
||||||
|
UIGraphicsEndImageContext()
|
||||||
|
return image
|
||||||
|
}
|
||||||
|
|
||||||
private let avatarSize = CGSize(width: 50.0, height: 50.0)
|
private let avatarSize = CGSize(width: 50.0, height: 50.0)
|
||||||
|
|
||||||
func avatarImage(accountPeerId: Int64?, peer: WidgetDataPeer?, size: CGSize) -> UIImage {
|
func avatarImage(accountPeerId: Int64?, peer: WidgetDataPeer?, size: CGSize) -> UIImage {
|
||||||
if let path = peer?.avatarPath, let image = UIImage(contentsOfFile: path), let roundImage = avatarRoundImage(size: size, source: image) {
|
if let peer = peer, let accountPeerId = accountPeerId, peer.id == accountPeerId {
|
||||||
|
return savedMessagesImage(size: size)!
|
||||||
|
} else if let path = peer?.avatarPath, let image = UIImage(contentsOfFile: path), let roundImage = avatarRoundImage(size: size, source: image) {
|
||||||
return roundImage
|
return roundImage
|
||||||
} else {
|
} else {
|
||||||
return avatarViewLettersImage(size: size, peerId: peer?.id ?? 1, accountPeerId: accountPeerId ?? 1, letters: peer?.letters ?? [" "])!
|
return avatarViewLettersImage(size: size, peerId: peer?.id ?? 1, accountPeerId: accountPeerId ?? 1, letters: peer?.letters ?? [" "])!
|
||||||
|
@ -316,7 +316,9 @@ struct WidgetView: View {
|
|||||||
dateText = ""
|
dateText = ""
|
||||||
}
|
}
|
||||||
var formattedName = peer.peer.name
|
var formattedName = peer.peer.name
|
||||||
if let lastName = peer.peer.lastName {
|
if peer.accountPeerId == peer.peer.id {
|
||||||
|
formattedName = self.presentationData.chatSavedMessages
|
||||||
|
} else if let lastName = peer.peer.lastName {
|
||||||
formattedName.append(" \(lastName)")
|
formattedName.append(" \(lastName)")
|
||||||
}
|
}
|
||||||
chatTitle = AnyView(Text(formattedName)
|
chatTitle = AnyView(Text(formattedName)
|
||||||
@ -575,10 +577,15 @@ struct WidgetView: View {
|
|||||||
content = .placeholder
|
content = .placeholder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let avatarView: AvatarItemView
|
||||||
|
avatarView = AvatarItemView(peer: peers?.peers[index], itemSize: 54.0, placeholderColor: getPlaceholderColor())
|
||||||
|
|
||||||
return AnyView(
|
return AnyView(
|
||||||
Link(destination: url, label: {
|
Link(destination: url, label: {
|
||||||
HStack(alignment: .center, spacing: 0.0, content: {
|
HStack(alignment: .center, spacing: 0.0, content: {
|
||||||
AvatarItemView(peer: peers?.peers[index], itemSize: 54.0, placeholderColor: getPlaceholderColor()).frame(width: 54.0, height: 54.0, alignment: .leading).padding(EdgeInsets(top: 0.0, leading: 10.0, bottom: 0.0, trailing: 10.0))
|
avatarView
|
||||||
|
.frame(width: 54.0, height: 54.0, alignment: .leading)
|
||||||
|
.padding(EdgeInsets(top: 0.0, leading: 10.0, bottom: 0.0, trailing: 10.0))
|
||||||
chatContent(content).frame(maxWidth: .infinity).padding(EdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 10.0))
|
chatContent(content).frame(maxWidth: .infinity).padding(EdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 10.0))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
12
Telegram/WidgetKitWidget/WidgetImages.xcassets/Widget/SavedMessages.imageset/Contents.json
vendored
Normal file
12
Telegram/WidgetKitWidget/WidgetImages.xcassets/Widget/SavedMessages.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "ic_av_savedmessages (2).pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
@ -1510,11 +1510,18 @@ public protocol ContextExtractedContentSource: class {
|
|||||||
var keepInPlace: Bool { get }
|
var keepInPlace: Bool { get }
|
||||||
var ignoreContentTouches: Bool { get }
|
var ignoreContentTouches: Bool { get }
|
||||||
var blurBackground: Bool { get }
|
var blurBackground: Bool { get }
|
||||||
|
var shouldBeDismissed: Signal<Bool, NoError> { get }
|
||||||
|
|
||||||
func takeView() -> ContextControllerTakeViewInfo?
|
func takeView() -> ContextControllerTakeViewInfo?
|
||||||
func putBack() -> ContextControllerPutBackViewInfo?
|
func putBack() -> ContextControllerPutBackViewInfo?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extension ContextExtractedContentSource {
|
||||||
|
var shouldBeDismissed: Signal<Bool, NoError> {
|
||||||
|
return .single(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public protocol ContextControllerContentSource: class {
|
public protocol ContextControllerContentSource: class {
|
||||||
var controller: ViewController { get }
|
var controller: ViewController { get }
|
||||||
var navigationController: NavigationController? { get }
|
var navigationController: NavigationController? { get }
|
||||||
@ -1555,6 +1562,8 @@ public final class ContextController: ViewController, StandalonePresentableContr
|
|||||||
|
|
||||||
public var reactionSelected: ((ReactionContextItem.Reaction) -> Void)?
|
public var reactionSelected: ((ReactionContextItem.Reaction) -> Void)?
|
||||||
|
|
||||||
|
private var shouldBeDismissedDisposable: Disposable?
|
||||||
|
|
||||||
public init(account: Account, presentationData: PresentationData, source: ContextContentSource, items: Signal<[ContextMenuItem], NoError>, reactionItems: [ReactionContextItem], recognizer: TapLongTapOrDoubleTapGestureRecognizer? = nil, gesture: ContextGesture? = nil, displayTextSelectionTip: Bool = false) {
|
public init(account: Account, presentationData: PresentationData, source: ContextContentSource, items: Signal<[ContextMenuItem], NoError>, reactionItems: [ReactionContextItem], recognizer: TapLongTapOrDoubleTapGestureRecognizer? = nil, gesture: ContextGesture? = nil, displayTextSelectionTip: Bool = false) {
|
||||||
self.account = account
|
self.account = account
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
@ -1567,8 +1576,19 @@ public final class ContextController: ViewController, StandalonePresentableContr
|
|||||||
|
|
||||||
super.init(navigationBarPresentationData: nil)
|
super.init(navigationBarPresentationData: nil)
|
||||||
|
|
||||||
if case let .extracted(extractedSource) = source, !extractedSource.blurBackground {
|
if case let .extracted(extractedSource) = source {
|
||||||
self.statusBar.statusBarStyle = .Ignore
|
if !extractedSource.blurBackground {
|
||||||
|
self.statusBar.statusBarStyle = .Ignore
|
||||||
|
}
|
||||||
|
self.shouldBeDismissedDisposable = (extractedSource.shouldBeDismissed
|
||||||
|
|> filter { $0 }
|
||||||
|
|> take(1)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] _ in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.dismiss(result: .default, completion: {})
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
self.statusBar.statusBarStyle = .Hide
|
self.statusBar.statusBarStyle = .Hide
|
||||||
}
|
}
|
||||||
@ -1579,6 +1599,10 @@ public final class ContextController: ViewController, StandalonePresentableContr
|
|||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.shouldBeDismissedDisposable?.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
override public func loadDisplayNode() {
|
override public func loadDisplayNode() {
|
||||||
self.displayNode = ContextControllerNode(account: self.account, controller: self, presentationData: self.presentationData, source: self.source, items: self.items, reactionItems: self.reactionItems, beginDismiss: { [weak self] result in
|
self.displayNode = ContextControllerNode(account: self.account, controller: self, presentationData: self.presentationData, source: self.source, items: self.items, reactionItems: self.reactionItems, beginDismiss: { [weak self] result in
|
||||||
self?.dismiss(result: result, completion: nil)
|
self?.dismiss(result: result, completion: nil)
|
||||||
|
@ -463,6 +463,7 @@ public class GalleryController: ViewController, StandalonePresentableController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|> take(1)
|
||||||
|
|
||||||
let semaphore: DispatchSemaphore?
|
let semaphore: DispatchSemaphore?
|
||||||
if synchronousLoad {
|
if synchronousLoad {
|
||||||
@ -486,23 +487,6 @@ public class GalleryController: ViewController, StandalonePresentableController
|
|||||||
strongSelf.configuration = configuration
|
strongSelf.configuration = configuration
|
||||||
|
|
||||||
let entries = view.entries
|
let entries = view.entries
|
||||||
|
|
||||||
if let centralEntryStableId = strongSelf.centralEntryStableId {
|
|
||||||
var found = false
|
|
||||||
for i in 0 ..< entries.count {
|
|
||||||
let message = entries[i].message
|
|
||||||
if message.stableId == centralEntryStableId {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !found {
|
|
||||||
strongSelf.dismiss(forceAway: true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var centralEntryStableId: UInt32?
|
var centralEntryStableId: UInt32?
|
||||||
loop: for i in 0 ..< entries.count {
|
loop: for i in 0 ..< entries.count {
|
||||||
let message = entries[i].message
|
let message = entries[i].message
|
||||||
@ -531,16 +515,14 @@ public class GalleryController: ViewController, StandalonePresentableController
|
|||||||
strongSelf.entries = entries.reversed()
|
strongSelf.entries = entries.reversed()
|
||||||
strongSelf.hasLeftEntries = view.hasLater
|
strongSelf.hasLeftEntries = view.hasLater
|
||||||
strongSelf.hasRightEntries = view.hasEarlier
|
strongSelf.hasRightEntries = view.hasEarlier
|
||||||
if strongSelf.centralEntryStableId == nil, let centralEntryStableId = centralEntryStableId {
|
if let centralEntryStableId = centralEntryStableId {
|
||||||
strongSelf.centralEntryStableId = centralEntryStableId
|
strongSelf.centralEntryStableId = centralEntryStableId
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strongSelf.entries = entries
|
strongSelf.entries = entries
|
||||||
strongSelf.hasLeftEntries = view.hasEarlier
|
strongSelf.hasLeftEntries = view.hasEarlier
|
||||||
strongSelf.hasRightEntries = view.hasLater
|
strongSelf.hasRightEntries = view.hasLater
|
||||||
if strongSelf.centralEntryStableId == nil {
|
strongSelf.centralEntryStableId = centralEntryStableId
|
||||||
strongSelf.centralEntryStableId = centralEntryStableId
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if strongSelf.isViewLoaded {
|
if strongSelf.isViewLoaded {
|
||||||
var items: [GalleryItem] = []
|
var items: [GalleryItem] = []
|
||||||
@ -565,17 +547,13 @@ public class GalleryController: ViewController, StandalonePresentableController
|
|||||||
strongSelf.galleryNode.pager.replaceItems(items, centralItemIndex: centralItemIndex)
|
strongSelf.galleryNode.pager.replaceItems(items, centralItemIndex: centralItemIndex)
|
||||||
|
|
||||||
if strongSelf.temporaryDoNotWaitForReady {
|
if strongSelf.temporaryDoNotWaitForReady {
|
||||||
if !strongSelf.didSetReady {
|
strongSelf.didSetReady = true
|
||||||
strongSelf.didSetReady = true
|
strongSelf._ready.set(.single(true))
|
||||||
strongSelf._ready.set(.single(true))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if !strongSelf.didSetReady {
|
let ready = strongSelf.galleryNode.pager.ready() |> timeout(2.0, queue: Queue.mainQueue(), alternate: .single(Void())) |> afterNext { [weak strongSelf] _ in
|
||||||
let ready = strongSelf.galleryNode.pager.ready() |> timeout(2.0, queue: Queue.mainQueue(), alternate: .single(Void())) |> afterNext { [weak strongSelf] _ in
|
strongSelf?.didSetReady = true
|
||||||
strongSelf?.didSetReady = true
|
|
||||||
}
|
|
||||||
strongSelf._ready.set(ready |> map { true })
|
|
||||||
}
|
}
|
||||||
|
strongSelf._ready.set(ready |> map { true })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -590,7 +568,7 @@ public class GalleryController: ViewController, StandalonePresentableController
|
|||||||
return (true, nil)
|
return (true, nil)
|
||||||
}
|
}
|
||||||
semaphore?.signal()
|
semaphore?.signal()
|
||||||
if process || true {
|
if process {
|
||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ private func peerAutoremoveSetupEntries(peer: Peer?, presentationData: Presentat
|
|||||||
24 * 60 * 60 * 7
|
24 * 60 * 60 * 7
|
||||||
]
|
]
|
||||||
if isDebug || true {
|
if isDebug || true {
|
||||||
availableValues[1] = 60
|
availableValues[1] = 5
|
||||||
availableValues[2] = 5 * 60
|
availableValues[2] = 5 * 60
|
||||||
}
|
}
|
||||||
entries.append(.timeValue(resolvedValue, availableValues))
|
entries.append(.timeValue(resolvedValue, availableValues))
|
||||||
|
@ -298,6 +298,8 @@ public final class SqliteValueBox: ValueBox {
|
|||||||
preconditionFailure("Couldn't open database")
|
preconditionFailure("Couldn't open database")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sqlite3_busy_timeout(database.handle, 1000 * 10000)
|
||||||
|
|
||||||
var resultCode: Bool = true
|
var resultCode: Bool = true
|
||||||
|
|
||||||
resultCode = database.execute("PRAGMA cipher_plaintext_header_size=32")
|
resultCode = database.execute("PRAGMA cipher_plaintext_header_size=32")
|
||||||
@ -408,8 +410,6 @@ public final class SqliteValueBox: ValueBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_busy_timeout(database.handle, 1000 * 10000)
|
|
||||||
|
|
||||||
//database.execute("PRAGMA cache_size=-2097152")
|
//database.execute("PRAGMA cache_size=-2097152")
|
||||||
resultCode = database.execute("PRAGMA mmap_size=0")
|
resultCode = database.execute("PRAGMA mmap_size=0")
|
||||||
assert(resultCode)
|
assert(resultCode)
|
||||||
|
@ -844,7 +844,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
let _ = ApplicationSpecificNotice.incrementChatTextSelectionTips(accountManager: strongSelf.context.sharedContext.accountManager).start()
|
let _ = ApplicationSpecificNotice.incrementChatTextSelectionTips(accountManager: strongSelf.context.sharedContext.accountManager).start()
|
||||||
}
|
}
|
||||||
|
|
||||||
let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, message: message, selectAll: selectAll)), items: .single(actions), reactionItems: reactionItems, recognizer: recognizer, gesture: gesture, displayTextSelectionTip: displayTextSelectionTip)
|
let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, postbox: strongSelf.context.account.postbox, message: message, selectAll: selectAll)), items: .single(actions), reactionItems: reactionItems, recognizer: recognizer, gesture: gesture, displayTextSelectionTip: displayTextSelectionTip)
|
||||||
strongSelf.currentContextController = controller
|
strongSelf.currentContextController = controller
|
||||||
controller.reactionSelected = { [weak controller] value in
|
controller.reactionSelected = { [weak controller] value in
|
||||||
guard let strongSelf = self, let message = updatedMessages.first else {
|
guard let strongSelf = self, let message = updatedMessages.first else {
|
||||||
@ -1870,7 +1870,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
})))
|
})))
|
||||||
|
|
||||||
let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, message: message, selectAll: true)), items: .single(actions), reactionItems: [], recognizer: nil)
|
let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, postbox: strongSelf.context.account.postbox, message: message, selectAll: true)), items: .single(actions), reactionItems: [], recognizer: nil)
|
||||||
strongSelf.currentContextController = controller
|
strongSelf.currentContextController = controller
|
||||||
strongSelf.forEachController({ controller in
|
strongSelf.forEachController({ controller in
|
||||||
if let controller = controller as? TooltipScreen {
|
if let controller = controller as? TooltipScreen {
|
||||||
@ -1947,7 +1947,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
f(.dismissWithoutContent)
|
f(.dismissWithoutContent)
|
||||||
})))
|
})))
|
||||||
|
|
||||||
let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, message: topMessage, selectAll: true)), items: .single(actions), reactionItems: [], recognizer: nil)
|
let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, postbox: strongSelf.context.account.postbox, message: topMessage, selectAll: true)), items: .single(actions), reactionItems: [], recognizer: nil)
|
||||||
strongSelf.currentContextController = controller
|
strongSelf.currentContextController = controller
|
||||||
strongSelf.forEachController({ controller in
|
strongSelf.forEachController({ controller in
|
||||||
if let controller = controller as? TooltipScreen {
|
if let controller = controller as? TooltipScreen {
|
||||||
|
@ -3,6 +3,7 @@ import UIKit
|
|||||||
import Display
|
import Display
|
||||||
import ContextUI
|
import ContextUI
|
||||||
import Postbox
|
import Postbox
|
||||||
|
import SwiftSignalKit
|
||||||
|
|
||||||
final class ChatMessageContextExtractedContentSource: ContextExtractedContentSource {
|
final class ChatMessageContextExtractedContentSource: ContextExtractedContentSource {
|
||||||
let keepInPlace: Bool = false
|
let keepInPlace: Bool = false
|
||||||
@ -10,11 +11,29 @@ final class ChatMessageContextExtractedContentSource: ContextExtractedContentSou
|
|||||||
let blurBackground: Bool = true
|
let blurBackground: Bool = true
|
||||||
|
|
||||||
private weak var chatNode: ChatControllerNode?
|
private weak var chatNode: ChatControllerNode?
|
||||||
|
private let postbox: Postbox
|
||||||
private let message: Message
|
private let message: Message
|
||||||
private let selectAll: Bool
|
private let selectAll: Bool
|
||||||
|
|
||||||
init(chatNode: ChatControllerNode, message: Message, selectAll: Bool) {
|
var shouldBeDismissed: Signal<Bool, NoError> {
|
||||||
|
let viewKey = PostboxViewKey.messages(Set([self.message.id]))
|
||||||
|
return self.postbox.combinedView(keys: [viewKey])
|
||||||
|
|> map { views -> Bool in
|
||||||
|
guard let view = views.views[viewKey] as? MessagesView else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if view.messages.isEmpty {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
init(chatNode: ChatControllerNode, postbox: Postbox, message: Message, selectAll: Bool) {
|
||||||
self.chatNode = chatNode
|
self.chatNode = chatNode
|
||||||
|
self.postbox = postbox
|
||||||
self.message = message
|
self.message = message
|
||||||
self.selectAll = selectAll
|
self.selectAll = selectAll
|
||||||
}
|
}
|
||||||
|
@ -277,7 +277,8 @@ final class WidgetDataContext {
|
|||||||
autodeleteTimerUpdated: presentationData.strings.Widget_MessageAutoremoveTimerUpdated,
|
autodeleteTimerUpdated: presentationData.strings.Widget_MessageAutoremoveTimerUpdated,
|
||||||
autodeleteTimerRemoved: presentationData.strings.Widget_MessageAutoremoveTimerRemoved,
|
autodeleteTimerRemoved: presentationData.strings.Widget_MessageAutoremoveTimerRemoved,
|
||||||
generalLockedTitle: presentationData.strings.Intents_ErrorLockedTitle,
|
generalLockedTitle: presentationData.strings.Intents_ErrorLockedTitle,
|
||||||
generalLockedText: presentationData.strings.Intents_ErrorLockedText
|
generalLockedText: presentationData.strings.Intents_ErrorLockedText,
|
||||||
|
chatSavedMessages: presentationData.strings.DialogList_SavedMessages
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|> distinctUntilChanged).start(next: { value in
|
|> distinctUntilChanged).start(next: { value in
|
||||||
|
@ -300,6 +300,8 @@ public struct WidgetPresentationData: Codable, Equatable {
|
|||||||
public var generalLockedTitle: String
|
public var generalLockedTitle: String
|
||||||
public var generalLockedText: String
|
public var generalLockedText: String
|
||||||
|
|
||||||
|
public var chatSavedMessages: String
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
widgetChatsGalleryTitle: String,
|
widgetChatsGalleryTitle: String,
|
||||||
widgetChatsGalleryDescription: String,
|
widgetChatsGalleryDescription: String,
|
||||||
@ -321,7 +323,8 @@ public struct WidgetPresentationData: Codable, Equatable {
|
|||||||
autodeleteTimerUpdated: String,
|
autodeleteTimerUpdated: String,
|
||||||
autodeleteTimerRemoved: String,
|
autodeleteTimerRemoved: String,
|
||||||
generalLockedTitle: String,
|
generalLockedTitle: String,
|
||||||
generalLockedText: String
|
generalLockedText: String,
|
||||||
|
chatSavedMessages: String
|
||||||
) {
|
) {
|
||||||
self.widgetChatsGalleryTitle = widgetChatsGalleryTitle
|
self.widgetChatsGalleryTitle = widgetChatsGalleryTitle
|
||||||
self.widgetChatsGalleryDescription = widgetChatsGalleryDescription
|
self.widgetChatsGalleryDescription = widgetChatsGalleryDescription
|
||||||
@ -344,6 +347,7 @@ public struct WidgetPresentationData: Codable, Equatable {
|
|||||||
self.autodeleteTimerRemoved = autodeleteTimerRemoved
|
self.autodeleteTimerRemoved = autodeleteTimerRemoved
|
||||||
self.generalLockedTitle = generalLockedTitle
|
self.generalLockedTitle = generalLockedTitle
|
||||||
self.generalLockedText = generalLockedText
|
self.generalLockedText = generalLockedText
|
||||||
|
self.chatSavedMessages = chatSavedMessages
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func getForExtension() -> WidgetPresentationData {
|
public static func getForExtension() -> WidgetPresentationData {
|
||||||
@ -392,7 +396,8 @@ public extension WidgetPresentationData {
|
|||||||
autodeleteTimerUpdated: "Auto-delete timer updated",
|
autodeleteTimerUpdated: "Auto-delete timer updated",
|
||||||
autodeleteTimerRemoved: "Auto-delete timer disabled",
|
autodeleteTimerRemoved: "Auto-delete timer disabled",
|
||||||
generalLockedTitle: "Locked",
|
generalLockedTitle: "Locked",
|
||||||
generalLockedText: "Open Telegram and enter passcode to edit widget."
|
generalLockedText: "Open Telegram and enter passcode to edit widget.",
|
||||||
|
chatSavedMessages: "Saved Messages"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user