mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-29 19:35:08 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
3bacb78f08
@ -463,12 +463,12 @@ NSString *suffix = @"";
|
||||
#if TARGET_OS_OSX
|
||||
NSString *value = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"SOURCE"];
|
||||
if (value != nil) {
|
||||
suffix = [NSString stringWithFormat:@"%@ ", value];
|
||||
suffix = [NSString stringWithFormat:@"%@", value];
|
||||
}
|
||||
#endif
|
||||
|
||||
//SOURCE
|
||||
NSString *versionString = [[NSString alloc] initWithFormat:@"%@ (%@)%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"], suffix];
|
||||
NSString *versionString = [[NSString alloc] initWithFormat:@"%@ (%@) %@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"], suffix];
|
||||
_appVersion = versionString;
|
||||
|
||||
_systemLangCode = [[NSLocale preferredLanguages] objectAtIndex:0];
|
||||
|
||||
@ -110,6 +110,9 @@ class MessageHistoryTagsSummaryTable: Table {
|
||||
|
||||
private func set(_ key: MessageHistoryTagsSummaryKey, summary: MessageHistoryTagNamespaceSummary, updatedSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary]) {
|
||||
if self.get(key) != summary {
|
||||
if key.tag.rawValue == 2048 {
|
||||
postboxLog("[MessageHistoryTagsSummaryTable] set \(key.tag.rawValue) for \(key.peerId) to \(summary.count)")
|
||||
}
|
||||
self.updatedKeys.insert(key)
|
||||
self.cachedSummaries[key] = CachedEntry(summary: summary)
|
||||
updatedSummaries[key] = summary
|
||||
|
||||
@ -54,10 +54,11 @@ private func updatePremiumPromoConfiguration(transaction: Transaction, _ f: (Pre
|
||||
private extension PremiumPromoConfiguration {
|
||||
init(apiPremiumPromo: Api.help.PremiumPromo) {
|
||||
switch apiPremiumPromo {
|
||||
case let .premiumPromo(statusText, statusEntities, videoSections, videoFiles, _, _):
|
||||
case let .premiumPromo(statusText, statusEntities, videoSections, videoFiles, currency, monthlyAmount):
|
||||
self.status = statusText
|
||||
self.statusEntities = messageTextEntitiesFromApiEntities(statusEntities)
|
||||
|
||||
self.currency = currency
|
||||
self.monthlyAmount = monthlyAmount
|
||||
var videos: [String: TelegramMediaFile] = [:]
|
||||
for (key, document) in zip(videoSections, videoFiles) {
|
||||
if let file = telegramMediaFileFromApiDocument(document) {
|
||||
|
||||
@ -232,7 +232,7 @@ private enum PreferencesKeyValues: Int32 {
|
||||
case chatListFiltersFeaturedState = 22
|
||||
case secretChatSettings = 23
|
||||
case reactionSettings = 24
|
||||
case premiumPromo = 25
|
||||
case premiumPromo = 26
|
||||
}
|
||||
|
||||
public func applicationSpecificPreferencesKey(_ value: Int32) -> ValueBoxKey {
|
||||
|
||||
@ -4,6 +4,8 @@ import Postbox
|
||||
public struct PremiumPromoConfiguration: Codable, Equatable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case status
|
||||
case currency
|
||||
case monthlyAmount
|
||||
case statusEntities
|
||||
case videos
|
||||
}
|
||||
@ -36,12 +38,17 @@ public struct PremiumPromoConfiguration: Codable, Equatable {
|
||||
public var statusEntities: [MessageTextEntity]
|
||||
public var videos: [String: TelegramMediaFile]
|
||||
|
||||
public var currency: String
|
||||
public var monthlyAmount: Int64
|
||||
|
||||
public static var defaultValue: PremiumPromoConfiguration {
|
||||
return PremiumPromoConfiguration(status: "", statusEntities: [], videos: [:])
|
||||
return PremiumPromoConfiguration(status: "", statusEntities: [], videos: [:], currency: "", monthlyAmount: 0)
|
||||
}
|
||||
|
||||
init(status: String, statusEntities: [MessageTextEntity], videos: [String: TelegramMediaFile]) {
|
||||
init(status: String, statusEntities: [MessageTextEntity], videos: [String: TelegramMediaFile], currency: String, monthlyAmount: Int64) {
|
||||
self.status = status
|
||||
self.currency = currency
|
||||
self.monthlyAmount = monthlyAmount
|
||||
self.statusEntities = statusEntities
|
||||
self.videos = videos
|
||||
}
|
||||
@ -58,6 +65,10 @@ public struct PremiumPromoConfiguration: Codable, Equatable {
|
||||
videos[pair.key] = pair.value
|
||||
}
|
||||
self.videos = videos
|
||||
|
||||
self.currency = try container.decode(String.self, forKey: .currency)
|
||||
self.monthlyAmount = try container.decode(Int64.self, forKey: .monthlyAmount)
|
||||
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -65,6 +76,8 @@ public struct PremiumPromoConfiguration: Codable, Equatable {
|
||||
|
||||
try container.encode(self.status, forKey: .status)
|
||||
try container.encode(self.statusEntities, forKey: .statusEntities)
|
||||
try container.encode(self.currency, forKey: .currency)
|
||||
try container.encode(self.monthlyAmount, forKey: .monthlyAmount)
|
||||
|
||||
var pairs: [DictionaryPair] = []
|
||||
for (key, file) in self.videos {
|
||||
|
||||
@ -499,6 +499,15 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
||||
return false
|
||||
}
|
||||
|
||||
public var noPremium: Bool {
|
||||
for attribute in self.attributes {
|
||||
if case .NoPremium = attribute {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public var premiumEffect: TelegramMediaFile.VideoThumbnail? {
|
||||
if let effect = self.videoThumbnails.first(where: { thumbnail in
|
||||
if let resource = thumbnail.resource as? CloudDocumentSizeMediaResource, resource.sizeSpec == "f" {
|
||||
|
||||
@ -155,11 +155,35 @@ public extension TelegramEngine {
|
||||
}
|
||||
|
||||
public func earliestUnseenPersonalMentionMessage(peerId: PeerId) -> Signal<EarliestUnseenPersonalMentionMessageResult, NoError> {
|
||||
let account = self.account
|
||||
return _internal_earliestUnseenPersonalMentionMessage(account: self.account, peerId: peerId)
|
||||
|> mapToSignal { result -> Signal<EarliestUnseenPersonalMentionMessageResult, NoError> in
|
||||
switch result {
|
||||
case .loading:
|
||||
return .single(result)
|
||||
case let .result(messageId):
|
||||
if messageId == nil {
|
||||
let _ = clearPeerUnseenPersonalMessagesInteractively(account: account, peerId: peerId).start()
|
||||
}
|
||||
return .single(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func earliestUnseenPersonalReactionMessage(peerId: PeerId) -> Signal<EarliestUnseenPersonalMentionMessageResult, NoError> {
|
||||
let account = self.account
|
||||
return _internal_earliestUnseenPersonalReactionMessage(account: self.account, peerId: peerId)
|
||||
|> mapToSignal { result -> Signal<EarliestUnseenPersonalMentionMessageResult, NoError> in
|
||||
switch result {
|
||||
case .loading:
|
||||
return .single(result)
|
||||
case let .result(messageId):
|
||||
if messageId == nil {
|
||||
let _ = clearPeerUnseenReactionsInteractively(account: account, peerId: peerId).start()
|
||||
}
|
||||
return .single(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func exportMessageLink(peerId: PeerId, messageId: MessageId, isThread: Bool = false) -> Signal<String?, NoError> {
|
||||
|
||||
@ -13,6 +13,7 @@ swift_library(
|
||||
"//submodules/ComponentFlow:ComponentFlow",
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/Display:Display",
|
||||
"//submodules/Components/LottieAnimationComponent:LottieAnimationComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
@ -3,6 +3,7 @@ import UIKit
|
||||
import ComponentFlow
|
||||
import AppBundle
|
||||
import Display
|
||||
import LottieAnimationComponent
|
||||
|
||||
public final class AudioTranscriptionPendingIndicatorComponent: Component {
|
||||
public let color: UIColor
|
||||
@ -98,3 +99,80 @@ public final class AudioTranscriptionPendingIndicatorComponent: Component {
|
||||
return view.update(component: self, availableSize: availableSize, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
public final class AudioTranscriptionPendingLottieIndicatorComponent: Component {
|
||||
public let color: UIColor
|
||||
public let font: UIFont
|
||||
|
||||
public init(color: UIColor, font: UIFont) {
|
||||
self.color = color
|
||||
self.font = font
|
||||
}
|
||||
|
||||
public static func ==(lhs: AudioTranscriptionPendingLottieIndicatorComponent, rhs: AudioTranscriptionPendingLottieIndicatorComponent) -> Bool {
|
||||
if lhs.color != rhs.color {
|
||||
return false
|
||||
}
|
||||
if lhs.font != rhs.font {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public final class View: UIView {
|
||||
private let animationView: ComponentHostView<Empty>
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.animationView = ComponentHostView<Empty>()
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.addSubview(self.animationView)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func update(component: AudioTranscriptionPendingLottieIndicatorComponent, availableSize: CGSize, transition: Transition) -> CGSize {
|
||||
let originalSize = CGSize(width: 48.0, height: 66.0)
|
||||
let animationSize = originalSize.aspectFitted(CGSize(width: 15.0, height: 100.0))
|
||||
let _ = self.animationView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(LottieAnimationComponent(
|
||||
animation: LottieAnimationComponent.AnimationItem(
|
||||
name: "animated_text_dots",
|
||||
colors: [
|
||||
"Comp 1.Point 3.Group 1.Fill 1": component.color,
|
||||
"Comp 1.Point 2.Group 1.Fill 1": component.color,
|
||||
"Comp 1.Point 1.Group 1.Fill 1": component.color
|
||||
],
|
||||
mode: .animating(loop: true)
|
||||
),
|
||||
size: animationSize
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: animationSize
|
||||
)
|
||||
|
||||
var stringSize = NSAttributedString(string: "...", font: component.font, textColor: .black).boundingRect(with: CGSize(width: 100.0, height: 100.0), options: .usesLineFragmentOrigin, context: nil).size
|
||||
stringSize.width = ceil(stringSize.width)
|
||||
stringSize.height = ceil(stringSize.height)
|
||||
|
||||
let size = CGSize(width: min(availableSize.width, stringSize.width), height: min(availableSize.height, 10.0))
|
||||
|
||||
self.animationView.frame = CGRect(origin: CGPoint(x: -2.0, y: size.height - animationSize.height + 4.0 + UIScreenPixel), size: animationSize)
|
||||
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
public func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
{"v":"5.8.1","fr":60,"ip":0,"op":60,"w":48,"h":66,"nm":"Comp 2","ddd":0,"assets":[{"id":"comp_0","nm":"Comp 1","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Point 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.7,"y":1},"o":{"x":0.7,"y":0},"t":12,"s":[118.6,256,0],"to":[-0.6,-119,0],"ti":[-1.438,-92.469,0]},{"i":{"x":0.4,"y":1},"o":{"x":0.32,"y":0},"t":32,"s":[255.938,275.469,0],"to":[0,0,0],"ti":[0,0,0]},{"t":42,"s":[255.938,255.969,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-102.4,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-17.673,0],[0,-17.673],[17.673,0],[0,17.673]],"o":[[17.673,0],[0,17.673],[-17.673,0],[0,-17.673]],"v":[[-102.4,-32],[-70.4,0],[-102.4,32],[-134.4,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Point 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.7,"y":1},"o":{"x":0.7,"y":0},"t":0,"s":[256,256,0],"to":[1.75,-110,0],"ti":[-5.25,-93.219,0]},{"i":{"x":0.42,"y":1},"o":{"x":0.3,"y":0},"t":20,"s":[393.25,276.969,0],"to":[0,0,0],"ti":[0,0,0]},{"t":30,"s":[393.25,255.969,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-17.673,0],[0,-17.673],[17.673,0],[0,17.673]],"o":[[17.673,0],[0,17.673],[-17.673,0],[0,-17.673]],"v":[[0,-32],[32,0],[0,32],[-32,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Point 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.4,"y":1},"o":{"x":0.3,"y":0},"t":0,"s":[393.4,256,0],"to":[0,0,0],"ti":[0,0,0]},{"t":40,"s":[118.562,255.969,0]}],"ix":2,"l":2},"a":{"a":0,"k":[102.4,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-17.673,0],[0,-17.673],[17.673,0],[0,17.673]],"o":[[17.673,0],[0,17.673],[-17.673,0],[0,-17.673]],"v":[[102.4,-32],[134.4,0],[102.4,32],[70.4,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Comp 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[24,48,0],"ix":2,"l":2},"a":{"a":0,"k":[256,256,0],"ix":1,"l":2},"s":{"a":0,"k":[10.8,10.8,100],"ix":6,"l":2}},"ao":0,"w":512,"h":512,"ip":0,"op":180,"st":0,"bm":0}],"markers":[]}
|
||||
@ -659,12 +659,12 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
case let .success(text, isPending):
|
||||
textString = NSAttributedString(string: text, font: textFont, textColor: messageTheme.primaryTextColor)
|
||||
|
||||
/*#if DEBUG
|
||||
#if DEBUG
|
||||
var isPending = isPending
|
||||
if "".isEmpty {
|
||||
isPending = true
|
||||
}
|
||||
#endif*/
|
||||
#endif
|
||||
|
||||
if isPending {
|
||||
let modifiedString = NSMutableAttributedString(attributedString: textString!)
|
||||
@ -1027,9 +1027,14 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
strongSelf.transcriptionPendingIndicator = transcriptionPendingIndicator
|
||||
strongSelf.textClippingNode.view.addSubview(transcriptionPendingIndicator)
|
||||
}
|
||||
|
||||
let indicatorComponent: AnyComponent<Empty>
|
||||
indicatorComponent = AnyComponent(AudioTranscriptionPendingLottieIndicatorComponent(color: messageTheme.primaryTextColor, font: textFont))
|
||||
//indicatorComponent = AnyComponent(AudioTranscriptionPendingIndicatorComponent(color: messageTheme.primaryTextColor, font: textFont))
|
||||
|
||||
let indicatorSize = transcriptionPendingIndicator.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(AudioTranscriptionPendingIndicatorComponent(color: messageTheme.primaryTextColor, font: textFont)),
|
||||
component: indicatorComponent,
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 100.0, height: 100.0)
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user