Various improvements

This commit is contained in:
Ilya Laktyushin 2023-03-22 16:11:37 +04:00
parent 0c3c7148fa
commit 272f538060
14 changed files with 127 additions and 115 deletions

View File

@ -690,13 +690,13 @@ final class CallListControllerNode: ASDisplayNode {
let alpha: CGFloat = isHidden ? 0.0 : 1.0 let alpha: CGFloat = isHidden ? 0.0 : 1.0
let previousAlpha = self.emptyTextNode.alpha let previousAlpha = self.emptyTextNode.alpha
self.emptyTextNode.alpha = alpha self.emptyTextNode.alpha = alpha
self.emptyTextNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.2) self.emptyTextNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.25)
if previousAlpha.isZero && !alpha.isZero { if previousAlpha.isZero && !alpha.isZero {
self.emptyAnimationNode.visibility = true self.emptyAnimationNode.visibility = true
} }
self.emptyAnimationNode.alpha = alpha self.emptyAnimationNode.alpha = alpha
self.emptyAnimationNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.2, completion: { [weak self] _ in self.emptyAnimationNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.25, completion: { [weak self] _ in
if let strongSelf = self { if let strongSelf = self {
if !previousAlpha.isZero && strongSelf.emptyAnimationNode.alpha.isZero { if !previousAlpha.isZero && strongSelf.emptyAnimationNode.alpha.isZero {
strongSelf.emptyAnimationNode.visibility = false strongSelf.emptyAnimationNode.visibility = false
@ -705,9 +705,9 @@ final class CallListControllerNode: ASDisplayNode {
}) })
self.emptyButtonIconNode.alpha = alpha self.emptyButtonIconNode.alpha = alpha
self.emptyButtonIconNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.2) self.emptyButtonIconNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.25)
self.emptyButtonTextNode.alpha = alpha self.emptyButtonTextNode.alpha = alpha
self.emptyButtonTextNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.2) self.emptyButtonTextNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.25)
self.emptyButtonNode.isUserInteractionEnabled = !isHidden self.emptyButtonNode.isUserInteractionEnabled = !isHidden
if !isHidden { if !isHidden {
@ -733,7 +733,6 @@ final class CallListControllerNode: ASDisplayNode {
} }
self.emptyTextNode.attributedText = NSAttributedString(string: emptyText, font: textFont, textColor: color, paragraphAlignment: .center) self.emptyTextNode.attributedText = NSAttributedString(string: emptyText, font: textFont, textColor: color, paragraphAlignment: .center)
self.emptyButtonTextNode.attributedText = NSAttributedString(string: buttonText, font: buttonFont, textColor: theme.list.itemAccentColor, paragraphAlignment: .center) self.emptyButtonTextNode.attributedText = NSAttributedString(string: buttonText, font: buttonFont, textColor: theme.list.itemAccentColor, paragraphAlignment: .center)
if let layout = self.containerLayout { if let layout = self.containerLayout {

View File

@ -230,7 +230,7 @@ func countMeaningfulCallListEntries(_ entries: [CallListNodeEntry]) -> Int {
var count: Int = 0 var count: Int = 0
for entry in entries { for entry in entries {
switch entry.stableId { switch entry.stableId {
case .setting, .groupCall: case .setting:
break break
default: default:
count += 1 count += 1

View File

@ -156,7 +156,7 @@ final class LocationSearchContainerNode: ASDisplayNode {
let searchItems = self.searchQuery.get() let searchItems = self.searchQuery.get()
|> mapToSignal { query -> Signal<String?, NoError> in |> mapToSignal { query -> Signal<String?, NoError> in
if let query = query, !query.isEmpty { if let query = query, !query.isEmpty {
return (.complete() |> delay(0.6, queue: Queue.mainQueue())) return (.complete() |> delay(1.0, queue: Queue.mainQueue()))
|> then(.single(query)) |> then(.single(query))
} else { } else {
return .single(query) return .single(query)

View File

@ -303,7 +303,13 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
disposable.set((callContext.context.panelData disposable.set((callContext.context.panelData
|> deliverOnMainQueue).start(next: { panelData in |> deliverOnMainQueue).start(next: { panelData in
callContext.keep() callContext.keep()
subscriber.putNext(panelData) var updatedPanelData = panelData
if let panelData {
var updatedInfo = panelData.info
updatedInfo.subscribedToScheduled = activeCall.subscribedToScheduled
updatedPanelData = panelData.withInfo(updatedInfo)
}
subscriber.putNext(updatedPanelData)
})) }))
} }

View File

@ -64,6 +64,18 @@ public final class GroupCallPanelData {
self.activeSpeakers = activeSpeakers self.activeSpeakers = activeSpeakers
self.groupCall = groupCall self.groupCall = groupCall
} }
public func withInfo(_ info: GroupCallInfo) -> GroupCallPanelData {
return GroupCallPanelData(
peerId: self.peerId,
isChannel: self.isChannel,
info: info,
topParticipants: self.topParticipants,
participantCount: self.participantCount,
activeSpeakers: self.activeSpeakers,
groupCall: self.groupCall
)
}
} }
private final class FakeAudioLevelGenerator { private final class FakeAudioLevelGenerator {

View File

@ -116,12 +116,12 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext {
activeSpeakers: Set(), activeSpeakers: Set(),
groupCall: nil groupCall: nil
)))*/ )))*/
let state = engine.calls.getGroupCallParticipants(callId: call.id, accessHash: call.accessHash, offset: "", ssrcs: [], limit: 100, sortAscending: nil) let state = engine.calls.getGroupCallParticipants(callId: call.id, accessHash: call.accessHash, offset: "", ssrcs: [], limit: 100, sortAscending: nil)
|> map(Optional.init) |> map(Optional.init)
|> `catch` { _ -> Signal<GroupCallParticipantsContext.State?, NoError> in |> `catch` { _ -> Signal<GroupCallParticipantsContext.State?, NoError> in
return .single(nil) return .single(nil)
} }
self.disposable = (combineLatest(queue: .mainQueue(), self.disposable = (combineLatest(queue: .mainQueue(),
state, state,
@ -139,7 +139,7 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext {
state: state, state: state,
previousServiceState: nil previousServiceState: nil
) )
strongSelf.participantsContext = context strongSelf.participantsContext = context
strongSelf.panelDataPromise.set(combineLatest(queue: .mainQueue(), strongSelf.panelDataPromise.set(combineLatest(queue: .mainQueue(),
context.state, context.state,

View File

@ -3910,7 +3910,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] { if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, initialCaption: NSAttributedString(string: message.text), snapshots: [], transitionCompletion: nil, getCaptionPanelView: { [weak self] in let inputText = strongSelf.presentationInterfaceState.interfaceState.effectiveInputState.inputText
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, initialCaption: inputText, snapshots: [], transitionCompletion: nil, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView() return self?.getCaptionPanelView()
}, sendMessagesWithSignals: { [weak self] signals, _, _ in }, sendMessagesWithSignals: { [weak self] signals, _, _ in
if let strongSelf = self { if let strongSelf = self {
@ -8139,16 +8140,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let strongSelf = self, let peerId = strongSelf.chatLocation.peerId { if let strongSelf = self, let peerId = strongSelf.chatLocation.peerId {
let presentationData = strongSelf.presentationData let presentationData = strongSelf.presentationData
let forwardOptions: Signal<ChatControllerSubject.ForwardOptions, NoError> let forwardOptions = strongSelf.presentationInterfaceStatePromise.get()
if peerId.namespace == Namespaces.Peer.SecretChat { |> map { state -> ChatControllerSubject.ForwardOptions in
forwardOptions = .single(ChatControllerSubject.ForwardOptions(hideNames: true, hideCaptions: false)) var hideNames = state.interfaceState.forwardOptionsState?.hideNames ?? false
} else { if peerId.namespace == Namespaces.Peer.SecretChat {
forwardOptions = strongSelf.presentationInterfaceStatePromise.get() hideNames = true
|> map { state -> ChatControllerSubject.ForwardOptions in
return ChatControllerSubject.ForwardOptions(hideNames: state.interfaceState.forwardOptionsState?.hideNames ?? false, hideCaptions: state.interfaceState.forwardOptionsState?.hideCaptions ?? false)
} }
|> distinctUntilChanged return ChatControllerSubject.ForwardOptions(hideNames: hideNames, hideCaptions: state.interfaceState.forwardOptionsState?.hideCaptions ?? false)
} }
|> distinctUntilChanged
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: .forwardedMessages(peerIds: [peerId], ids: strongSelf.presentationInterfaceState.interfaceState.forwardMessageIds ?? [], options: forwardOptions), botStart: nil, mode: .standard(previewing: true)) let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: .forwardedMessages(peerIds: [peerId], ids: strongSelf.presentationInterfaceState.interfaceState.forwardMessageIds ?? [], options: forwardOptions), botStart: nil, mode: .standard(previewing: true))
chatController.canReadHistory.set(false) chatController.canReadHistory.set(false)
@ -8208,88 +8208,90 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
} }
let canHideNames = hasNotOwnMessages && hasOther var canHideNames = hasNotOwnMessages && hasOther
if case let .peer(peerId) = strongSelf.chatLocation, peerId.namespace == Namespaces.Peer.SecretChat {
canHideNames = false
}
let hideNames = forwardOptions.hideNames let hideNames = forwardOptions.hideNames
let hideCaptions = forwardOptions.hideCaptions let hideCaptions = forwardOptions.hideCaptions
if case let .peer(peerId) = strongSelf.chatLocation, peerId.namespace == Namespaces.Peer.SecretChat { if canHideNames {
items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_ShowSendersName : presentationData.strings.Conversation_ForwardOptions_ShowSendersNames, icon: { theme in
if hideNames {
return nil
} else {
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
}
}, action: { [weak self] _, f in
self?.interfaceInteraction?.updateForwardOptionsState({ current in
var updated = current
updated.hideNames = false
updated.hideCaptions = false
updated.unhideNamesOnCaptionChange = false
return updated
})
})))
} else { items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_HideSendersName : presentationData.strings.Conversation_ForwardOptions_HideSendersNames, icon: { theme in
if canHideNames { if hideNames {
items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_ShowSendersName : presentationData.strings.Conversation_ForwardOptions_ShowSendersNames, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
if hideNames { } else {
return nil return nil
} else { }
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) }, action: { _, f in
} self?.interfaceInteraction?.updateForwardOptionsState({ current in
}, action: { [weak self] _, f in var updated = current
self?.interfaceInteraction?.updateForwardOptionsState({ current in updated.hideNames = true
var updated = current updated.unhideNamesOnCaptionChange = false
updated.hideNames = false return updated
updated.hideCaptions = false })
updated.unhideNamesOnCaptionChange = false })))
return updated
})
})))
items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_HideSendersName : presentationData.strings.Conversation_ForwardOptions_HideSendersNames, icon: { theme in
if hideNames {
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
} else {
return nil
}
}, action: { _, f in
self?.interfaceInteraction?.updateForwardOptionsState({ current in
var updated = current
updated.hideNames = true
updated.unhideNamesOnCaptionChange = false
return updated
})
})))
items.append(.separator)
}
if hasCaptions { items.append(.separator)
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_ShowCaption, icon: { theme in }
if hideCaptions {
return nil if hasCaptions {
} else { items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_ShowCaption, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) if hideCaptions {
} return nil
}, action: { [weak self] _, f in } else {
self?.interfaceInteraction?.updateForwardOptionsState({ current in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
var updated = current }
updated.hideCaptions = false }, action: { [weak self] _, f in
self?.interfaceInteraction?.updateForwardOptionsState({ current in
var updated = current
updated.hideCaptions = false
if canHideNames {
if updated.unhideNamesOnCaptionChange { if updated.unhideNamesOnCaptionChange {
updated.unhideNamesOnCaptionChange = false updated.unhideNamesOnCaptionChange = false
updated.hideNames = false updated.hideNames = false
} }
return updated
})
})))
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_HideCaption, icon: { theme in
if hideCaptions {
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
} else {
return nil
} }
}, action: { _, f in return updated
self?.interfaceInteraction?.updateForwardOptionsState({ current in })
var updated = current })))
updated.hideCaptions = true
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_HideCaption, icon: { theme in
if hideCaptions {
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
} else {
return nil
}
}, action: { _, f in
self?.interfaceInteraction?.updateForwardOptionsState({ current in
var updated = current
updated.hideCaptions = true
if canHideNames {
if !updated.hideNames { if !updated.hideNames {
updated.hideNames = true updated.hideNames = true
updated.unhideNamesOnCaptionChange = true updated.unhideNamesOnCaptionChange = true
} }
return updated }
}) return updated
}))) })
})))
items.append(.separator)
} items.append(.separator)
} }
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_ChangeRecipient, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor) }, action: { c, f in items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_ChangeRecipient, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor) }, action: { c, f in
@ -11370,7 +11372,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
var layout = layout var layout = layout
if case .compact = layout.metrics.widthClass, let _ = self.attachmentController { if case .compact = layout.metrics.widthClass, let attachmentController = self.attachmentController, attachmentController.window != nil {
layout = layout.withUpdatedInputHeight(nil) layout = layout.withUpdatedInputHeight(nil)
} }

View File

@ -1687,8 +1687,8 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
state = .none state = .none
badgeContent = nil badgeContent = nil
} else if wideLayout { } else if wideLayout {
if let size = file.size { if let size = file.size, size > 0 && size != .max {
let sizeString = "\(dataSizeString(Int(Float(size) * progress), forceDecimal: true, formatting: formatting)) / \(dataSizeString(size, forceDecimal: true, formatting: formatting))" let sizeString = "\(dataSizeString(Int(Float(size) * progress), forceDecimal: true, formatting: formatting)) / \(dataSizeString(size, forceDecimal: true, formatting: formatting))"
if let duration = file.duration, !message.flags.contains(.Unsent) { if let duration = file.duration, !message.flags.contains(.Unsent) {
let durationString = file.isAnimated ? gifTitle : stringForDuration(playerDuration > 0 ? playerDuration : duration, position: playerPosition) let durationString = file.isAnimated ? gifTitle : stringForDuration(playerDuration > 0 ? playerDuration : duration, position: playerPosition)
if isMediaStreamable(message: message, media: file) { if isMediaStreamable(message: message, media: file) {
@ -1721,8 +1721,8 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
state = automaticPlayback ? .none : state state = automaticPlayback ? .none : state
} }
} else { } else {
if isMediaStreamable(message: message, media: file), let size = file.size { if isMediaStreamable(message: message, media: file), let fileSize = file.size, fileSize > 0 && fileSize != .max {
let sizeString = "\(dataSizeString(Int(Float(size) * progress), forceDecimal: true, formatting: formatting)) / \(dataSizeString(size, forceDecimal: true, formatting: formatting))" let sizeString = "\(dataSizeString(Int64(Float(fileSize) * progress), forceDecimal: true, formatting: formatting)) / \(dataSizeString(fileSize, forceDecimal: true, formatting: formatting))"
if message.flags.contains(.Unsent), let duration = file.duration { if message.flags.contains(.Unsent), let duration = file.duration {
let durationString = stringForDuration(playerDuration > 0 ? playerDuration : duration, position: playerPosition) let durationString = stringForDuration(playerDuration > 0 ? playerDuration : duration, position: playerPosition)
@ -1749,8 +1749,8 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
if let duration = file.duration, !file.isAnimated { if let duration = file.duration, !file.isAnimated {
let durationString = stringForDuration(playerDuration > 0 ? playerDuration : duration, position: playerPosition) let durationString = stringForDuration(playerDuration > 0 ? playerDuration : duration, position: playerPosition)
if automaticPlayback, let size = file.size { if automaticPlayback, let fileSize = file.size, fileSize > 0 && fileSize != .max {
let sizeString = "\(dataSizeString(Int(Float(size) * progress), forceDecimal: true, formatting: formatting)) / \(dataSizeString(size, forceDecimal: true, formatting: formatting))" let sizeString = "\(dataSizeString(Int64(Float(fileSize) * progress), forceDecimal: true, formatting: formatting)) / \(dataSizeString(fileSize, forceDecimal: true, formatting: formatting))"
mediaDownloadState = .fetching(progress: progress) mediaDownloadState = .fetching(progress: progress)
badgeContent = .mediaDownload(backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, duration: durationString, size: active ? sizeString : nil, muted: muted, active: active) badgeContent = .mediaDownload(backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, duration: durationString, size: active ? sizeString : nil, muted: muted, active: active)
} else { } else {
@ -1800,9 +1800,9 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
do { do {
let durationString = file.isAnimated ? gifTitle : stringForDuration(playerDuration > 0 ? playerDuration : (file.duration ?? 0), position: playerPosition) let durationString = file.isAnimated ? gifTitle : stringForDuration(playerDuration > 0 ? playerDuration : (file.duration ?? 0), position: playerPosition)
if wideLayout { if wideLayout {
if isMediaStreamable(message: message, media: file) { if isMediaStreamable(message: message, media: file), let fileSize = file.size, fileSize > 0 && fileSize != .max {
state = automaticPlayback ? .none : .play(messageTheme.mediaOverlayControlColors.foregroundColor) state = automaticPlayback ? .none : .play(messageTheme.mediaOverlayControlColors.foregroundColor)
badgeContent = .mediaDownload(backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, duration: durationString, size: dataSizeString(file.size ?? 0, formatting: formatting), muted: muted, active: true) badgeContent = .mediaDownload(backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, duration: durationString, size: dataSizeString(fileSize, formatting: formatting), muted: muted, active: true)
mediaDownloadState = .remote mediaDownloadState = .remote
} else { } else {
state = automaticPlayback ? .none : state state = automaticPlayback ? .none : state

View File

@ -263,19 +263,16 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
} else if item.messages[0].id.peerId.namespace == Namespaces.Peer.CloudGroup { } else if item.messages[0].id.peerId.namespace == Namespaces.Peer.CloudGroup {
isGroup = true isGroup = true
} }
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
if isChannel { if isChannel {
switch kind { switch kind {
case .image: case .image:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_CHANNEL_MESSAGE_PHOTOS_TEXT(Int32(item.messages.count)) messageText = presentationData.strings.PUSH_CHANNEL_MESSAGE_PHOTOS_TEXT(Int32(item.messages.count))
case .video: case .video:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_CHANNEL_MESSAGE_VIDEOS_TEXT(Int32(item.messages.count)) messageText = presentationData.strings.PUSH_CHANNEL_MESSAGE_VIDEOS_TEXT(Int32(item.messages.count))
case .file: case .file:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_CHANNEL_MESSAGE_DOCS_TEXT(Int32(item.messages.count)) messageText = presentationData.strings.PUSH_CHANNEL_MESSAGE_DOCS_TEXT(Int32(item.messages.count))
default: default:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_CHANNEL_MESSAGES_TEXT(Int32(item.messages.count)) messageText = presentationData.strings.PUSH_CHANNEL_MESSAGES_TEXT(Int32(item.messages.count))
} }
} else if isGroup, var author = item.messages[0].author { } else if isGroup, var author = item.messages[0].author {
@ -284,31 +281,23 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
} }
switch kind { switch kind {
case .image: case .image:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_CHAT_MESSAGE_PHOTOS_TEXT(Int32(item.messages.count)).replacingOccurrences(of: "{author}", with: EnginePeer(author).compactDisplayTitle) messageText = presentationData.strings.PUSH_CHAT_MESSAGE_PHOTOS_TEXT(Int32(item.messages.count)).replacingOccurrences(of: "{author}", with: EnginePeer(author).compactDisplayTitle)
case .video: case .video:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_CHAT_MESSAGE_VIDEOS_TEXT(Int32(item.messages.count)).replacingOccurrences(of: "{author}", with: EnginePeer(author).compactDisplayTitle) messageText = presentationData.strings.PUSH_CHAT_MESSAGE_VIDEOS_TEXT(Int32(item.messages.count)).replacingOccurrences(of: "{author}", with: EnginePeer(author).compactDisplayTitle)
case .file: case .file:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_CHAT_MESSAGE_DOCS_TEXT(Int32(item.messages.count)).replacingOccurrences(of: "{author}", with: EnginePeer(author).compactDisplayTitle) messageText = presentationData.strings.PUSH_CHAT_MESSAGE_DOCS_TEXT(Int32(item.messages.count)).replacingOccurrences(of: "{author}", with: EnginePeer(author).compactDisplayTitle)
default: default:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_CHAT_MESSAGES_TEXT(Int32(item.messages.count)).replacingOccurrences(of: "{author}", with: EnginePeer(author).compactDisplayTitle) messageText = presentationData.strings.PUSH_CHAT_MESSAGES_TEXT(Int32(item.messages.count)).replacingOccurrences(of: "{author}", with: EnginePeer(author).compactDisplayTitle)
} }
} else { } else {
switch kind { switch kind {
case .image: case .image:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_MESSAGE_PHOTOS_TEXT(Int32(item.messages.count)) messageText = presentationData.strings.PUSH_MESSAGE_PHOTOS_TEXT(Int32(item.messages.count))
case .video: case .video:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_MESSAGE_VIDEOS_TEXT(Int32(item.messages.count)) messageText = presentationData.strings.PUSH_MESSAGE_VIDEOS_TEXT(Int32(item.messages.count))
case .file: case .file:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_MESSAGE_FILES_TEXT(Int32(item.messages.count)) messageText = presentationData.strings.PUSH_MESSAGE_FILES_TEXT(Int32(item.messages.count))
default: default:
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
messageText = presentationData.strings.PUSH_MESSAGES_TEXT(Int32(item.messages.count)) messageText = presentationData.strings.PUSH_MESSAGES_TEXT(Int32(item.messages.count))
} }
} }
@ -325,6 +314,10 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
title = "📅 \(currentTitle)" title = "📅 \(currentTitle)"
} }
if let attribute = item.messages.first?.attributes.first(where: { $0 is NotificationInfoMessageAttribute }) as? NotificationInfoMessageAttribute, attribute.flags.contains(.muted), let currentTitle = title {
title = "\(currentTitle) 🔕"
}
let textFont = compact ? Font.regular(15.0) : Font.regular(16.0) let textFont = compact ? Font.regular(15.0) : Font.regular(16.0)
let textColor = presentationData.theme.inAppNotification.primaryTextColor let textColor = presentationData.theme.inAppNotification.primaryTextColor
var attributedMessageText: NSAttributedString var attributedMessageText: NSAttributedString

View File

@ -3691,7 +3691,7 @@ private class DynamicIslandMaskNode: ManagedAnimationNode {
func update(_ value: CGFloat) { func update(_ value: CGFloat) {
let lowerBound = 0 let lowerBound = 0
let upperBound = 180 let upperBound = 540
let frameIndex = lowerBound + Int(value * CGFloat(upperBound - lowerBound)) let frameIndex = lowerBound + Int(value * CGFloat(upperBound - lowerBound))
if frameIndex != self.frameIndex { if frameIndex != self.frameIndex {
self.update(frameIndex: frameIndex) self.update(frameIndex: frameIndex)

View File

@ -295,7 +295,7 @@ public final class WebSearchController: ViewController {
let throttledSearchQuery = self.searchQueryPromise.get() let throttledSearchQuery = self.searchQueryPromise.get()
|> mapToSignal { query -> Signal<String, NoError> in |> mapToSignal { query -> Signal<String, NoError> in
if !query.isEmpty { if !query.isEmpty {
return (.complete() |> delay(0.6, queue: Queue.mainQueue())) return (.complete() |> delay(1.0, queue: Queue.mainQueue()))
|> then(.single(query)) |> then(.single(query))
} else { } else {
return .single(query) return .single(query)

View File

@ -61,7 +61,7 @@
_dimensions = CGSizeMake(width, height); _dimensions = CGSizeMake(width, height);
if ((_frameRate > 60) || _animation->duration() > 7.0) { if ((_frameRate > 60) || _animation->duration() > 9.0) {
return nil; return nil;
} }
} }