Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2021-02-12 17:24:29 +04:00
commit 41ea1fb330
14 changed files with 131 additions and 88 deletions

View File

@ -6045,9 +6045,9 @@ Sorry for the inconvenience.";
"Report.Report" = "Report";
"Report.Succeed" = "Telegram moderators will study your report. Thank you!";
"Conversation.AutoremoveRemainingTime" = "auto-delete in %@";
"Conversation.AutoremoveRemainingDays_1" = "auto-delete in %@ day";
"Conversation.AutoremoveRemainingDays_any" = "auto-delete in %@ days";
"Conversation.AutoremoveRemainingTime" = "auto-deletes in %@";
"Conversation.AutoremoveRemainingDays_1" = "auto-deletes in %@ day";
"Conversation.AutoremoveRemainingDays_any" = "auto-deletes in %@ days";
"PeerInfo.AutoremoveMessages" = "Auto-Delete Messages";
"PeerInfo.AutoremoveMessagesDisabled" = "Never";

View File

@ -316,6 +316,7 @@ extension PeersWidgetData {
struct AvatarItemView: View {
var peer: ParsedPeer?
var itemSize: CGFloat
var placeholderColor: Color
var displayBadge: Bool = true
var body: some View {
@ -324,11 +325,12 @@ struct AvatarItemView: View {
Image(uiImage: avatarImage(accountPeerId: peer.accountPeerId, peer: peer.peer, size: CGSize(width: itemSize, height: itemSize)))
.clipShape(Circle())
} else {
Image(uiImage: avatarImage(accountPeerId: nil, peer: nil, size: CGSize(width: itemSize, height: itemSize)))
//Rectangle()
.frame(width: itemSize, height: itemSize)
.clipShape(Circle())
.redacted(reason: .placeholder)
Circle()
.fill(placeholderColor)
.frame(width: itemSize, height: itemSize)
//Image(uiImage: avatarImage(accountPeerId: nil, peer: nil, size: CGSize(width: itemSize, height: itemSize)))
//.clipShape(Circle())
//.redacted(reason: .placeholder)
}
/*if let peer = peer, displayBadge, let badge = peer.badge, badge.count > 0 {
Text("\(badge.count)")
@ -430,7 +432,8 @@ struct WidgetView: View {
Link(destination: URL(string: linkForPeer(accountId: peers.peers[i].accountId, id: peers.peers[i].peer.id))!, label: {
AvatarItemView(
peer: peers.peers[i],
itemSize: itemSize
itemSize: itemSize,
placeholderColor: getPlaceholderColor()
).frame(width: itemSize, height: itemSize)
}).frame(width: itemSize, height: itemSize)
.position(x: floor(horizontalInsetFraction * geometry.size.width + itemSize / 2.0 + CGFloat(i % columnCount) * (itemSize + horizontalSpacingFraction * geometry.size.width)), y: floor(verticalInsetFraction * geometry.size.height + itemSize / 2.0 + CGFloat(i / columnCount) * (itemSize + verticalSpacingFraction * geometry.size.height)))
@ -461,7 +464,7 @@ struct WidgetView: View {
func chatTopLine(_ peer: ParsedPeer?) -> some View {
let dateText: String
let chatTitle: Text
let chatTitle: AnyView
let date: Text
if let peer = peer {
@ -470,26 +473,44 @@ struct WidgetView: View {
} else {
dateText = ""
}
chatTitle = Text(peer.peer.name).font(Font.system(size: 16.0, weight: .medium, design: .default)).foregroundColor(.primary)
chatTitle = AnyView(Text(peer.peer.name)
.lineLimit(1)
.font(Font.system(size: 16.0, weight: .medium, design: .default))
.foregroundColor(.primary))
date = Text(dateText)
.font(Font.system(size: 14.0, weight: .regular, design: .default)).foregroundColor(.secondary)
} else {
dateText = "10:00"
chatTitle = Text("Chat Title").font(Font.system(size: 16.0, weight: .medium, design: .default)).foregroundColor(.primary)
dateText = " "
chatTitle = AnyView(Text(" ").font(Font.system(size: 16.0, weight: .medium, design: .default)).foregroundColor(.primary))
date = Text(dateText)
.font(Font.system(size: 14.0, weight: .regular, design: .default)).foregroundColor(.secondary)
.font(Font.system(size: 16.0, weight: .regular, design: .default)).foregroundColor(.secondary)
}
return HStack(alignment: .center, spacing: 0.0, content: {
if peer != nil {
chatTitle
} else {
chatTitle.redacted(reason: .placeholder)
chatTitle
.frame(minWidth: 48.0)
.background(GeometryReader { geometry in
RoundedRectangle(cornerRadius: 4.0)
.fill(getPlaceholderColor())
.frame(width: geometry.size.width, height: 8.0, alignment: .center)
.offset(x: 0.0, y: (geometry.size.height - 8.0) / 2.0 + 1.0)
}
)
}
Spacer()
if peer != nil {
date
} else {
date.redacted(reason: .placeholder)
date
.background(GeometryReader { geometry in
RoundedRectangle(cornerRadius: 4.0)
.fill(getPlaceholderColor())
.frame(width: geometry.size.width, height: 8.0, alignment: .center)
.offset(x: 0.0, y: (geometry.size.height - 8.0) / 2.0)
}
)
}
})
.padding(0.0)
@ -580,15 +601,42 @@ struct WidgetView: View {
.foregroundColor(.secondary)
.multilineTextAlignment(.leading)
.padding(0.0)
//.frame(maxHeight: .infinity, alignment: .topLeading)
//.background(Rectangle().foregroundColor(.gray))
if peer != nil {
return AnyView(textView)
} else {
return AnyView(
textView
.redacted(reason: .placeholder)
VStack(alignment: .leading, spacing: 0.0, content: {
Text(" ")
.lineLimit(1)
.font(Font.system(size: 15.0, weight: .regular, design: .default))
.foregroundColor(.secondary)
.multilineTextAlignment(.leading)
.padding(0.0)
.frame(minWidth: 182.0)
.background(GeometryReader { geometry in
RoundedRectangle(cornerRadius: 4.0)
.fill(getPlaceholderColor())
.frame(width: geometry.size.width, height: 8.0, alignment: .center)
.offset(x: 0.0, y: (geometry.size.height - 8.0) / 2.0 - 1.0)
}
)
Text(" ")
.lineLimit(1)
.font(Font.system(size: 15.0, weight: .regular, design: .default))
.foregroundColor(.secondary)
.multilineTextAlignment(.leading)
.padding(0.0)
.frame(minWidth: 96.0)
.background(GeometryReader { geometry in
RoundedRectangle(cornerRadius: 4.0)
.fill(getPlaceholderColor())
.frame(width: geometry.size.width, height: 8.0, alignment: .center)
.offset(x: 0.0, y: (geometry.size.height - 8.0) / 2.0 - 1.0)
}
)
})
//textView.redacted(reason: .placeholder)
)
}
@ -658,7 +706,7 @@ struct WidgetView: View {
return AnyView(
Link(destination: url, label: {
HStack(alignment: .center, spacing: 0.0, content: {
AvatarItemView(peer: peers?.peers[index], itemSize: 54.0, displayBadge: false).frame(width: 54.0, height: 54.0, alignment: .leading).padding(EdgeInsets(top: 0.0, leading: 10.0, bottom: 0.0, trailing: 10.0))
AvatarItemView(peer: peers?.peers[index], itemSize: 54.0, placeholderColor: getPlaceholderColor(), displayBadge: false).frame(width: 54.0, height: 54.0, alignment: .leading).padding(EdgeInsets(top: 0.0, leading: 10.0, bottom: 0.0, trailing: 10.0))
chatContent(peers?.peers[index]).frame(maxWidth: .infinity).padding(EdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 10.0))
})
})
@ -718,7 +766,7 @@ struct WidgetView: View {
}
}
default:
text = ""
text = "Long tap to edit widget"
}
return Text(text)
@ -765,6 +813,17 @@ struct WidgetView: View {
}
}
func getPlaceholderColor() -> Color {
switch colorScheme {
case .light:
return Color(.sRGB, red: 242.0 / 255.0, green: 242.0 / 255.0, blue: 247.0 / 255.0, opacity: 1.0)
case .dark:
return Color(.sRGB, red: 21.0 / 255.0, green: 21.0 / 255.0, blue: 21.0 / 255.0, opacity: 1.0)
@unknown default:
return .secondary
}
}
var body: some View {
GeometryReader(content: { geometry in
return VStack(alignment: .center, spacing: 0.0, content: {

View File

@ -10,7 +10,12 @@ enum ContextActionSibling {
case separator
}
final class ContextActionNode: ASDisplayNode {
public protocol ContextActionNodeProtocol: ASDisplayNode {
func setIsHighlighted(_ value: Bool)
func performAction()
}
final class ContextActionNode: ASDisplayNode, ContextActionNodeProtocol {
private let action: ContextMenuActionItem
private let getController: () -> ContextController?
private let actionSelected: (ContextMenuActionResult) -> Void

View File

@ -50,7 +50,7 @@ private final class InnerActionsContainerNode: ASDisplayNode {
private let feedbackTap: () -> Void
private(set) var gesture: UIGestureRecognizer?
private var currentHighlightedActionNode: ContextActionNode?
private var currentHighlightedActionNode: ContextActionNodeProtocol?
var panSelectionGestureEnabled: Bool = true {
didSet {
@ -291,13 +291,17 @@ private final class InnerActionsContainerNode: ASDisplayNode {
self.containerNode.backgroundColor = presentationData.theme.contextMenu.backgroundColor
}
func actionNode(at point: CGPoint) -> ContextActionNode? {
func actionNode(at point: CGPoint) -> ContextActionNodeProtocol? {
for itemNode in self.itemNodes {
switch itemNode {
case let .action(actionNode):
if actionNode.frame.contains(point) {
return actionNode
}
case let .custom(node):
if let node = node as? ContextActionNodeProtocol, node.frame.contains(point) {
return node
}
default:
break
}
@ -536,7 +540,7 @@ final class ContextActionsContainerNode: ASDisplayNode {
self.scrollNode.frame = CGRect(origin: CGPoint(), size: containerSize)
}
func actionNode(at point: CGPoint) -> ContextActionNode? {
func actionNode(at point: CGPoint) -> ContextActionNodeProtocol? {
return self.actionsNode.actionNode(at: self.view.convert(point, to: self.actionsNode.view))
}

View File

@ -138,7 +138,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
private var didCompleteAnimationIn = false
private var initialContinueGesturePoint: CGPoint?
private var didMoveFromInitialGesturePoint = false
private var highlightedActionNode: ContextActionNode?
private var highlightedActionNode: ContextActionNodeProtocol?
private var highlightedReaction: ReactionContextItem.Reaction?
private let hapticFeedback = HapticFeedback()

View File

@ -268,19 +268,20 @@ public func peerAutoremoveSetupScreen(context: AccountContext, peerId: PeerId, c
if let globalValue = globalValue, globalValue != defaultGlobalValue {
updated = true
}
var resolvedValue: Int32? = changedValue ?? resolvedDefaultValue
if resolvedValue == Int32.max {
resolvedValue = nil
}
let resolvedMaxValue: Int32
if peer is TelegramUser {
resolvedMaxValue = peerValue
} else {
resolvedMaxValue = Int32.max
}
if updated {
var resolvedValue: Int32? = changedValue ?? resolvedDefaultValue
if resolvedValue == Int32.max {
resolvedValue = nil
}
let resolvedMaxValue: Int32
if peer is TelegramUser {
resolvedMaxValue = peerValue
} else {
resolvedMaxValue = Int32.max
}
let resolvedGlobalValue = globalValue ?? defaultGlobalValue
let signal = setChatMessageAutoremoveTimeoutInteractively(account: context.account, peerId: peerId, timeout: resolvedValue, isGlobal: resolvedGlobalValue)
@ -301,7 +302,12 @@ public func peerAutoremoveSetupScreen(context: AccountContext, peerId: PeerId, c
}))
} else {
dismissImpl?()
completion(.unchanged)
if resolvedMaxValue != Int32.max {
completion(.updated(PeerAutoremoveSetupScreenResult.Updated(myValue: resolvedValue, limitedByValue: resolvedMaxValue)))
} else {
completion(.unchanged)
}
}
})
}

View File

@ -83,7 +83,7 @@ private final class PeerInputActivityContext {
}, queue: self.queue)
let updateId = nextUpdateId
nextUpdateId += 1
self.activities.insert(ActivityRecord(peerId: peerId, activity: activity, id: activityId, timer: timer, episodeId: episodeId, timestamp: timestamp, updateId: updateId), at: 0)
self.activities.append(ActivityRecord(peerId: peerId, activity: activity, id: activityId, timer: timer, episodeId: episodeId, timestamp: timestamp, updateId: updateId))
timer.start()
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5566,8 +5566,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
canSetupAutoremoveTimeout = true
}
}
} else if let _ = peer as? TelegramUser {
canSetupAutoremoveTimeout = true
} else if let user = peer as? TelegramUser {
if user.id != strongSelf.context.account.peerId {
canSetupAutoremoveTimeout = true
}
} else if let channel = peer as? TelegramChannel {
if channel.hasPermission(.deleteAllMessages) {
canSetupAutoremoveTimeout = true
@ -7746,8 +7748,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
canSetupAutoremoveTimeout = true
}
}
} else if let _ = self.presentationInterfaceState.renderedPeer?.peer as? TelegramUser {
canSetupAutoremoveTimeout = true
} else if let user = self.presentationInterfaceState.renderedPeer?.peer as? TelegramUser {
if user.id != self.context.account.peerId {
canSetupAutoremoveTimeout = true
}
} else if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel {
if channel.hasPermission(.deleteAllMessages) {
canSetupAutoremoveTimeout = true

View File

@ -256,7 +256,7 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
if canSetupAutoremoveTimeout {
if case .scheduledMessages = chatPresentationInterfaceState.subject {
} else {
} else if chatPresentationInterfaceState.renderedPeer?.peerId != context.account.peerId {
if currentAutoremoveTimeout != nil || chatPresentationInterfaceState.renderedPeer?.peer is TelegramSecretChat {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
}
@ -283,7 +283,7 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
}
if !extendedSearchLayout {
if case .scheduledMessages = chatPresentationInterfaceState.subject {
} else {
} else if chatPresentationInterfaceState.renderedPeer?.peerId != context.account.peerId {
if let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat {
accessoryItems.append(.messageAutoremoveTimeout(peer.messageAutoremoveTimeout))
} else if currentAutoremoveTimeout != nil && chatPresentationInterfaceState.interfaceState.composeInputState.inputText.length == 0 {

View File

@ -1250,7 +1250,7 @@ final class ChatDeleteMessageContextItem: ContextMenuCustomItem {
private let textFont = Font.regular(17.0)
private final class ChatDeleteMessageContextItemNode: ASDisplayNode, ContextMenuCustomNode {
private final class ChatDeleteMessageContextItemNode: ASDisplayNode, ContextMenuCustomNode, ContextActionNodeProtocol {
private let item: ChatDeleteMessageContextItem
private let presentationData: PresentationData
private let getController: () -> ContextController?

View File

@ -152,43 +152,8 @@ final class WidgetDataContext {
}
let processedRecent = recent
|> map { result -> WidgetData in
switch result {
case .disabled:
return WidgetData(accountId: account.id.int64, content: .empty, unlockedForLockId: nil)
case let .peers(peers, unread, messages):
return WidgetData(accountId: account.id.int64, content: .peers(WidgetDataPeers(accountPeerId: account.peerId.toInt64(), peers: peers.compactMap { peer -> WidgetDataPeer? in
var name: String = ""
var lastName: String?
if let user = peer as? TelegramUser {
if let firstName = user.firstName {
name = firstName
lastName = user.lastName
} else if let lastName = user.lastName {
name = lastName
} else if let phone = user.phone, !phone.isEmpty {
name = phone
}
} else {
name = peer.debugDisplayTitle
}
var badge: WidgetDataPeer.Badge?
if let unreadValue = unread[peer.id], unreadValue.count > 0 {
badge = WidgetDataPeer.Badge(
count: Int(unreadValue.count),
isMuted: unreadValue.isMuted
)
}
let message = messages[peer.id]
return WidgetDataPeer(id: peer.id.toInt64(), name: name, lastName: lastName, letters: peer.displayLetters, avatarPath: smallestImageRepresentation(peer.profileImageRepresentations).flatMap { representation in
return account.postbox.mediaBox.resourcePath(representation.resource)
}, badge: badge, message: message)
}, updateTimestamp: Int32(Date().timeIntervalSince1970))), unlockedForLockId: nil)
}
|> map { _ -> WidgetData in
return WidgetData(accountId: account.id.int64, content: .peers(WidgetDataPeers(accountPeerId: account.peerId.toInt64(), peers: [], updateTimestamp: Int32(Date().timeIntervalSince1970))), unlockedForLockId: nil)
}
|> distinctUntilChanged

View File

@ -147,7 +147,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
}
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(14.0), textColor: .white)
displayUndo = false
self.originalRemainingSeconds = 3
self.originalRemainingSeconds = 5
case let .succeed(text):
self.avatarNode = nil
self.iconNode = nil