mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Display the saved messages icon in widgets
This commit is contained in:
parent
a46bfa8265
commit
6417d8862c
@ -1339,13 +1339,23 @@ swift_intent_library(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "IntentsAssets",
|
||||
srcs = glob(["SiriIntents/IntentsImages.xcassets/**"]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
swift_library(
|
||||
name = "IntentsExtensionLib",
|
||||
module_name = "IntentsExtensionLib",
|
||||
srcs = glob([
|
||||
"SiriIntents/**/*.swift",
|
||||
]),
|
||||
data = glob(["SiriIntents/*.lproj/Intents.intentdefinition"]),
|
||||
data = glob([
|
||||
"SiriIntents/*.lproj/Intents.intentdefinition"
|
||||
]) + [
|
||||
":IntentsAssets"
|
||||
],
|
||||
deps = [
|
||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||
"//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, *)
|
||||
private func mapPeersToFriends(accountId: AccountRecordId, accountPeerId: PeerId, mediaBox: MediaBox, peers: [Peer]) -> [Friend] {
|
||||
var items: [Friend] = []
|
||||
@ -1231,7 +1299,26 @@ private func mapPeersToFriends(accountId: AccountRecordId, accountPeerId: PeerId
|
||||
autoreleasepool {
|
||||
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)
|
||||
if let _ = fileSize(cachedPath) {
|
||||
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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
} else {
|
||||
return avatarViewLettersImage(size: size, peerId: peer?.id ?? 1, accountPeerId: accountPeerId ?? 1, letters: peer?.letters ?? [" "])!
|
||||
|
@ -316,7 +316,9 @@ struct WidgetView: View {
|
||||
dateText = ""
|
||||
}
|
||||
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)")
|
||||
}
|
||||
chatTitle = AnyView(Text(formattedName)
|
||||
@ -575,10 +577,15 @@ struct WidgetView: View {
|
||||
content = .placeholder
|
||||
}
|
||||
|
||||
let avatarView: AvatarItemView
|
||||
avatarView = AvatarItemView(peer: peers?.peers[index], itemSize: 54.0, placeholderColor: getPlaceholderColor())
|
||||
|
||||
return AnyView(
|
||||
Link(destination: url, label: {
|
||||
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))
|
||||
})
|
||||
})
|
||||
|
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.
@ -277,7 +277,8 @@ final class WidgetDataContext {
|
||||
autodeleteTimerUpdated: presentationData.strings.Widget_MessageAutoremoveTimerUpdated,
|
||||
autodeleteTimerRemoved: presentationData.strings.Widget_MessageAutoremoveTimerRemoved,
|
||||
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
|
||||
|
@ -300,6 +300,8 @@ public struct WidgetPresentationData: Codable, Equatable {
|
||||
public var generalLockedTitle: String
|
||||
public var generalLockedText: String
|
||||
|
||||
public var chatSavedMessages: String
|
||||
|
||||
public init(
|
||||
widgetChatsGalleryTitle: String,
|
||||
widgetChatsGalleryDescription: String,
|
||||
@ -321,7 +323,8 @@ public struct WidgetPresentationData: Codable, Equatable {
|
||||
autodeleteTimerUpdated: String,
|
||||
autodeleteTimerRemoved: String,
|
||||
generalLockedTitle: String,
|
||||
generalLockedText: String
|
||||
generalLockedText: String,
|
||||
chatSavedMessages: String
|
||||
) {
|
||||
self.widgetChatsGalleryTitle = widgetChatsGalleryTitle
|
||||
self.widgetChatsGalleryDescription = widgetChatsGalleryDescription
|
||||
@ -344,6 +347,7 @@ public struct WidgetPresentationData: Codable, Equatable {
|
||||
self.autodeleteTimerRemoved = autodeleteTimerRemoved
|
||||
self.generalLockedTitle = generalLockedTitle
|
||||
self.generalLockedText = generalLockedText
|
||||
self.chatSavedMessages = chatSavedMessages
|
||||
}
|
||||
|
||||
public static func getForExtension() -> WidgetPresentationData {
|
||||
@ -392,7 +396,8 @@ public extension WidgetPresentationData {
|
||||
autodeleteTimerUpdated: "Auto-delete timer updated",
|
||||
autodeleteTimerRemoved: "Auto-delete timer disabled",
|
||||
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