Auto-remove fixes

This commit is contained in:
Ali 2021-02-12 16:59:50 +04:00
parent a7c7dbfd02
commit a364ef1284
13 changed files with 130 additions and 87 deletions

View File

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

View File

@ -316,6 +316,7 @@ extension PeersWidgetData {
struct AvatarItemView: View { struct AvatarItemView: View {
var peer: ParsedPeer? var peer: ParsedPeer?
var itemSize: CGFloat var itemSize: CGFloat
var placeholderColor: Color
var displayBadge: Bool = true var displayBadge: Bool = true
var body: some View { 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))) Image(uiImage: avatarImage(accountPeerId: peer.accountPeerId, peer: peer.peer, size: CGSize(width: itemSize, height: itemSize)))
.clipShape(Circle()) .clipShape(Circle())
} else { } else {
Image(uiImage: avatarImage(accountPeerId: nil, peer: nil, size: CGSize(width: itemSize, height: itemSize))) Circle()
//Rectangle() .fill(placeholderColor)
.frame(width: itemSize, height: itemSize) .frame(width: itemSize, height: itemSize)
.clipShape(Circle()) //Image(uiImage: avatarImage(accountPeerId: nil, peer: nil, size: CGSize(width: itemSize, height: itemSize)))
.redacted(reason: .placeholder) //.clipShape(Circle())
//.redacted(reason: .placeholder)
} }
/*if let peer = peer, displayBadge, let badge = peer.badge, badge.count > 0 { /*if let peer = peer, displayBadge, let badge = peer.badge, badge.count > 0 {
Text("\(badge.count)") 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: { Link(destination: URL(string: linkForPeer(accountId: peers.peers[i].accountId, id: peers.peers[i].peer.id))!, label: {
AvatarItemView( AvatarItemView(
peer: peers.peers[i], peer: peers.peers[i],
itemSize: itemSize itemSize: itemSize,
placeholderColor: getPlaceholderColor()
).frame(width: itemSize, height: itemSize) ).frame(width: itemSize, height: itemSize)
}).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))) .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 { func chatTopLine(_ peer: ParsedPeer?) -> some View {
let dateText: String let dateText: String
let chatTitle: Text let chatTitle: AnyView
let date: Text let date: Text
if let peer = peer { if let peer = peer {
@ -470,26 +473,44 @@ struct WidgetView: View {
} else { } else {
dateText = "" 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) date = Text(dateText)
.font(Font.system(size: 14.0, weight: .regular, design: .default)).foregroundColor(.secondary) .font(Font.system(size: 14.0, weight: .regular, design: .default)).foregroundColor(.secondary)
} else { } else {
dateText = "10:00" dateText = " "
chatTitle = Text("Chat Title").font(Font.system(size: 16.0, weight: .medium, design: .default)).foregroundColor(.primary) chatTitle = AnyView(Text(" ").font(Font.system(size: 16.0, weight: .medium, design: .default)).foregroundColor(.primary))
date = Text(dateText) 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: { return HStack(alignment: .center, spacing: 0.0, content: {
if peer != nil { if peer != nil {
chatTitle chatTitle
} else { } 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() Spacer()
if peer != nil { if peer != nil {
date date
} else { } 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) .padding(0.0)
@ -580,15 +601,42 @@ struct WidgetView: View {
.foregroundColor(.secondary) .foregroundColor(.secondary)
.multilineTextAlignment(.leading) .multilineTextAlignment(.leading)
.padding(0.0) .padding(0.0)
//.frame(maxHeight: .infinity, alignment: .topLeading)
//.background(Rectangle().foregroundColor(.gray))
if peer != nil { if peer != nil {
return AnyView(textView) return AnyView(textView)
} else { } else {
return AnyView( return AnyView(
textView VStack(alignment: .leading, spacing: 0.0, content: {
.redacted(reason: .placeholder) 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( 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, 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)) 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: default:
text = "" text = "Long tap to edit widget"
} }
return Text(text) 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 { var body: some View {
GeometryReader(content: { geometry in GeometryReader(content: { geometry in
return VStack(alignment: .center, spacing: 0.0, content: { return VStack(alignment: .center, spacing: 0.0, content: {

View File

@ -10,7 +10,12 @@ enum ContextActionSibling {
case separator 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 action: ContextMenuActionItem
private let getController: () -> ContextController? private let getController: () -> ContextController?
private let actionSelected: (ContextMenuActionResult) -> Void private let actionSelected: (ContextMenuActionResult) -> Void

View File

@ -50,7 +50,7 @@ private final class InnerActionsContainerNode: ASDisplayNode {
private let feedbackTap: () -> Void private let feedbackTap: () -> Void
private(set) var gesture: UIGestureRecognizer? private(set) var gesture: UIGestureRecognizer?
private var currentHighlightedActionNode: ContextActionNode? private var currentHighlightedActionNode: ContextActionNodeProtocol?
var panSelectionGestureEnabled: Bool = true { var panSelectionGestureEnabled: Bool = true {
didSet { didSet {
@ -291,13 +291,17 @@ private final class InnerActionsContainerNode: ASDisplayNode {
self.containerNode.backgroundColor = presentationData.theme.contextMenu.backgroundColor self.containerNode.backgroundColor = presentationData.theme.contextMenu.backgroundColor
} }
func actionNode(at point: CGPoint) -> ContextActionNode? { func actionNode(at point: CGPoint) -> ContextActionNodeProtocol? {
for itemNode in self.itemNodes { for itemNode in self.itemNodes {
switch itemNode { switch itemNode {
case let .action(actionNode): case let .action(actionNode):
if actionNode.frame.contains(point) { if actionNode.frame.contains(point) {
return actionNode return actionNode
} }
case let .custom(node):
if let node = node as? ContextActionNodeProtocol, node.frame.contains(point) {
return node
}
default: default:
break break
} }
@ -536,7 +540,7 @@ final class ContextActionsContainerNode: ASDisplayNode {
self.scrollNode.frame = CGRect(origin: CGPoint(), size: containerSize) 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)) 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 didCompleteAnimationIn = false
private var initialContinueGesturePoint: CGPoint? private var initialContinueGesturePoint: CGPoint?
private var didMoveFromInitialGesturePoint = false private var didMoveFromInitialGesturePoint = false
private var highlightedActionNode: ContextActionNode? private var highlightedActionNode: ContextActionNodeProtocol?
private var highlightedReaction: ReactionContextItem.Reaction? private var highlightedReaction: ReactionContextItem.Reaction?
private let hapticFeedback = HapticFeedback() private let hapticFeedback = HapticFeedback()

View File

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

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

View File

@ -256,7 +256,7 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
if canSetupAutoremoveTimeout { if canSetupAutoremoveTimeout {
if case .scheduledMessages = chatPresentationInterfaceState.subject { if case .scheduledMessages = chatPresentationInterfaceState.subject {
} else { } else if chatPresentationInterfaceState.renderedPeer?.peerId != context.account.peerId {
if currentAutoremoveTimeout != nil || chatPresentationInterfaceState.renderedPeer?.peer is TelegramSecretChat { if currentAutoremoveTimeout != nil || chatPresentationInterfaceState.renderedPeer?.peer is TelegramSecretChat {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout)) accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
} }
@ -283,7 +283,7 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
} }
if !extendedSearchLayout { if !extendedSearchLayout {
if case .scheduledMessages = chatPresentationInterfaceState.subject { if case .scheduledMessages = chatPresentationInterfaceState.subject {
} else { } else if chatPresentationInterfaceState.renderedPeer?.peerId != context.account.peerId {
if let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat { if let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat {
accessoryItems.append(.messageAutoremoveTimeout(peer.messageAutoremoveTimeout)) accessoryItems.append(.messageAutoremoveTimeout(peer.messageAutoremoveTimeout))
} else if currentAutoremoveTimeout != nil && chatPresentationInterfaceState.interfaceState.composeInputState.inputText.length == 0 { } 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 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 item: ChatDeleteMessageContextItem
private let presentationData: PresentationData private let presentationData: PresentationData
private let getController: () -> ContextController? private let getController: () -> ContextController?

View File

@ -152,43 +152,8 @@ final class WidgetDataContext {
} }
let processedRecent = recent let processedRecent = recent
|> map { result -> WidgetData in |> map { _ -> WidgetData in
switch result { return WidgetData(accountId: account.id.int64, content: .peers(WidgetDataPeers(accountPeerId: account.peerId.toInt64(), peers: [], updateTimestamp: Int32(Date().timeIntervalSince1970))), unlockedForLockId: nil)
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)
}
} }
|> distinctUntilChanged |> distinctUntilChanged

View File

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