Various UI fixes

This commit is contained in:
Ilya Laktyushin 2020-01-14 13:17:34 +03:00
parent 14f9d04a36
commit a85da95943
14 changed files with 139 additions and 90 deletions

View File

@ -360,8 +360,8 @@ public func standardTextAlertController(theme: AlertControllerTheme, title: Stri
var dismissImpl: (() -> Void)?
let attributedText: NSAttributedString
if parseMarkdown {
let font = title == nil ? Font.semibold(theme.baseFontSize) : Font.regular(floor(theme.baseFontSize * 13.0 / 17.0))
let boldFont = title == nil ? Font.bold(theme.baseFontSize) : Font.semibold(floor(theme.baseFontSize * 13.0 / 17.0))
let font = title == nil ? Font.semibold(theme.baseFontSize * 13.0 / 17.0) : Font.regular(floor(theme.baseFontSize * 13.0 / 17.0))
let boldFont = title == nil ? Font.bold(theme.baseFontSize * 13.0 / 17.0) : Font.semibold(floor(theme.baseFontSize * 13.0 / 17.0))
let body = MarkdownAttributeSet(font: font, textColor: theme.primaryColor)
let bold = MarkdownAttributeSet(font: boldFont, textColor: theme.primaryColor)
attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in nil }), textAlignment: .center)

View File

@ -185,6 +185,7 @@ open class TooltipController: ViewController, StandalonePresentableController {
open func dismissImmediately() {
self.dismissed?(false)
self.controllerNode.hide()
self.presentingViewController?.dismiss(animated: false)
}
}

View File

@ -126,6 +126,10 @@ final class TooltipControllerNode: ASDisplayNode {
})
}
func hide() {
self.containerNode.alpha = 0.0
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if let event = event {
var eventIsPresses = false

View File

@ -238,7 +238,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
}
self.statusButtonNode.addSubnode(self.statusNode)
self.statusButtonNode.addTarget(self, action: #selector(statusButtonPressed), forControlEvents: .touchUpInside)
self.statusButtonNode.addTarget(self, action: #selector(self.statusButtonPressed), forControlEvents: .touchUpInside)
self.addSubnode(self.statusButtonNode)

View File

@ -187,7 +187,7 @@ private enum IntentsSettingsControllerEntry: ItemListNodeEntry {
case let .accountHeader(theme, text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .account(theme, peer, selected, _):
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: PresentationDateTimeFormat(timeFormat: .regular, dateFormat: .dayFirst, dateSeparator: ".", decimalSeparator: ".", groupingSeparator: ""), nameDisplayOrder: .firstLast, context: arguments.context, peer: peer, height: .generic, aliasHandling: .standard, nameStyle: .plain, presence: nil, text: .none, label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: false), revealOptions: nil, switchValue: ItemListPeerItemSwitch(value: selected, style: .check), enabled: true, selectable: true, sectionId: self.section, action: {
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: PresentationDateTimeFormat(timeFormat: .regular, dateFormat: .dayFirst, dateSeparator: ".", decimalSeparator: ".", groupingSeparator: ""), nameDisplayOrder: .firstLast, context: arguments.context.sharedContext.makeTempAccountContext(account: arguments.context.account), peer: peer, height: .generic, aliasHandling: .standard, nameStyle: .plain, presence: nil, text: .none, label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: false), revealOptions: nil, switchValue: ItemListPeerItemSwitch(value: selected, style: .check), enabled: true, selectable: true, sectionId: self.section, action: {
arguments.updateSettings { $0.withUpdatedAccount(peer.id) }
}, setPeerIdWithRevealedOptions: { _, _ in}, removePeer: { _ in })
return ItemListTextItem(presentationData: presentationData, text: .plain(""), sectionId: self.section)

View File

@ -151,7 +151,7 @@ public func donateSendMessageIntent(account: Account, sharedContext: SharedAccou
let presentationData = sharedContext.currentPresentationData.with { $0 }
for (peer, subject, avatarImage) in peers {
let recipientHandle = INPersonHandle(value: "tg\(peer.id.id)", type: .unknown)
let recipientHandle = INPersonHandle(value: "tg\(peer.id.toInt64())", type: .unknown)
let displayTitle: String
var nameComponents = PersonNameComponents()
@ -173,9 +173,9 @@ public func donateSendMessageIntent(account: Account, sharedContext: SharedAccou
nameComponents.givenName = displayTitle
}
let recipient = INPerson(personHandle: recipientHandle, nameComponents: nameComponents, displayName: displayTitle, image: nil, contactIdentifier: nil, customIdentifier: "tg\(peer.id.id)")
let recipient = INPerson(personHandle: recipientHandle, nameComponents: nameComponents, displayName: displayTitle, image: nil, contactIdentifier: nil, customIdentifier: "tg\(peer.id.toInt64())")
let intent = INSendMessageIntent(recipients: [recipient], content: nil, speakableGroupName: INSpeakableString(spokenPhrase: displayTitle), conversationIdentifier: "tg\(peer.id.id)", serviceName: nil, sender: nil)
let intent = INSendMessageIntent(recipients: [recipient], content: nil, speakableGroupName: INSpeakableString(spokenPhrase: displayTitle), conversationIdentifier: "tg\(peer.id.toInt64())", serviceName: nil, sender: nil)
if let avatarImage = avatarImage, let avatarImageData = avatarImage.jpegData(compressionQuality: 0.8) {
intent.setImage(INImage(imageData: avatarImageData), forParameterNamed: \.groupName)
}

View File

@ -81,6 +81,14 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
}
return .waitForSingleTap
}
recognizer.longTap = { [weak self] point, recognizer in
guard let strongSelf = self else {
return
}
if strongSelf.gestureRecognized(gesture: .longTap, location: point, recognizer: recognizer) {
recognizer.cancel()
}
}
self.view.addGestureRecognizer(recognizer)
let replyRecognizer = ChatSwipeToReplyRecognizer(target: self, action: #selector(self.swipeToReplyGesture(_:)))
@ -580,87 +588,93 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
switch recognizer.state {
case .ended:
if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation {
switch gesture {
case .tap:
if let avatarNode = self.accessoryItemNode as? ChatMessageAvatarAccessoryItemNode, avatarNode.frame.contains(location) {
if let item = self.item, let author = item.content.firstMessage.author {
var openPeerId = item.effectiveAuthorId ?? author.id
var navigate: ChatControllerInteractionNavigateToPeer
if item.content.firstMessage.id.peerId == item.context.account.peerId {
navigate = .chat(textInputState: nil, subject: nil)
} else {
navigate = .info
}
for attribute in item.content.firstMessage.attributes {
if let attribute = attribute as? SourceReferenceMessageAttribute {
openPeerId = attribute.messageId.peerId
navigate = .chat(textInputState: nil, subject: .message(attribute.messageId))
}
}
if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty {
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame)
} else {
if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil {
if case .member = channel.participationStatus {
} else {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame)
return
}
}
item.controllerInteraction.openPeer(openPeerId, navigate, item.message)
}
}
return
}
if let replyInfoNode = self.replyInfoNode, replyInfoNode.frame.contains(location) {
if let item = self.item {
for attribute in item.message.attributes {
if let attribute = attribute as? ReplyMessageAttribute {
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId)
return
}
}
}
}
if let forwardInfoNode = self.forwardInfoNode, forwardInfoNode.frame.contains(location) {
if let item = self.item, let forwardInfo = item.message.forwardInfo {
if let sourceMessageId = forwardInfo.sourceMessageId {
if let channel = forwardInfo.author as? TelegramChannel, channel.username == nil {
if case .member = channel.participationStatus {
} else {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, forwardInfoNode, nil)
return
}
}
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId)
} else if let id = forwardInfo.source?.id ?? forwardInfo.author?.id {
item.controllerInteraction.openPeer(id, .chat(textInputState: nil, subject: nil), nil)
} else if let _ = forwardInfo.authorSignature {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)
}
return
}
}
self.item?.controllerInteraction.clickThroughMessage()
case .longTap, .doubleTap:
if let item = self.item, let videoContentNode = self.interactiveVideoNode.videoContentNode(at: self.view.convert(location, to: self.interactiveVideoNode.view)) {
item.controllerInteraction.openMessageContextMenu(item.message, false, videoContentNode, videoContentNode.bounds, nil)
}
case .hold:
break
}
let _ = self.gestureRecognized(gesture: gesture, location: location, recognizer: nil)
}
default:
break
}
}
private func gestureRecognized(gesture: TapLongTapOrDoubleTapGesture, location: CGPoint, recognizer: TapLongTapOrDoubleTapGestureRecognizer?) -> Bool {
switch gesture {
case .tap:
if let avatarNode = self.accessoryItemNode as? ChatMessageAvatarAccessoryItemNode, avatarNode.frame.contains(location) {
if let item = self.item, let author = item.content.firstMessage.author {
var openPeerId = item.effectiveAuthorId ?? author.id
var navigate: ChatControllerInteractionNavigateToPeer
if item.content.firstMessage.id.peerId == item.context.account.peerId {
navigate = .chat(textInputState: nil, subject: nil)
} else {
navigate = .info
}
for attribute in item.content.firstMessage.attributes {
if let attribute = attribute as? SourceReferenceMessageAttribute {
openPeerId = attribute.messageId.peerId
navigate = .chat(textInputState: nil, subject: .message(attribute.messageId))
}
}
if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty {
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame)
} else {
if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil {
if case .member = channel.participationStatus {
} else {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame)
return true
}
}
item.controllerInteraction.openPeer(openPeerId, navigate, item.message)
}
}
return true
}
if let replyInfoNode = self.replyInfoNode, replyInfoNode.frame.contains(location) {
if let item = self.item {
for attribute in item.message.attributes {
if let attribute = attribute as? ReplyMessageAttribute {
item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId)
return true
}
}
}
}
if let forwardInfoNode = self.forwardInfoNode, forwardInfoNode.frame.contains(location) {
if let item = self.item, let forwardInfo = item.message.forwardInfo {
if let sourceMessageId = forwardInfo.sourceMessageId {
if let channel = forwardInfo.author as? TelegramChannel, channel.username == nil {
if case .member = channel.participationStatus {
} else {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, forwardInfoNode, nil)
return true
}
}
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId)
} else if let id = forwardInfo.source?.id ?? forwardInfo.author?.id {
item.controllerInteraction.openPeer(id, .chat(textInputState: nil, subject: nil), nil)
} else if let _ = forwardInfo.authorSignature {
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)
}
return true
}
}
self.item?.controllerInteraction.clickThroughMessage()
case .longTap, .doubleTap:
if let item = self.item, let videoContentNode = self.interactiveVideoNode.videoContentNode(at: self.view.convert(location, to: self.interactiveVideoNode.view)) {
item.controllerInteraction.openMessageContextMenu(item.message, false, videoContentNode, videoContentNode.bounds, recognizer)
return false
}
case .hold:
break
}
return true
}
@objc func shareButtonPressed() {
if let item = self.item {
if item.content.firstMessage.id.peerId == item.context.account.peerId {

View File

@ -109,6 +109,7 @@ final class HashtagChatInputContextPanelNode: ChatInputContextPanelNode {
let transition = preparedTransition(from: from ?? [], to: to, account: self.context.account, presentationData: presentationData, setHashtagRevealed: { [weak self] text in
if let strongSelf = self {
strongSelf.revealedHashtag = text
strongSelf.updateResults(strongSelf.currentResults)
}
}, hashtagSelected: { [weak self] text in
if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction {
@ -138,6 +139,7 @@ final class HashtagChatInputContextPanelNode: ChatInputContextPanelNode {
}, removeRequested: { [weak self] text in
if let strongSelf = self {
let _ = removeRecentlyUsedHashtag(postbox: strongSelf.context.account.postbox, string: text).start()
strongSelf.revealedHashtag = nil
}
})
self.currentEntries = to

View File

@ -62,6 +62,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
private let listView: ListView
private var currentEntries: [MentionChatInputContextPanelEntry]?
private var currentResults: [Peer] = []
private var revealedPeerId: PeerId?
private var enqueuedTransitions: [(CommandChatInputContextPanelTransition, Bool)] = []
@ -90,6 +91,8 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
}
func updateResults(_ results: [Peer]) {
self.currentResults = results
var entries: [MentionChatInputContextPanelEntry] = []
var index = 0
var peerIdSet = Set<Int64>()
@ -99,7 +102,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
continue
}
peerIdSet.insert(peerId)
entries.append(MentionChatInputContextPanelEntry(index: index, peer: peer, revealed: revealedPeerId == peer.id))
entries.append(MentionChatInputContextPanelEntry(index: index, peer: peer, revealed: self.revealedPeerId == peer.id))
index += 1
}
self.updateToEntries(entries: entries, forceUpdate: false)
@ -109,7 +112,10 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
let firstTime = self.currentEntries == nil
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
let transition = preparedTransition(from: self.currentEntries ?? [], to: entries, context: self.context, presentationData: presentationData, inverted: self.mode == .search, forceUpdate: forceUpdate, setPeerIdRevealed: { [weak self] peerId in
if let strongSelf = self {
strongSelf.revealedPeerId = peerId
strongSelf.updateResults(strongSelf.currentResults)
}
}, peerSelected: { [weak self] peer in
if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction {
switch strongSelf.mode {
@ -157,6 +163,10 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
}, removeRequested: { [weak self] peerId in
if let strongSelf = self {
let _ = removeRecentlyUsedInlineBot(account: strongSelf.context.account, peerId: peerId).start()
strongSelf.revealedPeerId = nil
strongSelf.currentResults = strongSelf.currentResults.filter { $0.id != peerId }
strongSelf.updateResults(strongSelf.currentResults)
}
})
self.currentEntries = entries

View File

@ -83,7 +83,11 @@ final class MentionChatInputPanelItem: ListViewItem {
}
func selected(listView: ListView) {
self.peerSelected(self.peer)
if self.revealed {
self.setPeerIdRevealed(nil)
} else {
self.peerSelected(self.peer)
}
}
}

View File

@ -120,6 +120,19 @@ public final class TelegramRootController: NavigationController {
self.accountSettingsController = accountSettingsController
self.rootTabController = tabBarController
self.pushViewController(tabBarController, animated: false)
// let _ = (archivedStickerPacks(account: self.context.account, namespace: .stickers)
// |> deliverOnMainQueue).start(next: { [weak self] stickerPacks in
// var packs: [(StickerPackCollectionInfo, StickerPackItem?)] = []
// for pack in stickerPacks {
// packs.append((pack.info, pack.topItems.first))
// }
//
// if let strongSelf = self {
// let controller = archivedStickersNoticeController(context: strongSelf.context, archivedStickerPacks: packs)
// strongSelf.chatListController?.present(controller, in: .window(.root))
// }
// })
}
public func updateRootControllers(showCallsTab: Bool) {

View File

@ -27,7 +27,7 @@ public struct IntentsSettings: PreferencesEntry, Equatable {
}
public init(decoder: PostboxDecoder) {
self.initiallyReset = decoder.decodeBoolForKey("initiallyReset_v1", orElse: false)
self.initiallyReset = decoder.decodeBoolForKey("initiallyReset_v2", orElse: false)
self.account = decoder.decodeOptionalInt64ForKey("account").flatMap { PeerId($0) }
self.contacts = decoder.decodeBoolForKey("contacts", orElse: true)
self.privateChats = decoder.decodeBoolForKey("privateChats", orElse: false)
@ -37,7 +37,7 @@ public struct IntentsSettings: PreferencesEntry, Equatable {
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeBool(self.initiallyReset, forKey: "initiallyReset_v1")
encoder.encodeBool(self.initiallyReset, forKey: "initiallyReset_v2")
if let account = self.account {
encoder.encodeInt64(account.toInt64(), forKey: "account")
} else {

View File

@ -151,6 +151,8 @@ private final class WebEmbedVideoContentNode: ASDisplayNode, UniversalVideoConte
func playOnceWithSound(playAndRecord: Bool, seek: MediaPlayerSeek, actionAtEnd: MediaPlayerPlayOnceWithSoundActionAtEnd) {
if case let .timecode(time) = seek {
self.playerNode.seek(timestamp: time)
} else {
self.playerNode.play()
}
}

View File

@ -779,7 +779,7 @@ public func drawThemeImage(context c: CGContext, theme: PresentationTheme, wallp
c.fill(CGRect(origin: CGPoint(x: 0.0, y: drawingRect.height - 42.0), size: CGSize(width: drawingRect.width, height: 42.0)))
c.setFillColor(theme.rootController.navigationBar.separatorColor.cgColor)
c.fill(CGRect(origin: CGPoint(x: 1.0, y: drawingRect.height - 43.0), size: CGSize(width: drawingRect.width - 2.0, height: 1.0)))
c.fill(CGRect(origin: CGPoint(x: 1.0, y: drawingRect.height - 42.0 - UIScreenPixel), size: CGSize(width: drawingRect.width - 2.0, height: UIScreenPixel)))
c.setFillColor(theme.rootController.navigationBar.secondaryTextColor.cgColor)
c.fillEllipse(in: CGRect(origin: CGPoint(x: drawingRect.width - 28.0 - 7.0, y: drawingRect.height - 7.0 - 28.0 - UIScreenPixel), size: CGSize(width: 28.0, height: 28.0)))
@ -796,7 +796,7 @@ public func drawThemeImage(context c: CGContext, theme: PresentationTheme, wallp
c.fill(CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: drawingRect.width, height: 42.0)))
c.setFillColor(theme.chat.inputPanel.panelSeparatorColor.cgColor)
c.fill(CGRect(origin: CGPoint(x: 1.0, y: 42.0), size: CGSize(width: drawingRect.width - 2.0, height: 1.0)))
c.fill(CGRect(origin: CGPoint(x: 1.0, y: 42.0), size: CGSize(width: drawingRect.width - 2.0, height: UIScreenPixel)))
}
c.setFillColor(theme.chat.inputPanel.inputBackgroundColor.cgColor)
@ -1323,7 +1323,6 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
c.translateBy(x: drawingRect.width / 2.0, y: drawingRect.height / 2.0)
c.scaleBy(x: 1.0, y: -1.0)
c.translateBy(x: -drawingRect.width / 2.0, y: -drawingRect.height / 2.0)
c.draw(incoming!.cgImage!, in: CGRect(x: 9.0, y: 34.0, width: 57.0, height: 16.0))
c.translateBy(x: drawingRect.width / 2.0, y: drawingRect.height / 2.0)