This commit is contained in:
Ali 2023-07-14 23:31:21 +04:00
parent c2d2da131c
commit 2e09bfe14f
9 changed files with 222 additions and 47 deletions

View File

@ -1069,6 +1069,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return
}
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().start()
let _ = (combineLatest(
ApplicationSpecificNotice.displayChatListArchiveTooltip(accountManager: self.context.sharedContext.accountManager),
self.context.engine.data.get(
@ -3280,6 +3281,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
func openArchiveMoreMenu(sourceView: UIView, gesture: ContextGesture?) {
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().start()
let _ = (
self.context.engine.messages.chatList(group: .archive, count: 10) |> take(1)
|> deliverOnMainQueue).start(next: { [weak self] archiveChatList in

View File

@ -134,6 +134,8 @@ final class ChatListEmptyNode: ASDisplayNode {
self.animationNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.animationTapGesture(_:))))
if case .archive = subject {
let _ = self.context.engine.privacy.updateGlobalPrivacySettings().start()
self.archiveSettingsDisposable = (context.engine.data.subscribe(
TelegramEngine.EngineData.Item.Configuration.GlobalPrivacy()
)

View File

@ -38,6 +38,18 @@ private final class TextNodeEmbeddedItem {
}
}
private final class TextNodeAttachment {
let range: NSRange
let frame: CGRect
let attachment: UIImage
init(range: NSRange, frame: CGRect, attachment: UIImage) {
self.range = range
self.frame = frame
self.attachment = attachment
}
}
public struct TextRangeRectEdge: Equatable {
public var x: CGFloat
public var y: CGFloat
@ -59,8 +71,9 @@ private final class TextNodeLine {
let spoilers: [TextNodeSpoiler]
let spoilerWords: [TextNodeSpoiler]
let embeddedItems: [TextNodeEmbeddedItem]
let attachments: [TextNodeAttachment]
init(line: CTLine, frame: CGRect, range: NSRange, isRTL: Bool, strikethroughs: [TextNodeStrikethrough], spoilers: [TextNodeSpoiler], spoilerWords: [TextNodeSpoiler], embeddedItems: [TextNodeEmbeddedItem]) {
init(line: CTLine, frame: CGRect, range: NSRange, isRTL: Bool, strikethroughs: [TextNodeStrikethrough], spoilers: [TextNodeSpoiler], spoilerWords: [TextNodeSpoiler], embeddedItems: [TextNodeEmbeddedItem], attachments: [TextNodeAttachment]) {
self.line = line
self.frame = frame
self.range = range
@ -69,6 +82,7 @@ private final class TextNodeLine {
self.spoilers = spoilers
self.spoilerWords = spoilerWords
self.embeddedItems = embeddedItems
self.attachments = attachments
}
}
@ -1084,6 +1098,7 @@ open class TextNode: ASDisplayNode {
var spoilers: [TextNodeSpoiler] = []
var spoilerWords: [TextNodeSpoiler] = []
var embeddedItems: [TextNodeEmbeddedItem] = []
var attachments: [TextNodeAttachment] = []
var lineConstrainedWidth = constrainedSize.width
var lineConstrainedWidthDelta: CGFloat = 0.0
@ -1159,6 +1174,24 @@ open class TextNode: ASDisplayNode {
embeddedItems.append(TextNodeEmbeddedItem(range: NSMakeRange(startIndex, endIndex - startIndex + 1), frame: CGRect(x: min(leftOffset, rightOffset), y: descent - (ascent + descent), width: abs(rightOffset - leftOffset) + rightInset, height: ascent + descent), item: item))
}
func addAttachment(attachment: UIImage, line: CTLine, ascent: CGFloat, descent: CGFloat, startIndex: Int, endIndex: Int, rightInset: CGFloat = 0.0) {
var secondaryLeftOffset: CGFloat = 0.0
let rawLeftOffset = CTLineGetOffsetForStringIndex(line, startIndex, &secondaryLeftOffset)
var leftOffset = floor(rawLeftOffset)
if !rawLeftOffset.isEqual(to: secondaryLeftOffset) {
leftOffset = floor(secondaryLeftOffset)
}
var secondaryRightOffset: CGFloat = 0.0
let rawRightOffset = CTLineGetOffsetForStringIndex(line, endIndex, &secondaryRightOffset)
var rightOffset = ceil(rawRightOffset)
if !rawRightOffset.isEqual(to: secondaryRightOffset) {
rightOffset = ceil(secondaryRightOffset)
}
attachments.append(TextNodeAttachment(range: NSMakeRange(startIndex, endIndex - startIndex), frame: CGRect(x: min(leftOffset, rightOffset), y: descent - (ascent + descent), width: abs(rightOffset - leftOffset) + rightInset, height: ascent + descent), attachment: attachment))
}
var isLastLine = false
if maximumNumberOfLines != 0 && lines.count == maximumNumberOfLines - 1 && lineCharacterCount > 0 {
isLastLine = true
@ -1307,6 +1340,14 @@ open class TextNode: ASDisplayNode {
addEmbeddedItem(item: embeddedItem, line: coreTextLine, ascent: ascent, descent: descent, startIndex: range.location, endIndex: range.location + range.length)
}
}
if let attachment = attributes[NSAttributedString.Key.attachment] as? UIImage {
var ascent: CGFloat = 0.0
var descent: CGFloat = 0.0
CTLineGetTypographicBounds(coreTextLine, &ascent, &descent, nil)
addAttachment(attachment: attachment, line: coreTextLine, ascent: ascent, descent: descent, startIndex: range.location, endIndex: range.location + range.length)
}
}
}
@ -1328,7 +1369,7 @@ open class TextNode: ASDisplayNode {
}
}
lines.append(TextNodeLine(line: coreTextLine, frame: lineFrame, range: NSMakeRange(lineRange.location, lineRange.length), isRTL: isRTL, strikethroughs: strikethroughs, spoilers: spoilers, spoilerWords: spoilerWords, embeddedItems: embeddedItems))
lines.append(TextNodeLine(line: coreTextLine, frame: lineFrame, range: NSMakeRange(lineRange.location, lineRange.length), isRTL: isRTL, strikethroughs: strikethroughs, spoilers: spoilers, spoilerWords: spoilerWords, embeddedItems: embeddedItems, attachments: attachments))
break
} else {
if lineCharacterCount > 0 {
@ -1398,6 +1439,14 @@ open class TextNode: ASDisplayNode {
addEmbeddedItem(item: embeddedItem, line: coreTextLine, ascent: ascent, descent: descent, startIndex: range.location, endIndex: range.location + range.length)
}
}
if let attachment = attributes[NSAttributedString.Key.attachment] as? UIImage {
var ascent: CGFloat = 0.0
var descent: CGFloat = 0.0
CTLineGetTypographicBounds(coreTextLine, &ascent, &descent, nil)
addAttachment(attachment: attachment, line: coreTextLine, ascent: ascent, descent: descent, startIndex: range.location, endIndex: range.location + range.length)
}
}
let lineWidth = ceil(CGFloat(CTLineGetTypographicBounds(coreTextLine, nil, nil, nil) - CTLineGetTrailingWhitespaceWidth(coreTextLine)))
@ -1418,7 +1467,7 @@ open class TextNode: ASDisplayNode {
}
}
lines.append(TextNodeLine(line: coreTextLine, frame: lineFrame, range: NSMakeRange(lineRange.location, lineRange.length), isRTL: isRTL, strikethroughs: strikethroughs, spoilers: spoilers, spoilerWords: spoilerWords, embeddedItems: embeddedItems))
lines.append(TextNodeLine(line: coreTextLine, frame: lineFrame, range: NSMakeRange(lineRange.location, lineRange.length), isRTL: isRTL, strikethroughs: strikethroughs, spoilers: spoilers, spoilerWords: spoilerWords, embeddedItems: embeddedItems, attachments: attachments))
} else {
if !lines.isEmpty {
layoutSize.height += fontLineSpacing
@ -1854,6 +1903,7 @@ open class TextView: UIView {
var strikethroughs: [TextNodeStrikethrough] = []
var spoilers: [TextNodeSpoiler] = []
var spoilerWords: [TextNodeSpoiler] = []
var attachments: [TextNodeAttachment] = []
var lineConstrainedWidth = constrainedSize.width
var lineConstrainedWidthDelta: CGFloat = 0.0
@ -1911,6 +1961,24 @@ open class TextView: UIView {
spoilerWords.append(TextNodeSpoiler(range: NSMakeRange(startIndex, endIndex - startIndex + 1), frame: CGRect(x: min(leftOffset, rightOffset), y: descent - (ascent + descent), width: abs(rightOffset - leftOffset) + rightInset, height: ascent + descent)))
}
func addAttachment(attachment: UIImage, line: CTLine, ascent: CGFloat, descent: CGFloat, startIndex: Int, endIndex: Int, rightInset: CGFloat = 0.0) {
var secondaryLeftOffset: CGFloat = 0.0
let rawLeftOffset = CTLineGetOffsetForStringIndex(line, startIndex, &secondaryLeftOffset)
var leftOffset = floor(rawLeftOffset)
if !rawLeftOffset.isEqual(to: secondaryLeftOffset) {
leftOffset = floor(secondaryLeftOffset)
}
var secondaryRightOffset: CGFloat = 0.0
let rawRightOffset = CTLineGetOffsetForStringIndex(line, endIndex, &secondaryRightOffset)
var rightOffset = ceil(rawRightOffset)
if !rawRightOffset.isEqual(to: secondaryRightOffset) {
rightOffset = ceil(secondaryRightOffset)
}
attachments.append(TextNodeAttachment(range: NSMakeRange(startIndex, endIndex - startIndex), frame: CGRect(x: min(leftOffset, rightOffset), y: descent - (ascent + descent), width: abs(rightOffset - leftOffset) + rightInset, height: ascent + descent), attachment: attachment))
}
var isLastLine = false
if maximumNumberOfLines != 0 && lines.count == maximumNumberOfLines - 1 && lineCharacterCount > 0 {
isLastLine = true
@ -2006,7 +2074,14 @@ open class TextView: UIView {
strikethroughs.append(TextNodeStrikethrough(range: range, frame: CGRect(x: x, y: 0.0, width: abs(upperX - lowerX), height: fontLineHeight)))
} else if let paragraphStyle = attributes[NSAttributedString.Key.paragraphStyle] as? NSParagraphStyle {
headIndent = paragraphStyle.headIndent
}
if let attachment = attributes[NSAttributedString.Key.attachment] as? UIImage {
var ascent: CGFloat = 0.0
var descent: CGFloat = 0.0
CTLineGetTypographicBounds(coreTextLine, &ascent, &descent, nil)
addAttachment(attachment: attachment, line: coreTextLine, ascent: ascent, descent: descent, startIndex: range.location, endIndex: range.location + range.length)
}
}
}
@ -2029,7 +2104,7 @@ open class TextView: UIView {
}
}
lines.append(TextNodeLine(line: coreTextLine, frame: lineFrame, range: NSMakeRange(lineRange.location, lineRange.length), isRTL: isRTL, strikethroughs: strikethroughs, spoilers: spoilers, spoilerWords: spoilerWords, embeddedItems: []))
lines.append(TextNodeLine(line: coreTextLine, frame: lineFrame, range: NSMakeRange(lineRange.location, lineRange.length), isRTL: isRTL, strikethroughs: strikethroughs, spoilers: spoilers, spoilerWords: spoilerWords, embeddedItems: [], attachments: attachments))
break
} else {
if lineCharacterCount > 0 {
@ -2089,6 +2164,14 @@ open class TextView: UIView {
} else if let paragraphStyle = attributes[NSAttributedString.Key.paragraphStyle] as? NSParagraphStyle {
headIndent = paragraphStyle.headIndent
}
if let attachment = attributes[NSAttributedString.Key.attachment] as? UIImage {
var ascent: CGFloat = 0.0
var descent: CGFloat = 0.0
CTLineGetTypographicBounds(coreTextLine, &ascent, &descent, nil)
addAttachment(attachment: attachment, line: coreTextLine, ascent: ascent, descent: descent, startIndex: range.location, endIndex: range.location + range.length)
}
}
let lineWidth = ceil(CGFloat(CTLineGetTypographicBounds(coreTextLine, nil, nil, nil) - CTLineGetTrailingWhitespaceWidth(coreTextLine)))
@ -2109,7 +2192,7 @@ open class TextView: UIView {
}
}
lines.append(TextNodeLine(line: coreTextLine, frame: lineFrame, range: NSMakeRange(lineRange.location, lineRange.length), isRTL: isRTL, strikethroughs: strikethroughs, spoilers: spoilers, spoilerWords: spoilerWords, embeddedItems: []))
lines.append(TextNodeLine(line: coreTextLine, frame: lineFrame, range: NSMakeRange(lineRange.location, lineRange.length), isRTL: isRTL, strikethroughs: strikethroughs, spoilers: spoilers, spoilerWords: spoilerWords, embeddedItems: [], attachments: attachments))
} else {
if !lines.isEmpty {
layoutSize.height += fontLineSpacing
@ -2229,30 +2312,47 @@ open class TextView: UIView {
context.clip(to: clipRects)
}
let glyphRuns = CTLineGetGlyphRuns(line.line) as NSArray
if glyphRuns.count != 0 {
for run in glyphRuns {
let run = run as! CTRun
let glyphCount = CTRunGetGlyphCount(run)
CTRunDraw(run, context, CFRangeMake(0, glyphCount))
if line.attachments.isEmpty {
let glyphRuns = CTLineGetGlyphRuns(line.line) as NSArray
if glyphRuns.count != 0 {
for run in glyphRuns {
let run = run as! CTRun
let glyphCount = CTRunGetGlyphCount(run)
CTRunDraw(run, context, CFRangeMake(0, glyphCount))
}
}
} else {
let glyphRuns = CTLineGetGlyphRuns(line.line) as NSArray
if glyphRuns.count != 0 {
for run in glyphRuns {
let run = run as! CTRun
let stringRange = CTRunGetStringRange(run)
if line.attachments.contains(where: { $0.range.contains(stringRange.location) }) {
continue
}
let glyphCount = CTRunGetGlyphCount(run)
CTRunDraw(run, context, CFRangeMake(0, glyphCount))
}
}
}
// if !line.strikethroughs.isEmpty {
// for strikethrough in line.strikethroughs {
// var textColor: UIColor?
// layout.attributedString?.enumerateAttributes(in: NSMakeRange(line.range.location, line.range.length), options: []) { attributes, range, _ in
// if range == strikethrough.range, let color = attributes[NSAttributedString.Key.foregroundColor] as? UIColor {
// textColor = color
// }
// }
// if let textColor = textColor {
// context.setFillColor(textColor.cgColor)
// }
// let frame = strikethrough.frame.offsetBy(dx: lineFrame.minX, dy: lineFrame.minY)
// context.fill(CGRect(x: frame.minX, y: frame.minY - 5.0, width: frame.width, height: 1.0))
// }
// }
for attachment in line.attachments {
let image = attachment.attachment
var textColor: UIColor?
layout.attributedString?.enumerateAttributes(in: attachment.range, options: []) { attributes, range, _ in
if let color = attributes[NSAttributedString.Key.foregroundColor] as? UIColor {
textColor = color
}
}
if let textColor {
if let tintedImage = generateTintedImage(image: image, color: textColor) {
let imageRect = CGRect(origin: CGPoint(x: attachment.frame.midX - tintedImage.size.width * 0.5, y: attachment.frame.midY - tintedImage.size.height * 0.5 + 1.0), size: tintedImage.size).offsetBy(dx: lineFrame.minX, dy: lineFrame.minY)
context.draw(tintedImage.cgImage!, in: imageRect)
}
}
}
if !line.spoilers.isEmpty {
if layout.displaySpoilers {

View File

@ -25,6 +25,10 @@ public extension TelegramEngine {
return _internal_requestAccountPrivacySettings(account: self.account)
}
public func updateGlobalPrivacySettings() -> Signal<Never, NoError> {
return _internal_updateGlobalPrivacySettings(account: self.account)
}
public func updateAccountAutoArchiveChats(value: Bool) -> Signal<Never, NoError> {
return _internal_updateAccountAutoArchiveChats(account: self.account, value: value)
}

View File

@ -3,6 +3,36 @@ import Postbox
import TelegramApi
import SwiftSignalKit
func _internal_updateGlobalPrivacySettings(account: Account) -> Signal<Never, NoError> {
return account.network.request(Api.functions.account.getGlobalPrivacySettings())
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.GlobalPrivacySettings?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<Never, NoError> in
return account.postbox.transaction { transaction -> Void in
guard let result = result else {
return
}
let globalSettings: GlobalPrivacySettings
switch result {
case let .globalPrivacySettings(flags):
let automaticallyArchiveAndMuteNonContacts = (flags & (1 << 0)) != 0
let keepArchivedUnmuted = (flags & (1 << 1)) != 0
let keepArchivedFolders = (flags & (1 << 2)) != 0
globalSettings = GlobalPrivacySettings(
automaticallyArchiveAndMuteNonContacts: automaticallyArchiveAndMuteNonContacts,
keepArchivedUnmuted: keepArchivedUnmuted,
keepArchivedFolders: keepArchivedFolders
)
}
updateGlobalPrivacySettings(transaction: transaction, { _ in
return globalSettings
})
}
|> ignoreValues
}
}
func _internal_requestAccountPrivacySettings(account: Account) -> Signal<AccountPrivacySettings, NoError> {
let lastSeenPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyStatusTimestamp))

View File

@ -57,6 +57,8 @@ public final class ArchiveInfoContentComponent: Component {
private let title = ComponentView<Empty>()
private let mainText = ComponentView<Empty>()
private var chevronImage: UIImage?
private var items: [Item] = []
private var component: ArchiveInfoContentComponent?
@ -151,34 +153,43 @@ public final class ArchiveInfoContentComponent: Component {
contentHeight += 16.0
let text: String
//TODO:localize
if component.settings.keepArchivedUnmuted {
text = "Archived chats will remain in the Archive when you receive a new message. [Tap to change ]()"
text = "Archived chats will remain in the Archive when you receive a new message. [Tap to change >]()"
} else {
text = "When you receive a new message, muted chats will remain in the Archive, while unmuted chats will be moved to Chats. [Tap to change 〉]()"
text = "When you receive a new message, muted chats will remain in the Archive, while unmuted chats will be moved to Chats. [Tap to change >]()"
}
let mainText = NSMutableAttributedString()
mainText.append(parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(
body: MarkdownAttributeSet(
font: Font.regular(15.0),
textColor: component.theme.list.itemSecondaryTextColor
),
bold: MarkdownAttributeSet(
font: Font.semibold(15.0),
textColor: component.theme.list.itemSecondaryTextColor
),
link: MarkdownAttributeSet(
font: Font.regular(15.0),
textColor: component.theme.list.itemAccentColor,
additionalAttributes: [:]
),
linkAttribute: { attributes in
return ("URL", "")
}
)))
if self.chevronImage == nil {
self.chevronImage = UIImage(bundleImageName: "Settings/TextArrowRight")
}
if let range = mainText.string.range(of: ">"), let chevronImage = self.chevronImage {
mainText.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: mainText.string))
}
//TODO:localize
let mainTextSize = self.mainText.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .markdown(text: text, attributes: MarkdownAttributes(
body: MarkdownAttributeSet(
font: Font.regular(15.0),
textColor: component.theme.list.itemSecondaryTextColor
),
bold: MarkdownAttributeSet(
font: Font.semibold(15.0),
textColor: component.theme.list.itemSecondaryTextColor
),
link: MarkdownAttributeSet(
font: Font.regular(15.0),
textColor: component.theme.list.itemAccentColor,
additionalAttributes: [:]
),
linkAttribute: { attributes in
return ("URL", "")
}
)),
text: .plain(mainText),
horizontalAlignment: .center,
maximumNumberOfLines: 0,
lineSpacing: 0.2,

View File

@ -815,6 +815,8 @@ public final class StoryPeerListItemComponent: Component {
self?.indicatorShapeSeenLayer.lineWidth = initialLineWidth
self?.indicatorShapeSeenLayer.animateShapeLineWidth(from: targetLineWidth, to: initialLineWidth, duration: 0.15)
})
HapticFeedback().success()
}
let titleSize = self.title.update(

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "chevron.right.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 232.5-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="7.16309" height="12.7222">
<g>
<rect height="12.7222" opacity="0" width="7.16309" x="0" y="0"/>
<path d="M7.16309 6.35742C7.16309 6.17432 7.08984 6.00586 6.95068 5.87402L1.1499 0.19043C1.01807 0.065918 0.856934 0 0.666504 0C0.292969 0 0 0.285645 0 0.666504C0 0.849609 0.0732422 1.01807 0.19043 1.14258L5.52246 6.35742L0.19043 11.5723C0.0732422 11.6968 0 11.8579 0 12.0483C0 12.4292 0.292969 12.7148 0.666504 12.7148C0.856934 12.7148 1.01807 12.6489 1.1499 12.5171L6.95068 6.84082C7.08984 6.70166 7.16309 6.54053 7.16309 6.35742Z" fill="#ffffff" fill-opacity="0.85"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 879 B