mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Various improvements
This commit is contained in:
parent
0c3c7148fa
commit
272f538060
Binary file not shown.
Binary file not shown.
@ -690,13 +690,13 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
let alpha: CGFloat = isHidden ? 0.0 : 1.0
|
||||
let previousAlpha = self.emptyTextNode.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 {
|
||||
self.emptyAnimationNode.visibility = true
|
||||
}
|
||||
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 !previousAlpha.isZero && strongSelf.emptyAnimationNode.alpha.isZero {
|
||||
strongSelf.emptyAnimationNode.visibility = false
|
||||
@ -705,9 +705,9 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
})
|
||||
|
||||
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.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.2)
|
||||
self.emptyButtonTextNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.25)
|
||||
self.emptyButtonNode.isUserInteractionEnabled = !isHidden
|
||||
|
||||
if !isHidden {
|
||||
@ -733,7 +733,6 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
if let layout = self.containerLayout {
|
||||
|
@ -230,7 +230,7 @@ func countMeaningfulCallListEntries(_ entries: [CallListNodeEntry]) -> Int {
|
||||
var count: Int = 0
|
||||
for entry in entries {
|
||||
switch entry.stableId {
|
||||
case .setting, .groupCall:
|
||||
case .setting:
|
||||
break
|
||||
default:
|
||||
count += 1
|
||||
|
@ -156,7 +156,7 @@ final class LocationSearchContainerNode: ASDisplayNode {
|
||||
let searchItems = self.searchQuery.get()
|
||||
|> mapToSignal { query -> Signal<String?, NoError> in
|
||||
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))
|
||||
} else {
|
||||
return .single(query)
|
||||
|
@ -303,7 +303,13 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
disposable.set((callContext.context.panelData
|
||||
|> deliverOnMainQueue).start(next: { panelData in
|
||||
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)
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,18 @@ public final class GroupCallPanelData {
|
||||
self.activeSpeakers = activeSpeakers
|
||||
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 {
|
||||
|
@ -3910,7 +3910,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
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()
|
||||
}, sendMessagesWithSignals: { [weak self] signals, _, _ in
|
||||
if let strongSelf = self {
|
||||
@ -8139,16 +8140,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if let strongSelf = self, let peerId = strongSelf.chatLocation.peerId {
|
||||
let presentationData = strongSelf.presentationData
|
||||
|
||||
let forwardOptions: Signal<ChatControllerSubject.ForwardOptions, NoError>
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
forwardOptions = .single(ChatControllerSubject.ForwardOptions(hideNames: true, hideCaptions: false))
|
||||
} else {
|
||||
forwardOptions = strongSelf.presentationInterfaceStatePromise.get()
|
||||
let forwardOptions = strongSelf.presentationInterfaceStatePromise.get()
|
||||
|> map { state -> ChatControllerSubject.ForwardOptions in
|
||||
return ChatControllerSubject.ForwardOptions(hideNames: state.interfaceState.forwardOptionsState?.hideNames ?? false, hideCaptions: state.interfaceState.forwardOptionsState?.hideCaptions ?? false)
|
||||
var hideNames = state.interfaceState.forwardOptionsState?.hideNames ?? false
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
hideNames = true
|
||||
}
|
||||
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))
|
||||
chatController.canReadHistory.set(false)
|
||||
@ -8208,14 +8208,13 @@ 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 hideCaptions = forwardOptions.hideCaptions
|
||||
|
||||
if case let .peer(peerId) = strongSelf.chatLocation, peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
|
||||
} else {
|
||||
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 {
|
||||
@ -8262,10 +8261,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self?.interfaceInteraction?.updateForwardOptionsState({ current in
|
||||
var updated = current
|
||||
updated.hideCaptions = false
|
||||
if canHideNames {
|
||||
if updated.unhideNamesOnCaptionChange {
|
||||
updated.unhideNamesOnCaptionChange = false
|
||||
updated.hideNames = false
|
||||
}
|
||||
}
|
||||
return updated
|
||||
})
|
||||
})))
|
||||
@ -8280,17 +8281,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self?.interfaceInteraction?.updateForwardOptionsState({ current in
|
||||
var updated = current
|
||||
updated.hideCaptions = true
|
||||
if canHideNames {
|
||||
if !updated.hideNames {
|
||||
updated.hideNames = true
|
||||
updated.unhideNamesOnCaptionChange = true
|
||||
}
|
||||
}
|
||||
return updated
|
||||
})
|
||||
})))
|
||||
|
||||
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
|
||||
self?.interfaceInteraction?.forwardCurrentForwardMessages()
|
||||
@ -11370,7 +11372,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -1687,7 +1687,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
state = .none
|
||||
badgeContent = nil
|
||||
} 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))"
|
||||
if let duration = file.duration, !message.flags.contains(.Unsent) {
|
||||
let durationString = file.isAnimated ? gifTitle : stringForDuration(playerDuration > 0 ? playerDuration : duration, position: playerPosition)
|
||||
@ -1721,8 +1721,8 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
state = automaticPlayback ? .none : state
|
||||
}
|
||||
} else {
|
||||
if isMediaStreamable(message: message, media: file), let size = file.size {
|
||||
let sizeString = "\(dataSizeString(Int(Float(size) * progress), forceDecimal: true, formatting: formatting)) / \(dataSizeString(size, forceDecimal: true, formatting: formatting))"
|
||||
if isMediaStreamable(message: message, media: file), let fileSize = file.size, fileSize > 0 && fileSize != .max {
|
||||
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 {
|
||||
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 {
|
||||
let durationString = stringForDuration(playerDuration > 0 ? playerDuration : duration, position: playerPosition)
|
||||
|
||||
if automaticPlayback, let size = file.size {
|
||||
let sizeString = "\(dataSizeString(Int(Float(size) * progress), forceDecimal: true, formatting: formatting)) / \(dataSizeString(size, forceDecimal: true, formatting: formatting))"
|
||||
if automaticPlayback, let fileSize = file.size, fileSize > 0 && fileSize != .max {
|
||||
let sizeString = "\(dataSizeString(Int64(Float(fileSize) * progress), forceDecimal: true, formatting: formatting)) / \(dataSizeString(fileSize, forceDecimal: true, formatting: formatting))"
|
||||
mediaDownloadState = .fetching(progress: progress)
|
||||
badgeContent = .mediaDownload(backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, duration: durationString, size: active ? sizeString : nil, muted: muted, active: active)
|
||||
} else {
|
||||
@ -1800,9 +1800,9 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
do {
|
||||
let durationString = file.isAnimated ? gifTitle : stringForDuration(playerDuration > 0 ? playerDuration : (file.duration ?? 0), position: playerPosition)
|
||||
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)
|
||||
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
|
||||
} else {
|
||||
state = automaticPlayback ? .none : state
|
||||
|
@ -263,19 +263,16 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
|
||||
} else if item.messages[0].id.peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||
isGroup = true
|
||||
}
|
||||
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
|
||||
if isChannel {
|
||||
switch kind {
|
||||
case .image:
|
||||
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
|
||||
messageText = presentationData.strings.PUSH_CHANNEL_MESSAGE_PHOTOS_TEXT(Int32(item.messages.count))
|
||||
case .video:
|
||||
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
|
||||
messageText = presentationData.strings.PUSH_CHANNEL_MESSAGE_VIDEOS_TEXT(Int32(item.messages.count))
|
||||
case .file:
|
||||
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
|
||||
messageText = presentationData.strings.PUSH_CHANNEL_MESSAGE_DOCS_TEXT(Int32(item.messages.count))
|
||||
default:
|
||||
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
|
||||
messageText = presentationData.strings.PUSH_CHANNEL_MESSAGES_TEXT(Int32(item.messages.count))
|
||||
}
|
||||
} else if isGroup, var author = item.messages[0].author {
|
||||
@ -284,31 +281,23 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
|
||||
}
|
||||
switch kind {
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
}
|
||||
} else {
|
||||
switch kind {
|
||||
case .image:
|
||||
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
|
||||
messageText = presentationData.strings.PUSH_MESSAGE_PHOTOS_TEXT(Int32(item.messages.count))
|
||||
case .video:
|
||||
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
|
||||
messageText = presentationData.strings.PUSH_MESSAGE_VIDEOS_TEXT(Int32(item.messages.count))
|
||||
case .file:
|
||||
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
|
||||
messageText = presentationData.strings.PUSH_MESSAGE_FILES_TEXT(Int32(item.messages.count))
|
||||
default:
|
||||
title = EnginePeer(peer).displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder)
|
||||
messageText = presentationData.strings.PUSH_MESSAGES_TEXT(Int32(item.messages.count))
|
||||
}
|
||||
}
|
||||
@ -325,6 +314,10 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
|
||||
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 textColor = presentationData.theme.inAppNotification.primaryTextColor
|
||||
var attributedMessageText: NSAttributedString
|
||||
|
@ -3691,7 +3691,7 @@ private class DynamicIslandMaskNode: ManagedAnimationNode {
|
||||
|
||||
func update(_ value: CGFloat) {
|
||||
let lowerBound = 0
|
||||
let upperBound = 180
|
||||
let upperBound = 540
|
||||
let frameIndex = lowerBound + Int(value * CGFloat(upperBound - lowerBound))
|
||||
if frameIndex != self.frameIndex {
|
||||
self.update(frameIndex: frameIndex)
|
||||
|
@ -295,7 +295,7 @@ public final class WebSearchController: ViewController {
|
||||
let throttledSearchQuery = self.searchQueryPromise.get()
|
||||
|> mapToSignal { query -> Signal<String, NoError> in
|
||||
if !query.isEmpty {
|
||||
return (.complete() |> delay(0.6, queue: Queue.mainQueue()))
|
||||
return (.complete() |> delay(1.0, queue: Queue.mainQueue()))
|
||||
|> then(.single(query))
|
||||
} else {
|
||||
return .single(query)
|
||||
|
@ -61,7 +61,7 @@
|
||||
|
||||
_dimensions = CGSizeMake(width, height);
|
||||
|
||||
if ((_frameRate > 60) || _animation->duration() > 7.0) {
|
||||
if ((_frameRate > 60) || _animation->duration() > 9.0) {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user